Hook endpoints
The four hook endpoints, their bodies and their responses.
Every hook endpoint sends one notification to the hook's recipient as a live send. How each shape is turned into a title, body, link and priority is explained in Hooks. This page lists the requests and responses.
Plain text#
/v1/hooks/{token}hk_…). No Authorization header.Headers#
- Rules
- Also
X-Titleort
- Rules
1–5,min,low,default,high,max,urgent; alsoX-Priorityorp- Default
high
data.tags.- Rules
- Comma-separated, first 10 kept; also
X-Tagsorta
- Rules
- https, up to 1,024 characters; also
X-Click
- Rules
- 1–255 characters
Body#
Plain text, read whatever the Content-Type is. It may be empty: without a Title header the title is then Notification.
⫻
curl
Response#
The same result as Send a notification: 202 Accepted for a new notification, 200 OK for a replay of the same Idempotency-Key.
⫻
202 Accepted
Discord#
/v1/hooks/{token}/discordhk_…). No Authorization header.Body#
Discord's webhook JSON, or multipart/form-data with a payload_json field (or content and username fields). These fields are read:
- Rules
- Required when there is no embed
icon.- Rules
- https only
name: value line in the body.- Rules
nameandvalue
url.- Rules
- https only
image.- Rules
- https only
Query#
204.- Rules
trueto get a message object back- Default
false
⫻
curl
Response#
Discord-style, so tools that check the answer are satisfied. A replay of the same Idempotency-Key gets the same answer as a new send. With wait=true, id is the Push notification id and content echoes the request's content.
Errors#
Errors use Discord's shape instead of Push's:
| Status | Body | When |
|---|---|---|
| 401 | {"message": "Invalid Webhook Token", "code": 50027} | Unknown or revoked token. |
| 429 | {"message": "You are being rate limited.", "retry_after": 12, "global": false} | Over a rate limit. The Retry-After header carries the same seconds. |
| 400 | {"message": "…", "code": 50035} | The notification is invalid, or a header such as Idempotency-Key is. |
| 400 | {"message": "The request body contains invalid JSON.", "code": 50109} | The body is not JSON, or not a Discord message. |
| 400 | {"message": "Cannot send an empty message", "code": 50006} | No content and no embed. |
| 400 | {"message": "…", "code": 0} | Any other Push error, such as no connected browsers, no credits, a suspended project or an idempotency conflict. message says which. |
| 500 | {"message": "500: Internal Server Error", "code": 0} | Something failed on Push's side. |
Slack#
/v1/hooks/{token}/slackhk_…). No Authorization header.Body#
Slack's incoming-webhook JSON, or application/x-www-form-urlencoded with the JSON in a payload field. These fields are read:
- Rules
- Required when there are no blocks and no attachment
header block's text is the title. Each section block's text.text and fields[].text are added to the body.- Rules
headerandsectionblocks are read
header block.url.- Rules
- https only
title: value line in the body.- Rules
titleandvalue
⫻
curl
Response#
Slack-style plain text: 200 with ok for a new send and for a replay. Errors are plain text too:
| Status | Body | When |
|---|---|---|
| 403 | invalid_token | Unknown or revoked token. |
| 429 | rate_limited | Over a rate limit. Retry-After says how many seconds to wait. |
| 400 | invalid_payload | The body is not valid JSON or not a Slack message, or the notification is invalid. |
| 400 | no_text | No text, no blocks and no attachment. |
| 400 | invalid_recipient, quota_exceeded, … | Any other Push error, as its code in lower case. |
| 500 | internal_error | Something failed on Push's side. |
Apprise#
/v1/hooks/{token}/apprisehk_…). No Authorization header.Body#
body. Apprise's json:// service sends this field.normal, normal, high or urgent. Without it, high.- Rules
info,success,warningorfailure
⫻
curl
Response#
The same result as Send a notification: 202 Accepted, or 200 OK for a replay.
Errors#
The plain text and Apprise endpoints answer with Push's error format:
| Code | HTTP | When |
|---|---|---|
| UNAUTHORIZED | 401 | The token is malformed, unknown or revoked. |
| PROJECT_SUSPENDED | 403 | The hook's project is suspended. |
| RATE_LIMITED | 429 | Over the hook's 60 requests per minute, the project's or the account's limit, or the per-IP limit for invalid tokens. Wait for Retry-After seconds. |
| VALIDATION_ERROR | 400 | The body is over 1 MiB, the Apprise body is not valid JSON or has an unknown type, Idempotency-Key is not valid, or the extracted notification breaks a field rule (a Click that is not https, for example) or the size limit. |
| IDEMPOTENCY_CONFLICT | 409 | The Idempotency-Key was already used with a different notification. |
| QUOTA_EXCEEDED | 402 | The free allowance is used up and the credit balance cannot cover this send. |
| INVALID_RECIPIENT | 422 | The hook's recipient has no connected browsers. |
| INTERNAL_ERROR | 500 | Something failed on Push's side. Safe to retry with the same Idempotency-Key. |
- Hook endpoints accept requests from any origin, so a browser can call them; the
Title,Priority,Tags,ClickandIdempotency-Keyheaders are allowed across origins. - The order of checks is: the token, the project, the rate limits,
Idempotency-Key, the body, then the same checks as an API send.