Skip to content

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:

bash
# Install once: brew install cloudflared (macOS) — or see Cloudflare's docs for your platform.
cloudflared tunnel --url http://localhost:9000

It 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):

bash
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" }'
js
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' }),
});
python
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

bash
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.