API reference

Overview

Base URL, authentication, errors and pagination.

The Ephemeral API is JSON over HTTPS. Runs, workflows, files, connections and models are served by the engine. On the hosted service, organizations, members, keys and billing are served by a separate organization API.

Base URLs

APIBase URLCovers
Engine, hostedhttps://app.ephemer.al/v1Runs, workflows, files, connections, models
Organization API, hostedhttps://ephemer.al/v1Organizations, members, invitations, keys, billing, licenses
Engine, self-hostedhttps://your-domain/v1The same engine routes, plus API keys

The examples in these pages use $EPHEMERAL_URL for the engine base, without the /v1.

Authentication

Send an organization API key as a bearer token on every engine request.

Terminal
curl $EPHEMERAL_URL/v1/me \
  -H "Authorization: Bearer $EPHEMERAL_API_KEY"

Hosted keys start with eak_; self-hosted keys start with eph_. A key belongs to one organization, so you never pass an organization ID to the engine. Whether a key can call an endpoint depends on its role; see roles and keys. The organization API refuses API keys for management actions and needs a signed-in owner or admin instead; see organizations.

Keep keys on your server
A key can start paid runs. Never send it to a browser or a mobile app, and never commit it to source control.

Applications that act for a person, such as MCP clients, can sign in with OAuth 2.1 instead (hosted service only): authorization code flow with PKCE, dynamic client registration, and the scopes member and admin. The access token (eoa_…, valid one hour) goes in the same Authorization: Bearer header and acts in the organization the person chose. Discovery: authorization server metadata and protected resource metadata. See MCP.

GET/v1/me
Returns the organization and role behind the key, and the settings that affect budgets.
Response
organization_idstring
The key's organization.
rolestring
owner, admin or member.
modestring
hosted or self-hosted.
compute_micros_per_secondinteger
Compute rate used to charge and authorize runs.
default_max_cost_microsinteger
Budget applied when a run request has no max_cost_micros.
JSON
{
  "organization_id": "org_5e2b8c91d4a7f03e6b1c9d2a8f4e7b10",
  "role": "member",
  "mode": "hosted",
  "compute_micros_per_second": 200,
  "default_max_cost_micros": 500000
}

Requests

  • Send JSON with Content-Type: application/json. File uploads are the exception and use multipart form data.
  • Unknown fields are rejected with 400, so a misspelled field returns an error.
  • Timestamps are RFC 3339 strings in UTC.
  • Money fields ending in _micros are integer millionths of a US dollar. Fields ending in _cents are integer cents.

Errors

Errors return an HTTP status and a JSON body with a readable message in error and, on engine routes, a stable machine-readable name in code, such as invalid_request, unauthorized, not_found or method_not_allowed. Unknown routes under /v1 return a JSON 404 in the same shape.

JSON
{ "error": "timeout_seconds must be between 1 and 3600", "code": "invalid_request" }
StatusMeaning
400The request is invalid. The message names the problem.
401The key is missing, invalid or revoked.
402Not enough available credits for the budget, or a licensed installation has used its monthly run allowance.
403The key or user does not have the role this action needs.
404The resource does not exist in this organization.
409The request conflicts with the current state.
429Rate limit reached, or too many attempts. Wait for the number of seconds in Retry-After and try again.
503A service Ephemeral depends on is temporarily unavailable. Retry with backoff.

Rate limits

Engine requests are limited per minute. A request with a bearer token counts against that credential, at 600 requests per minute. A request without one, such as GET /v1/models, counts against the client address, at 120 requests per minute. The window is one minute long and restarts at the top of each minute.

Every engine response, including errors, says where you stand. RateLimit-Policy and RateLimit follow the IETF RateLimit header draft (q is the quota, w the window in seconds, r the requests remaining and t the seconds until the window resets). X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset carry the same numbers under the names many clients already read.

Text
RateLimit-Policy: "default";q=600;w=60
RateLimit: "default";r=598;t=41
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 598
X-RateLimit-Reset: 41

When you exceed the limit the engine answers 429 with the usual JSON error, code rate_limited, and a Retry-After header holding the seconds to wait. Back off for that long instead of retrying at once. Following a run with GET /v1/runs/{id}/events counts once for the connection, not for each event.

Idempotent run creation

Network failures can leave you unsure whether a run was created. Send an Idempotency-Key header, up to 200 characters, with POST /v1/runs. If a run with that key already exists in your organization, Ephemeral returns it with status 200 instead of creating another one. A new run returns 202.

Ephemeral matches on the key alone and does not compare request bodies. Use a fresh key for each distinct run, such as a UUID generated when you decide to start it.

Pagination

GET /v1/runs pages when you pass limit (1 to 100) or cursor. The response is {"items": [...], "next_cursor": "..."}. Pass next_cursor back as cursor to get the next page; an empty next_cursor means you have reached the last one. Cursors are opaque and only valid with the same status filter. Without limit or cursor, the response is a plain array of the 100 most recent runs.

Versioning and deprecation

The API is versioned in its path: every endpoint here is under /v1. Within a version, changes are additive only: new endpoints, new optional request fields, new response fields and new event types. Existing fields keep their names and meaning, so clients should ignore fields they do not know.

A change that would break existing clients ships as a new version under a new path. The previous version keeps working for at least six months after the new one is published. While it is deprecated, its responses carry a Deprecation header and a Sunset header with the date it stops working, and organization owners are told by email.

Reference

The engine API is also published as an OpenAPI 3.1 description (https://app.ephemer.al/openapi.json) with the key role each operation needs. The key roles, member and admin, are listed as machine-readable scopes_supported in the protected resource metadata.

PageEndpoints
RunsStart, list, read, stream, cancel and inspect runs
WorkflowsSave, list, read and delete workflows
FilesUpload, list, download, rename and delete files
ConnectionsConfigure connections, start OAuth, list the catalog
ModelsThe model catalog
CallbacksSigned completion requests to your server
OrganizationsMembers, keys, billing and licenses on the hosted service
© 2026 EphemeralProduced by erni.works
esc

Nothing matches “”.