Build
Authentication and keys
API keys, scopes, the device flow, rate limits, and OAuth for MCP.
The REST API uses API keys. A key is a bearer token that acts as the account that made it, limited to its scopes and to /v1. The MCP server uses OAuth instead, so your AI client never holds a long-lived secret.
API keys
Keys start with rl_live_ and go in the header: Authorization: Bearer rl_live_.... Only a hash is stored, so you see a key once. A key works on every workspace its owner can edit; pass workspaceId to target one other than the personal workspace. Outside /v1 keys get a 403 with code api_key_scope, so a leaked key cannot read the rest of the account. A call the key's scopes do not cover gets a 403 with code api_key_missing_scope.
Scopes
| Scope | Unlocks |
|---|---|
productions | /v1/productions and /v1/webhooks: productions and their webhooks. |
renders | /v1/renders: the older one-call Render API (images in, video out). |
capture | /v1/capture: uploads from Capture for Mac. |
import | /v1/import: After Effects imports from the panel. |
App keys carry the scopes you tick. Device-flow keys carry all four, since the owner approves them for their own account and a second pairing for one more scope would add nothing.
The device flow
For CLIs, coding agents and anything else without a browser session. Starting needs no key; a human approves once in a browser.
- 1
Request
POST /v1/keys/requestwith anamethat says who is asking (tool plus machine or project). The approver sees it. - 2
Show the approval URL
The 201 has
approvalUrl(https://www.raylight.app/keys/approve?code=XXXXXXXX) anduserCode. Have your user open it and click Approve; they can sign in or create an account from that page. The request expires after 10 minutes (expiresInSeconds). - 3
Poll
POST /v1/keys/pollwith thedeviceCodeeverypollIntervalSeconds(3).pendinguntil approved. - 4
Claim the key
The first poll after approval answers
approvedwithapiKey, once, and the server wipes the plaintext. Later polls answerclaimed. Save the key before doing anything else. - 5
Terminal states
denied: the user refused.expired: the 10 minutes passed, or the key was approved but not claimed within 10 minutes (it is revoked and the plaintext cleared). Start a new request.
curl -X POST https://api.raylight.app/v1/keys/request \ -H "Content-Type: application/json" \ -d '{ "name": "CI on acme/web" }'{ "deviceCode": "1aSs9fWUrhEUu3hOo5TzSJfWDgradXEK_k9BIV67XV8", "userCode": "ABCD2345", "approvalUrl": "https://www.raylight.app/keys/approve?code=ABCD2345", "expiresInSeconds": 600, "pollIntervalSeconds": 3}curl -X POST https://api.raylight.app/v1/keys/poll \ -H "Content-Type: application/json" \ -d '{ "deviceCode": "1aSs9fWUrhEUu3hOo5TzSJfWDgradXEK_k9BIV67XV8" }'{ "status": "pending" }{ "status": "approved", "apiKey": "rl_live_..." }{ "status": "claimed" }{ "status": "denied" }{ "status": "expired" }/v1/keys allows 60 requests a minute per IP, plenty for one poll every three seconds.
Key management in the app
Raylight API, then Keys. Create a key with a name and scopes, see each key's prefix, scopes, creation date and last use, and revoke any key. Revocation is immediate and keeps the key's history. A key cannot be shown again; make a new one.
Revoke the key you are using
DELETE /v1/keys/current with the key in the Authorization header revokes that key and answers 204. It needs no scope (30 calls a minute per key), so any key can retire itself: a tool that is done with a machine, or that thinks its key leaked, can sign out without a person opening the app. Only an API key can revoke itself; a browser session gets 400 not_api_key. raylight logout makes this call before deleting the saved key, and the SDK has it as raylight.keys.revokeCurrent().
Rate limits
Fixed one-minute windows. Over the limit you get 429 with { "code": "rate_limited" } and a Retry-After header in seconds.
| Surface | Limit | Counted per |
|---|---|---|
/v1/productions | 120 a minute | key |
/v1/webhooks | 60 a minute | key |
/v1/renders | 30 a minute | key |
/v1/keys | 60 a minute | IP |
/production-links | 30 a minute | IP |
The monthly pitch cap (per workspace) is separate and return 429 with code: "cap". See Limits and pricing.
MCP uses OAuth, not keys
The MCP server at https://api.raylight.app/mcp uses OAuth 2.0 with PKCE. Your AI client opens a Raylight page that shows the app asking, the scopes, and where you will be sent back. You approve, and the client gets a token for your account that refreshes on its own. API keys do not work there, and MCP tokens do not work on /v1. Setup for every client is on /mcp.