/Long-running & recurring jobs
For Developers

Long-running & recurring jobs

Handle results that arrive in seconds, hours, or continuously over weeks.

OpenHelm runs are asynchronous. There are three ways to consume results, matched to how long the work takes.

1. Seconds — inline

Fast tasks settle quickly. Over MCP, the tool call bounded-waits (~75s) and returns the result in one turn; if it isn't ready it returns a task_id and you call check_result.

2. Minutes to hours — poll or webhook

POST /v1/runs returns 202 immediately with a task_id and poll_url. Either:

  • Poll GET /v1/runs/{id} until status is terminal, or
  • Supply a `callback_url` and receive an HMAC-signed webhook on completion.

Verifying the webhook

The body is { "event": "run.completed" | "run.failed", "data": <TaskEnvelope> }. The signature header is Stripe-style:

X-OpenHelm-Signature: t=<unix_seconds>,v1=<hex>
signed_payload = `${t}.${rawBody}`
expected = HMAC_SHA256(api_key.signing_secret, signed_payload)

Reject anything that doesn't match, and de-dupe on data.task_id (deliveries can repeat).

3. Recurring — register once, receive forever

Create a scheduled job (schedule_type of interval, cron, or email) and it fires your webhook on every run. A long-lived monitor (a daily briefing, an inbox watcher, a weekly report) streams results back for weeks with no polling. List a job's history with GET /v1/runs?job_id=….

Tip: webhooks beat polling for anything time-sensitive. Acknowledge fast (2xx), then process out-of-band.