Local development
SimpleQ delivers jobs by POSTing to your queue's webhookUrl from the cloud, so it can't reach a worker on localhost. To develop locally, expose your worker through a public tunnel and point the queue at the tunnel URL.
Start your worker
The examples listen on port 9000 and serve POST /webhook. Start your worker first, then open a tunnel to it.
Open a tunnel
Cloudflare Tunnel gives your local worker a public URL with no account or login:
# Install once: brew install cloudflared (macOS) — or see Cloudflare's docs for your platform.
cloudflared tunnel --url http://localhost:9000It prints a public https://<random>.trycloudflare.com URL that forwards to http://localhost:9000. Your webhook endpoint is that URL with /webhook appended.
Point the queue at the tunnel
Update the queue's webhookUrl to the tunnel URL. Via the API (use the queue's _id from the POST /v1/queues response):
curl -X PUT "$SQ_API_URL/v1/queues/<queue-id>" \
-H "Authorization: Bearer $SIMPLEQ_API_KEY" \
-H "content-type: application/json" \
-d '{ "webhookUrl": "https://<random>.trycloudflare.com/webhook" }'await fetch(`${process.env.SQ_API_URL}/v1/queues/<queue-id>`, {
method: 'PUT',
headers: { 'content-type': 'application/json', authorization: `Bearer ${process.env.SIMPLEQ_API_KEY}` },
body: JSON.stringify({ webhookUrl: 'https://<random>.trycloudflare.com/webhook' }),
});import os, httpx
httpx.put(
f"{os.environ['SQ_API_URL']}/v1/queues/<queue-id>",
headers={"authorization": f"Bearer {os.environ['SIMPLEQ_API_KEY']}"},
json={"webhookUrl": "https://<random>.trycloudflare.com/webhook"},
)SQ_API_URL— the SimpleQ API base:https://api.simpleq.io.SIMPLEQ_API_KEY— create one on the dashboard's API Keys page.<queue-id>— the queue's_id, returned when you created it (POST /v1/queues).
Prefer the dashboard? Open your queue, click Edit queue, and set Webhook URL to the tunnel URL (with /webhook appended).
The change takes effect on the next published job — typically within a second.
Publish a job and watch it arrive
curl -X POST "$SQ_API_URL/v1/queues/<your-queue>/jobs" \
-H "Authorization: Bearer $SIMPLEQ_API_KEY" \
-H "content-type: application/json" \
-d '{ "payload": { "hello": "world" }, "idempotencyKey": "local-test-1" }'The job is delivered through the tunnel to your worker. Signature verification works with no changes — the tunnel forwards the raw body byte-for-byte, so the x-simpleq-signature HMAC over the raw body still matches (see Signature verification).
Tunnel URLs change on restart
A quick Cloudflare tunnel gets a new URL every restart. When the URL changes, set the new webhookUrl again (re-run the PUT /v1/queues/<queue-id> call, or re-save it under Edit queue in the dashboard) — the next job uses it within about a second. A named Cloudflare tunnel gives you a stable URL that survives restarts.
Next steps
- Job delivery — the exact request your endpoint receives.
- Examples — full reference workers in Node, Python, Go, Java, PHP, and C#/.NET.