Skip to content
dply/edge

Resources

Messages

Send HTTP requests later, with retries, callbacks and cron schedules: a message queue your app publishes to over HTTPS.

dply Messages delivers HTTP requests for your app: now, after a delay, or on a cron schedule. It retries failures with backoff, can call you back when a delivery succeeds or gives up, and signs every request so the receiver can check it came from dply. Clients written for Upstash QStash work too: the Upstash-* header names are accepted alongside Dply-*.

Messages works in container apps and in SSR or hybrid (Worker) apps, on every plan.

Add it to an app

  1. In your app, open Overview.
  2. Choose Add resource, then Messages.
  3. Deploy the app.

The next deploy sets four variables:

Variable What it is
MESSAGES_URL Where to publish
MESSAGES_TOKEN Your app's publish token (a secret)
MESSAGES_SIGNING_KEY Checks the signature on deliveries
MESSAGES_NEXT_SIGNING_KEY The next signing key, for rotations

Manage tokens and signing keys under Projects → Messages.

Publish

Send the body you want delivered, with the destination URL in the path:

bash
curl -X POST "$MESSAGES_URL/v2/publish/https://example.com/hooks/welcome" \
  -H "Authorization: Bearer $MESSAGES_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Dply-Delay: 10m" \
  -d '{"user": 42}'

The reply holds the message id. Useful headers:

Header Effect
Dply-Delay Deliver later, for example 30s, 10m, 2h, 7d (at most 7 days)
Dply-Not-Before Deliver at a Unix time
Dply-Retries Retries after a failed delivery, up to 5
Dply-Method The method to deliver with (default POST)
Dply-Timeout How long a delivery may take, up to 5 minutes
Dply-Callback A URL called with the response after a successful delivery
Dply-Failure-Callback A URL called when the retries run out
Dply-Deduplication-Id Publishing the same id twice delivers once
Dply-Forward-* Sent on to the destination with the prefix removed

A delivery is done when the destination answers 2xx. Anything else is retried with growing gaps (at most a day apart). After the last retry the message goes to the dead-letter list, where you can see it, retry it or delete it.

Delivery is at least once: make receivers safe to run twice.

Schedules

Publish to /v2/schedules/{url} with a Dply-Cron header (5 fields, UTC) to send the same request on a schedule:

bash
curl -X POST "$MESSAGES_URL/v2/schedules/https://example.com/jobs/nightly" \
  -H "Authorization: Bearer $MESSAGES_TOKEN" \
  -H "Dply-Cron: 0 3 * * *"

Schedules can be listed, paused, resumed and deleted. An organization can have up to 100.

Check the signature

Each delivery carries a Dply-Signature header (also sent as Upstash-Signature): a JWT signed with MESSAGES_SIGNING_KEY, whose claims include the destination URL and a SHA-256 of the body. Verify it with the current key and fall back to MESSAGES_NEXT_SIGNING_KEY, so a key rotation never rejects a good delivery. QStash's Receiver from @upstash/qstash works with these keys.

Limits

  • Body: 1 MB
  • Delay: 7 days
  • Retries: 5
  • Publishes: 100 per second per organization
  • Destinations must be public http(s) URLs: not localhost, private or reserved addresses, .internal or .local names, or dply's own hosts.

Not supported yet: topics (URL groups), queues with parallelism, flow control and cron time zones.

Pricing

Meter Price Unit
Published messages (schedule firings and callbacks count) $0.50 per 100,000

Schedule firings and callbacks count as published messages.

View as Markdown llms.txt

dply/edge