Sending Notifications
Requirements
Section titled “Requirements”- An API key with
notifyorfullscope - The App ID of the app to send notifications to
Send to All Subscribers
Section titled “Send to All Subscribers”Send a notification to all active subscribers of the app.
curl -X POST https://api.todoke.dev/api/v1/notify \ -H "Authorization: Bearer pk_notify_key" \ -H "Content-Type: application/json" \ -d '{ "title": "New Update", "body": "There is an update available", "url": "https://yourapp.com/news", "icon": "https://yourapp.com/icon.png" }'import { PushCF } from "@todoke/sdk";
const client = new PushCF({ apiKey: "pk_notify_key",});
await client.notify({ title: "New Update", body: "There is an update available", url: "https://yourapp.com/news", icon: "https://yourapp.com/icon.png",});await fetch("https://api.todoke.dev/api/v1/notify", { method: "POST", headers: { "Authorization": "Bearer pk_notify_key", "Content-Type": "application/json", }, body: JSON.stringify({ title: "New Update", body: "There is an update available", url: "https://yourapp.com/news", }),});Send to a Specific User
Section titled “Send to a Specific User”Specify the endpoint field to send to only that subscriber.
curl -X POST https://api.todoke.dev/api/v1/notify \ -H "Authorization: Bearer pk_notify_key" \ -H "Content-Type: application/json" \ -d '{ "title": "Message for you", "body": "This is a targeted notification", "endpoint": "https://fcm.googleapis.com/fcm/send/..." }'Batch Send
Section titled “Batch Send”Send to multiple endpoints in a single request using the batch API.
curl -X POST https://api.todoke.dev/api/v1/notify/batch \ -H "Authorization: Bearer pk_notify_key" \ -H "Content-Type: application/json" \ -d '{ "endpoints": [ "https://fcm.googleapis.com/fcm/send/endpoint1", "https://fcm.googleapis.com/fcm/send/endpoint2" ], "payload": { "title": "Batch notification", "body": "Sent to multiple users" } }'Response: { "queued": 2 }
Request Parameters
Section titled “Request Parameters”POST /api/v1/notify
Section titled “POST /api/v1/notify”| Field | Type | Required | Description |
|---|---|---|---|
title | string | ✅ | Notification title |
body | string | ✅ | Notification body |
url | string | — | URL to navigate to on click |
icon | string | — | Notification icon URL |
badge | string | — | Badge icon URL |
endpoint | string | — | If specified, sends only to this subscriber |
POST /api/v1/notify/batch
Section titled “POST /api/v1/notify/batch”| Field | Type | Required | Description |
|---|---|---|---|
endpoints | string[] | ✅ | List of endpoints (max 100 items; returns 400 TOO_MANY_ENDPOINTS if exceeded) |
payload.title | string | ✅ | Notification title |
payload.body | string | ✅ | Notification body |
payload.url | string | — | URL to navigate to on click (https:// only) |
title and body are required. url / icon / badge only allow https:// URLs; specifying an http:// URL returns 400 INVALID_URL.
Limits and Errors
Section titled “Limits and Errors”- Payload size: the combined size of
title/body/url/icon/badgeis limited to 3,072 bytes (returns 413PAYLOAD_TOO_LARGEif exceeded) - Monthly sends: the Free plan is limited to 30,000 notifications (returns 429
MONTHLY_LIMIT_EXCEEDEDwithupgrade_urlif exceeded) - URL format:
url/icon/badgemust behttps://only (400INVALID_URL)
See Error Codes and Limits for the full list of error codes.
How It Works
Section titled “How It Works”REST API → Cloudflare Queues → Queue Consumer Worker → Browser PushNotifications are enqueued immediately upon receiving the request. The Consumer Worker automatically starts and sends them asynchronously, so there are no timeouts even with a large number of subscribers.