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
| API | Base URL | Covers |
|---|---|---|
| Engine, hosted | https:/ | Runs, workflows, files, connections, models |
| Organization API, hosted | https:/ | Organizations, members, invitations, keys, billing, licenses |
| Engine, self-hosted | https:/ | The 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.
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.
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.
/v1/meorganization_idstringrolestringowner, admin or member.modestringhosted or self-hosted.compute_micros_per_secondintegerdefault_max_cost_microsintegermax_cost_micros.{
"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
_microsare integer millionths of a US dollar. Fields ending in_centsare 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.
{ "error": "timeout_seconds must be between 1 and 3600", "code": "invalid_request" }| Status | Meaning |
|---|---|
400 | The request is invalid. The message names the problem. |
401 | The key is missing, invalid or revoked. |
402 | Not enough available credits for the budget, or a licensed installation has used its monthly run allowance. |
403 | The key or user does not have the role this action needs. |
404 | The resource does not exist in this organization. |
409 | The request conflicts with the current state. |
429 | Rate limit reached, or too many attempts. Wait for the number of seconds in Retry-After and try again. |
503 | A 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.
RateLimit-Policy: "default";q=600;w=60
RateLimit: "default";r=598;t=41
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 598
X-RateLimit-Reset: 41When 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.
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.
| Page | Endpoints |
|---|---|
| Runs | Start, list, read, stream, cancel and inspect runs |
| Workflows | Save, list, read and delete workflows |
| Files | Upload, list, download, rename and delete files |
| Connections | Configure connections, start OAuth, list the catalog |
| Models | The model catalog |
| Callbacks | Signed completion requests to your server |
| Organizations | Members, keys, billing and licenses on the hosted service |