Skip to Content

Authentication and API keys

Every /v1 request is authenticated with an API key.

curl -s "https://api.upserve.app/v1/deployments" \ -H "Authorization: Bearer $UPSERVE_API_KEY"

A key is a string that starts with up_. A missing key, a malformed key, or a revoked or expired key returns 401 INVALID_API_KEY.

The key is shown only once

  • The key itself appears only in the response when you create or rotate it. The server stores only a one-way hash of the key, so it cannot show it again.
  • If you lose it, create a new key or rotate.
  • Keep it in an environment variable or a secret store. Do not put it in code, logs, error reports, a browser, or a mobile app.
  • A key belongs to a Project. Key management (create, rotate, revoke) is done only by an organization OWNER through the signed-in management screen or the management API. An execution API key cannot do it.
  • If the person who issued a key loses organization OWNER permission, that key starts returning 401 INVALID_API_KEY.

Scopes

You choose the allowed scopes for each key. An operation without its scope returns 403 INSUFFICIENT_SCOPE.

scopeAllowed operations
deployments:readList and read Deployments
sessions:readRead Sessions and Items
sessions:writeCreate, close, and delete Sessions
turns:readList Turns and read their status
turns:writeCreate Turns (including the first Turn of a new Session)
turns:cancelCancel a Turn
events:readRead Session and Run events (SSE)
usage:readRead usage
files:writeUpload input files (including Session files)
artifacts:readRead Artifact details and download
workflows:readRead workflow details
workflows:runSubmit a Run
runs:readRead Run status and results
runs:cancelCancel a Run
runs:deleteDelete a Run
actions:resolveResolve questions (RequiredAction) that the caller may answer
actions:approveSubmit human approvals or rejections collected by your service (explicit delegation)
works:readRead and list organization work preparations
works:writeSubmit an organization work, revise its spec, and answer preparation questions
works:approveSubmit a person’s scope confirmation collected by your service (explicit delegation)

One request can require several scopes. For example, creating a Session needs sessions:write and turns:write, and reading a Turn result needs turns:read and sessions:read. Grant only the minimum scopes you need.

Deployment and workflow allowlists

Separately from scopes, a key has a list of Deployments and workflows it may call.

  • A Deployment or workflow that is not on the key answers 404 NOT_FOUND, so its existence is not revealed.
  • The effective permission is the intersection of the key scopes, the Project and key allowlists, and the capabilities frozen at publication. Scopes alone never widen access.
  • Split keys by purpose, and allow each key only the Deployments it needs.
  • A key with at least one works scope and nothing else but usage:read runs no Deployment, so it can be created without one. A key that mixes in any other scope needs at least one Deployment. See organization works.

Rotation

Use rotation to replace a key. Rotating creates a new key with the same name, scopes, and allowlists, and the new key appears once in the response.

  • At rotation you explicitly choose an overlap time (overlap_seconds, 0 to 86,400 seconds). The default of 0 revokes the old key immediately.
  • With an overlap, the old key expires once that time has passed, and both keys work in the meantime. It gives your callers time to move to the new key.
  • Rotating a key that is already revoked, expired, or rotated returns 409 KEY_NOT_ROTATABLE. Create a new key instead.
  • Idempotency receipts are kept at Project scope, so resending with the same Idempotency-Key still works after rotation.

Revocation

  • Revocation immediately blocks new requests and the start of new external effects right after it commits. Later requests return 401 INVALID_API_KEY.
  • Unfinished Turns and Runs that were already accepted are switched to cancel requests. Effects that already completed are not undone, and an in-flight model call is not guaranteed to stop at once.
  • Open SSE connections are closed at their periodic revalidation.
  • Revoking a Project disables all of its keys.

Expiry

A key has no caller-chosen lifetime (expiry date). A key expires in only two ways.

  1. The old key expires at a set time after a rotation that had an overlap.
  2. An owner revokes it.

Rotate on a regular schedule to keep key lifetimes short.

Rate limits

Call rates are limited per key, Project, and Deployment. When you exceed them you get 429 RATE_LIMITED and Retry-After. See limits and data for the numbers.