Guides
Wire a worker process into Mobius to execute workflow steps — for a service that pulls pending jobs, runs them, and reports results back to the run. No separate registration call is needed; the first claim request registers the worker.
Before you start
- You have a Mobius API key exported as
MOBIUS_API_KEY. See Create an API key if you do not. - Export
MOBIUS_BASE_URL(typicallyhttps://api.mobius.deepnoodle.ai) andPROJECT(your project handle). - Choose a stable string for
WORKER_ID— this is the lease fence used on every heartbeat and complete call — and export it. - A workflow run is in progress with at least one pending worker step. See Run a workflow from your code to start one.
Walkthrough
-
Long-poll for the next pending job with
POST /v1/projects/{project}/jobs/claim. The server holds the connection open for up towait_secondsseconds (maximum 30). A200response carriesjob_id,attempt, andheartbeat_interval_seconds; capture them as$JOB_IDand$ATTEMPT. A204means the poll window closed empty — loop and retry.curl -X POST "$MOBIUS_BASE_URL/v1/projects/$PROJECT/jobs/claim" \ -H "Authorization: Bearer $MOBIUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "worker_id": "'"$WORKER_ID"'", "queues": ["default"], "wait_seconds": 30 }' -
Keep the lease alive by calling
POST /v1/projects/{project}/jobs/{id}/heartbeatat the cadence fromheartbeat_interval_seconds. The response includesdirectives.should_cancel; when it istrue, stop executing and move to step 4 withstatus: failed.curl -X POST "$MOBIUS_BASE_URL/v1/projects/$PROJECT/jobs/$JOB_ID/heartbeat" \ -H "Authorization: Bearer $MOBIUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "worker_id": "'"$WORKER_ID"'", "attempt": '"$ATTEMPT"' }' -
Emit progress events with
POST /v1/projects/{project}/jobs/{id}/events. Events are appended to the run's durable event store and fanned out to live SSE subscribers. Themobius.type prefix is rejected with400; use any other identifier.curl -X POST "$MOBIUS_BASE_URL/v1/projects/$PROJECT/jobs/$JOB_ID/events" \ -H "Authorization: Bearer $MOBIUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "worker_id": "'"$WORKER_ID"'", "attempt": '"$ATTEMPT"', "events": [ { "type": "progress", "payload": { "pct": 50 } } ] }' -
Report the terminal result with
POST /v1/projects/{project}/jobs/{id}/complete. Returns204. Onstatus: failed, the workflow engine retries the step ifattempt < max_attempts; otherwise the run transitions tofailed.curl -X POST "$MOBIUS_BASE_URL/v1/projects/$PROJECT/jobs/$JOB_ID/complete" \ -H "Authorization: Bearer $MOBIUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "worker_id": "'"$WORKER_ID"'", "attempt": '"$ATTEMPT"', "status": "completed" }'
Follow-ups
- Attach job output to downstream steps by including
result_b64(base64-encoded bytes) in the complete request — seePOST …/completefor the full schema. - Pause a run for human review by creating an interaction from within a job with
POST /v1/projects/{project}/jobs/{id}/interactions. - Inspect registered workers and their
stalestatus withGET /v1/projects/{project}/workers.
Troubleshooting
204on claim: no pending job matched the subscribed queues within the poll window → loop back and retry the claim.409on heartbeat or complete: the lease fence (worker_id+attempt) does not match the server's current record → the lease has expired; discard this claim and start a new claim loop.directives.should_cancel: true: the run received a cancellation request → callPOST /completewithstatus: failedimmediately.
See also
- Workers — worker identity and registry model.
- Jobs — job lifecycle and retry configuration.
- Redoc reference: jobs and workers — full request and response schemas.
- Run a workflow from your code — how to start a run that produces jobs.