API reference

Organizations

Members, keys, billing and licenses on the hosted service.

On the hosted service, organizations, members, API keys, credits and deployment licenses are managed through the organization API at https://ephemer.al/v1. The customer portal and dashboard use it for you; this page is for scripts and integrations.

Authentication

These endpoints act as a person. Sign in with POST /v1/auth/login and send the returned token as a bearer token. Sessions last 30 days; POST /v1/auth/logout ends one early.

Terminal
curl https://ephemer.al/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"…"}'

The response is {"token": "...", "user": {...}, "organizations": [...]}. Each organization has id, name and your role. Everything below except listing and creating organizations and accepting an invitation needs the owner or admin role in the organization named in the path.

API keys are refused here
Organization API keys, including admin keys, cannot call the member, key, billing or license endpoints. This keeps a leaked key from adding people, issuing keys or spending money. They can read their own organization's balance.

Organizations

GET/v1/organizations
Lists the organizations you belong to, each with id, name and role.
POST/v1/organizations
Creates an organization from {"name": "..."} and makes you its owner. Returns 201 with {"id": "org_...", "name": "...", "role": "owner"}.
PATCH/v1/organizations/{id}
Owner or admin. Renames the organization with {"name": "..."}. The name is trimmed and must be 1 to 200 characters. Returns {"id": "org_...", "name": "...", "role": "owner"}. Members get 403.

Members

GET/v1/organizations/{id}/members
Lists members with id, email, name, role and avatar_url.
DELETE/v1/organizations/{id}/members/{user_id}
Removes a member. Admins can remove members; only the owner can remove an admin. The owner cannot be removed.
PATCH/v1/organizations/{id}/members/{user_id}
Owner only. Changes a member's role with {"role": "admin"} or {"role": "member"}.
POST/v1/organizations/{id}/ownership
Owner only. Transfers ownership to an existing member with {"user_id": "..."}. You become an admin.

Invitations

POST/v1/organizations/{id}/invitations
Invites someone with {"email": "...", "role": "member"}. role is admin or member. Returns 201 with token, url and email_delivery.

email_delivery is accepted when the email provider took the message, which does not guarantee it reached the inbox. If it is unavailable or failed, share the returned url privately. Invitations expire after 7 days. The invited person accepts with POST /v1/invitations/accept and {"token": "..."}, signed in with the invited email address.

API keys

GET/v1/organizations/{id}/keys
Lists keys with id, name, role and created_at. Secrets are never listed.
POST/v1/organizations/{id}/keys
Creates a key from {"name": "...", "role": "member"}. role is member or admin and defaults to member.
201 Created
{
  "id": "key_0b7e4c2a9d1f8356e4a2c7b9d0f1e3a5",
  "name": "production-server",
  "role": "member",
  "key": "eak_…"
}
The key value is returned only once. Store it before you close the response.
DELETE/v1/organizations/{id}/keys/{key_id}
Revokes the key immediately.

Profile

These need a signed-in user session; API keys are refused. Users, and each members entry, carry avatar_url: a path such as /v1/users/usr_…/avatar?v=3f2a…, or null.

PUT/v1/me/avatar
The raw image as the body, with Content-Type image/png, image/jpeg or image/webp, up to 256 KiB. Returns the same body as GET /v1/auth/me. At most 20 uploads an hour.
DELETE/v1/me/avatar
Removes the picture.
POST/v1/me/password
Changes your password with {"current_password": "...", "new_password": "..."}. The new password is 12 to 72 bytes. Your other sessions are signed out; the one making the request stays signed in. At most 10 attempts an hour.
GET/v1/users/{user_id}/avatar
The image, for that user and people who share an organization with them; anyone else gets 404. The URL changes when the picture does, so it can be cached for good.

Billing

Money in these endpoints uses cents for Stripe amounts and micros for wallet amounts. See budgets and billing.

GET/v1/organizations/{id}/balance
Any member, or an API key of the organization. Returns {"balance_micros": ..., "reserved_micros": ..., "available_micros": ...}: credits held, reserved for unsettled runs, and available for new runs. Check available_micros against a run's budget before you start it.
GET/v1/organizations/{id}/billing
Returns the wallet and payment settings.
balance_micros, reserved_micros, available_microsinteger
Credits held, reserved for unsettled runs, and available for new runs.
ledgerarray
The latest 100 entries, each with amount_micros, description, created_at and, where they apply, run_id, payment_id and topup_id.
purchase_limitsobject
min_amount_cents, max_amount_cents and min_threshold_cents. Validate against these instead of hard-coding limits.
auto_topupobject
enabled, threshold_cents, amount_cents, payment_method_saved and last_topup_status.
payment_methodobject | null
The card used for top-ups: brand, last4, exp_month, exp_year and source.
payment_method_syncstring
synced, or unavailable when Stripe could not be reached. A failed lookup does not mean there is no card.
stripe_configuredboolean
Whether payments are available.
POST/v1/organizations/{id}/billing/checkout
Starts a credit purchase with {"amount_cents": 2500} and returns {"url": "..."} for Stripe Checkout. Add "save_payment_method": true to save the card for automatic top-ups. Amounts are 500 to 1,000,000 cents.
POST/v1/organizations/{id}/billing/portal
Returns {"url": "..."} for the Stripe customer portal, where cards are managed.
PUT/v1/organizations/{id}/billing/auto-topup
Turns automatic top-up on with {"enabled": true, "threshold_cents": 1000, "amount_cents": 5000, "consent": true}, or off with {"enabled": false}. Enabling needs a saved card.
GET/v1/organizations/{id}/billing/payments
Payment history, newest first. Takes limit (1 to 100, default 25) and cursor, and returns {"payments": [...], "next_cursor": "..."}. Each payment has amount_cents, refunded_cents, disputed_cents, refund_status, created_at, topup_id and receipt_endpoint.
GET/v1/organizations/{id}/billing/payments/{payment_id}/receipt
Returns {"url": "..."} for Stripe's receipt, or 404 if Stripe has not provided one.

Deployment licenses

GET/v1/organizations/{id}/license
The organization's self-hosting entitlement, or {"entitlement": null}.
GET/v1/organizations/{id}/deployments
Lists registered installations.
POST/v1/organizations/{id}/deployments
Registers an installation with {"name": "..."} and returns its license token once, with the machine ID Ephemeral generated (or the machine_id you send).
DELETE/v1/organizations/{id}/deployments/{deployment_id}
Revokes an installation's license.
Deployment licenses describes these fields and how installations use the token.
© 2026 EphemeralProduced by erni.works
esc

Nothing matches “”.