Connect anything that can make an HTTPS request.
Create a notification service and API key in the web console, then send. By default, omit to and NOTIPOCKET automatically targets every approved recipient of that service. Use to only for a specific subset.
Quick start
Send JSON with a bearer API key. Do not include to for the normal all-approved send. Reuse the same Idempotency-Key when retrying the same business event.
curl --request POST 'https://api.notipocket.com/v1/messages' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: support-1824-created' \
--data '{"title":"New request","body":"Please review request 1824.","url":"https://example.com/support/1824","require_ack":true}'If URL rewriting is unavailable, use the same endpoint through: https://api.notipocket.com/index.php?r=/v1/messages
Recipient rules
The default audience is the approved recipient list managed for the notification service in the web console. You do not need to repeat Pocket IDs on every API request.
Default: all approved recipients
When the to field is completely omitted, NOTIPOCKET automatically selects every active account whose connection to the service is approved. This is the normal production sending mode.
{
"title": "Backup completed",
"body": "The daily backup completed successfully."
}Optional: specific recipients
Provide a to array only when the message should go to a subset. Every named Pocket ID must still be approved for the service. An explicit to: [] is invalid and is never interpreted as send-to-all.
{
"to": ["NP-AAAA-BBBB-CCCC"],
"title": "Private alert",
"body": "This alert is only for the selected recipient."
}Approval state and audience
Only approved connections belonging to active accounts are in the default audience. Pending, denied, blocked, deleted or inactive accounts are excluded. A muted recipient still gets an inbox recipient record but no push is dispatched. The audience is snapshotted at initial acceptance and blocking, account deletion, or approval withdrawal is checked again before push delivery.
Message fields
Recipients are resolved when the request is first accepted, then account and connection state are checked again immediately before push delivery. HTTP 202 means the message and queue work were durably accepted, not that a device displayed the notification.
| Field | Description | Limit |
|---|---|---|
| title | Required · Title | 200 chars |
| body | Required · Message body | 16 KiB UTF-8 |
| to | Optional · Optional: specific recipients | Omit = all approved |
| channel | Alert category | default |
| url / url_title | Open link | HTTPS |
| actions | Actions | 6 |
| priority | Priority | normal | high | low |
| require_ack / ack_policy | Needs confirmation | false · any | all |
| scheduled_at / expires_at | Scheduled time | RFC 3339 with timezone |
| thread_key / external_id | External reference | 200 chars |
| data | Extra data (JSON) | 4 KiB JSON |
| allow_partial | Allow partial recipient acceptance | Targeted mode only |
Sending examples
Most integrations can start with only title and body. Requests without to go to every approved recipient; requests with to go only to that approved subset.
1. Default: all approved recipients
POST /v1/messages
Authorization: Bearer YOUR_API_KEY
Idempotency-Key: order-20260927-1001
Content-Type: application/json
{
"title": "New order",
"body": "Order #1001 was received.",
"url": "https://example.com/orders/1001",
"url_title": "Open order"
}2. Optional: specific recipients
{
"to": ["NP-AAAA-BBBB-CCCC", "NP-DDDD-EEEE-FFFF"],
"title": "Selected staff only",
"body": "Only the approved recipients listed in to receive this message.",
"allow_partial": false
}3. Scheduled time
{
"title": "Maintenance starts soon",
"body": "Scheduled maintenance begins at 01:00.",
"scheduled_at": "2026-09-28T01:00:00+09:00",
"expires_at": "2026-09-28T03:00:00+09:00"
}Message actions
Actions run only after a user taps. A phone action prepares a call; SMS and email prepare a draft. URLs do not bypass the destination’s login.
{
"actions": [
{
"id": "call",
"type": "phone",
"phone": "+12025550147"
},
{
"id": "sms",
"type": "sms",
"phone": "+12025550147",
"body": "Hello"
},
{
"id": "reference",
"type": "copy",
"text": "1824"
}
]
}Responses and delivery state
The audience field is all_approved or targeted. accepted_recipients is the number of durable recipient rows created. excluded_recipients counts explicitly requested recipients skipped only when partial targeted delivery is enabled.
HTTP/1.1 202 Accepted
{
"success": true,
"data": {
"message_id": "0123456789abcdef0123456789abcdef",
"status": "queued",
"audience": "all_approved",
"accepted_recipients": 3,
"excluded_recipients": 0,
"duplicate": false,
"idempotency_expires_at": "2026-09-28T00:00:00+00:00"
},
"request_id": "..."
}Accepted means saved for processing, not displayed on a phone. Device settings, connectivity and push providers can delay delivery.
Authentication & safety
Store keys server-side. Repeated requests with the same project-scoped Idempotency-Key and content reuse one message for 24 hours; changed content returns 409.
Idempotency-Key prevents a retry of the same business event from creating another message. The same key with identical normalized content returns the original message_id; the same key with different content returns 409. For default all-approved sends, the recipient snapshot is taken on the first accepted request, so retrying the same idempotency key does not add recipients that joined later.
Legacy GET sending
GET sending is a restricted compatibility feature for systems that can only call a URL. Enable it per project and use a restricted legacy token. Without to, it sends to all currently approved recipients within that token’s allowed target set; with to, it targets only the named approved recipients within that set.
Legacy GET must be enabled explicitly. Use restricted tokens, not management keys. URLs can leak into logs and automated link checks can trigger requests; POST is preferred.
GET /v1/legacy/notify?token=RESTRICTED_TOKEN&request_id=UNIQUE_EVENT&title=TITLE&body=BODY # Optional targeted delivery: GET /v1/legacy/notify?token=RESTRICTED_TOKEN&request_id=UNIQUE_EVENT&to=NP-AAAA-BBBB-CCCC&title=TITLE&body=BODY
Signed callbacks
Verify the raw-body HMAC and timestamp before processing. Deduplicate event IDs. Return completed only after work finishes, or send a signed result later.
X-Notipocket-Event: EVENT_ID
X-Notipocket-Timestamp: UNIX_TIMESTAMP
X-Notipocket-Signature: sha256=HMAC_SHA256(timestamp + '.' + raw_body, signing_secret)
Verification response:
{"proof":"HMAC_SHA256(challenge, signing_secret)"}
Completed work response:
{"status":"completed"}
Asynchronous result: POST /v1/callbacks/result
{"event_id":"ACTION_EVENT_ID","status":"completed"}Limits & delivery
Requests are limited to 64 KiB and up to 6 external actions. A targeted to list can contain at most 100 recipients per request. When to is omitted, every approved recipient is selected subject to the project daily-recipient quota. Default retention is 30 days.
Common send errors
Error responses include the HTTP status, error.code, a localized message, details, and request_id. Keep request_id when correlating a failed call with server diagnostics.
NO_APPROVED_RECIPIENTS 422 No active approved recipient exists for the default audience. RECIPIENT_NOT_AVAILABLE 422 A targeted recipient is not active/approved, or a legacy key cannot target it. INVALID_REQUEST 422 Invalid field, empty explicit to list, invalid date/range, etc. UNKNOWN_FIELD 422 Unsupported request field. INVALID_API_KEY 401 Missing, invalid, expired or revoked project API key. IDEMPOTENCY_CONFLICT 409 Same Idempotency-Key was reused with different normalized content. QUOTA_EXCEEDED 429 Project daily recipient quota was exceeded. REQUEST_TOO_LARGE 413 Request/body exceeds configured size limits.OpenAPI 3.1 JSON ↓