emit.run

Authentication

How to authenticate with the emit.run API

Authentication

All API requests authenticate with an API key passed via request header.

API Keys

API keys authenticate all job-related operations. Pass the key via either header:

x-api-key: emit_YOUR_KEY
Authorization: Bearer emit_YOUR_KEY

Keys are scoped to a single space by default — space scoping is enforced when a key includes a spaceId in its metadata. Avoid unscoped keys unless you explicitly need cross-space access.

Keys are prefixed with emit_ and the full key is only shown once at creation time.

Rate Limits

API keys are rate-limited to 1000 requests per second. If you exceed this, you'll receive a 429 response.

Scopes Reference

Each API key has one or more scopes that control what it can do. Scopes are checked on every request — if your key is missing a required scope, you'll get a 403 with the message Missing required scope: <scope>.

Granular Scopes

ScopeDescriptionUsed by
jobs:createCreate new jobs in a spacePOST /spaces/:id/jobs
jobs:readList jobs, get job details and eventsGET /spaces/:id/jobs, GET /jobs/:id
jobs:pollClaim pending jobs from the dispatch queuePOST /spaces/:id/jobs/poll
jobs:ackAcknowledge receipt of a polled jobPOST /jobs/:id/ack
jobs:progressSend in-progress updates for a running jobPOST /jobs/:id/progress
jobs:eventPublish checkpoint and custom eventsPOST /jobs/:id/checkpoint, POST /jobs/:id/event
jobs:completeMark a job as successfully completedPOST /jobs/:id/complete
jobs:failFail a job (retry or mark dead)POST /jobs/:id/fail
jobs:killForce-stop a job and mark it as killedPOST /jobs/:id/kill
jobs:keepaliveExtend a running job's timeoutPOST /jobs/:id/keepalive
jobs:read:progressRead job progress via API or a single job's WebSocket stream onlyGET /jobs/:id/progress, GET /realtime/:id

Shorthand Scopes

These expand to multiple granular scopes for convenience. You can use them when creating tokens, and they'll be recognized during authorization.

ShorthandExpands to
jobs:workerjobs:read, jobs:poll, jobs:ack, jobs:progress, jobs:event, jobs:complete, jobs:fail, jobs:kill, jobs:keepalive, jobs:read:progress
jobs:writejobs:ack, jobs:progress, jobs:event, jobs:complete, jobs:fail, jobs:kill, jobs:keepalive

jobs:worker is the most common — it includes everything a worker needs to poll, process, and report results.

RoleScopesWhy
Producerjobs:createCan only submit jobs, nothing else
Workerjobs:workerFull worker lifecycle: poll → ack → progress → complete/fail
Dashboard / monitorjobs:readREST read + both WS streams (job and space-wide)
Producer + monitorjobs:create, jobs:readSubmit jobs and watch them complete
Third-party clientjobs:read:progressProgress-only stream for a single job (no space-level access)
Minimal workerjobs:poll, jobs:ack, jobs:complete, jobs:failWorker without progress/event/keepalive

WebSocket Auth

WebSocket connections authenticate via ?token= query parameter — required on all realtime endpoints:

wss://emit.run/api/v1/realtime/:jobId?token=emit_YOUR_KEY
EndpointMinimum scope
GET /realtime/:jobIdjobs:read:progress
GET /realtime/spaces/:spaceIdjobs:read

jobs:read:progress only grants access to job progress (API + single-job stream) — it cannot connect to the space-wide stream. This makes it safe to embed in frontend code for client-facing progress bars.

Space scoping is enforced on both endpoints: a space-scoped token can only subscribe to its own space's stream and to jobs within that space. Connecting to a job in a different space returns 403.

Your scope also controls what data you receive. With jobs:read:progress, the stream includes init (last known progress, if any), progress, and a completed signal without payload data. Other event types are not delivered. With jobs:read, you receive the full event stream and all payloads. See WebSockets for details.

On this page