API reference
Webhooks
Register endpoints to receive event notifications.
/v1/webhooksList registered webhooks
webhooks:rNode.js SDKhonkio.webhooks.list()Requires webhooks:r.
Responses
200Every endpoint on the account, newest first. Not paginated.
Field Type Description data[]requiredobject[] idrequiredstring urlrequiredstring eventsrequiredstring[] activerequiredboolean deactivated_reasonrequiredstring Why delivery disabled the endpoint, when it did: e.g. "HTTP_401 for 26h across 7 events" after 24 hours of failure across at least 5 events, or SSRF_BLOCKED.
- Can be null
deactivated_atrequiredstring - Format: date-time
- Can be null
failing_sincerequiredstring The first failed attempt since the last successful delivery; null while the endpoint is healthy. Any delivered attempt clears it.
- Format: date-time
- Can be null
failed_eventsrequiredinteger Distinct events that have failed since failing_since. The endpoint is disabled once every attempt has failed for 24 hours and this reaches 5.
last_success_atrequiredstring The last delivered attempt, to within a minute.
- Format: date-time
- Can be null
last_failure_atrequiredstring - Format: date-time
- Can be null
last_failure_reasonrequiredstring The last failed attempt's result: HTTP_<status>, HTTP_<status>_REDIRECT_NOT_FOLLOWED, TIMEOUT or NETWORK_ERROR.
- Can be null
secret_rotated_atrequiredstring When the signing secret was last rotated (POST /v1/webhooks/{id}/rotate-secret); null while the endpoint still signs with the secret it was created with.
- Format: date-time
- Can be null
created_atrequiredstring - Format: date-time
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.webhooks.list()
if (error) throw new Error(error.message)
for (const w of data.data) console.log(w.id, w.url)curl https://api.honkio.ca/v1/webhooks \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooksRegister a webhook endpoint
webhooks:wNode.js SDKhonkio.webhooks.create()Requires webhooks:w.
Request body
| Field | Type | Description |
|---|---|---|
urlrequired | string | HTTPS URL to deliver events to. It must answer 2xx directly: deliveries never follow a redirect, so a 3xx is recorded as a failed attempt.
|
eventsrequired | string[] |
|
Responses
201The endpoint. signing_secret is shown only here: store it to verify X-HonkIO-Signature.
Field Type Description idrequiredstring urlrequiredstring eventsrequiredstring[] signing_secretrequiredstring 64 hex characters.
activerequiredboolean created_atrequiredstring - Format: date-time
noticerequiredstring - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 422VALIDATION_ERROR (not a public HTTPS URL, an unknown event, or an email event while email is off) or WEBHOOK_LIMIT_REACHED (10 endpoints per account).The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data: webhook, error } = await honkio.webhooks.create({
url: 'https://yourapp.ca/webhooks/honkio',
events: ['message.delivered', 'message.failed', 'message.received'],
})
if (error) throw new Error(error.message)
console.log(webhook.signing_secret) // shown once: store it nowcurl -X POST https://api.honkio.ca/v1/webhooks \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/honkio",
"events": [
"message.queued"
]
}'/v1/webhooks/{id}Get a webhook by ID
webhooks:rNode.js SDKhonkio.webhooks.get()Requires webhooks:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The endpoint.
Field Type Description idrequiredstring urlrequiredstring eventsrequiredstring[] activerequiredboolean deactivated_reasonrequiredstring Why delivery disabled the endpoint, when it did: e.g. "HTTP_401 for 26h across 7 events" after 24 hours of failure across at least 5 events, or SSRF_BLOCKED.
- Can be null
deactivated_atrequiredstring - Format: date-time
- Can be null
failing_sincerequiredstring The first failed attempt since the last successful delivery; null while the endpoint is healthy. Any delivered attempt clears it.
- Format: date-time
- Can be null
failed_eventsrequiredinteger Distinct events that have failed since failing_since. The endpoint is disabled once every attempt has failed for 24 hours and this reaches 5.
last_success_atrequiredstring The last delivered attempt, to within a minute.
- Format: date-time
- Can be null
last_failure_atrequiredstring - Format: date-time
- Can be null
last_failure_reasonrequiredstring The last failed attempt's result: HTTP_<status>, HTTP_<status>_REDIRECT_NOT_FOLLOWED, TIMEOUT or NETWORK_ERROR.
- Can be null
secret_rotated_atrequiredstring When the signing secret was last rotated (POST /v1/webhooks/{id}/rotate-secret); null while the endpoint still signs with the secret it was created with.
- Format: date-time
- Can be null
created_atrequiredstring - Format: date-time
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.webhooks.get('WEBHOOK_ID')
if (error) throw new Error(error.message)
console.log(data.url, data.events)curl https://api.honkio.ca/v1/webhooks/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/{id}Update a webhook
webhooks:mNode.js SDKhonkio.webhooks.update()Requires webhooks:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Request body
| Field | Type | Description |
|---|---|---|
url | string |
|
events | string[] |
|
active | boolean |
Responses
200The updated endpoint.
Field Type Description idrequiredstring urlrequiredstring eventsrequiredstring[] activerequiredboolean - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 422VALIDATION_ERROR: not a public HTTPS URL, an unknown event, or an email event while email is off.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { error } = await honkio.webhooks.update('WEBHOOK_ID', { events: ['message.delivered', 'message.failed'] })
if (error) throw new Error(error.message)curl -X PATCH https://api.honkio.ca/v1/webhooks/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
"message.delivered",
"message.failed"
]
}'/v1/webhooks/{id}Delete a webhook
webhooks:dNode.js SDKhonkio.webhooks.remove()Requires webhooks:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 204Deleted, with its delivery history and dead letters.
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { error } = await honkio.webhooks.remove('WEBHOOK_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/webhooks/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/{id}/deliveriesList recent delivery attempts for a webhook
webhooks:rNode.js SDKhonkio.webhooks.deliveries()Requires webhooks:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
limitquery | integer |
|
idrequiredpath | string |
Responses
200Recent delivery attempts, newest first.
Field Type Description data[]requiredobject[] idrequiredstring event_idrequiredstring event_typerequiredstring attemptrequiredinteger successrequiredboolean http_statusrequiredinteger - Can be null
error_reasonrequiredstring - Can be null
duration_msrequiredinteger - Can be null
occurred_atrequiredstring - Format: date-time
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 422VALIDATION_ERROR: the request failed validation; details names the fields.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.webhooks.deliveries('WEBHOOK_ID', { limit: 20 })
if (error) throw new Error(error.message)
console.log(data.data)curl https://api.honkio.ca/v1/webhooks/ID/deliveries \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/{id}/dead-lettersList events that failed all delivery attempts (dead-letter queue)
webhooks:rNode.js SDKhonkio.webhooks.deadLetters()Requires webhooks:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
limitquery | integer |
|
include_replayedquery | boolean |
|
idrequiredpath | string |
Responses
200Events that failed every attempt, newest first.
Field Type Description data[]requiredobject[] idrequiredstring event_idrequiredstring event_typerequiredstring failed_reasonrequiredstring Why the event stopped being retried: the last attempt's failure with the attempt count after about 24 hours of retries (e.g. "HTTP_500 after 8 attempts"), the same with "; endpoint disabled" when the endpoint was disabled while it was owed, ENDPOINT_DISABLED when you had switched the endpoint off, SSRF_BLOCKED, or queue_full.
created_atrequiredstring - Format: date-time
replayed_atrequiredstring - Format: date-time
- Can be null
payloadrequiredany The event body that failed to deliver: { id, type, created, account_id, data }.
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 422VALIDATION_ERROR: the request failed validation; details names the fields.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.webhooks.deadLetters('WEBHOOK_ID')
if (error) throw new Error(error.message)
for (const dl of data.data) console.log(dl.id)curl https://api.honkio.ca/v1/webhooks/ID/dead-letters \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/dead-letters/{dlid}/replayReplay a dead-lettered event against the original webhook URL
webhooks:mNode.js SDKhonkio.webhooks.replay()Sends the event again, signed with a fresh timestamp and marked X-HonkIO-Replay: true. 200 { status: "replayed" } when your endpoint accepted it; 502 { status: "failed", http_status, error_reason } when it did not (the event stays in the dead-letter queue and can be replayed again); 404 NOT_FOUND when the dead letter is not on your account; 409 DEAD_LETTER_ALREADY_REPLAYED when it was already replayed or a replay of it is in progress, or 409 ACCOUNT_SUSPENDED while the account is suspended or closed, in which case nothing is sent.
Requires webhooks:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
dlidrequiredpath | string |
Responses
200Your endpoint accepted the replay.
Field Type Description statusrequiredstring - One of: replayed
http_statusrequiredinteger - Can be null
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 409DEAD_LETTER_ALREADY_REPLAYED: already replayed, or a replay is in progress. Also ACCOUNT_SUSPENDED while the account is suspended or closed. Either way, nothing was sent.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
502WEBHOOK_REPLAY_FAILED: your endpoint did not accept the replay. The event stays in the dead-letter queue.
Field Type Description coderequiredstring Machine-readable error code, e.g. VALIDATION_ERROR.
messagerequiredstring Human-readable message in the request's locale (Accept-Language).
messageEnstring English message, always present alongside message.
messageFrstring French message, always present alongside message.
statusCoderequiredinteger The HTTP status, repeated in the body.
detailsany Present on some errors: an AJV validation array, or error-specific structured detail.
statusrequiredstring - One of: failed
http_statusrequiredinteger - Can be null
error_reasonrequiredstring - Can be null
Example
const { error } = await honkio.webhooks.replay('DEAD_LETTER_ID')
if (error) throw new Error(error.message)curl -X POST https://api.honkio.ca/v1/webhooks/dead-letters/DLID/replay \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/dead-letters/{dlid}Discard a dead-lettered event without replaying it
webhooks:dNode.js SDKhonkio.webhooks.discard()Requires webhooks:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
dlidrequiredpath | string |
Responses
- 204Discarded.
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { error } = await honkio.webhooks.discard('DEAD_LETTER_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/webhooks/dead-letters/DLID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/{id}/reactivateReactivate a webhook that was auto-disabled by delivery failures
webhooks:mNode.js SDKhonkio.webhooks.reactivate()Turns delivery back on and starts the endpoint's failure streak over. Events that failed while it was off are not resent: list them with GET /v1/webhooks/{id}/dead-letters and replay each one.
Requires webhooks:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The endpoint is active again.
Field Type Description idrequiredstring activerequiredboolean - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 422VALIDATION_ERROR: the URL no longer resolves to a public endpoint.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { error } = await honkio.webhooks.reactivate('WEBHOOK_ID')
if (error) throw new Error(error.message)curl -X POST https://api.honkio.ca/v1/webhooks/ID/reactivate \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/webhooks/{id}/rotate-secretRotate a webhook's signing secret
webhooks:mNode.js SDKhonkio.webhooks.rotateSecret()Generates a new signing secret and returns it once. The previous secret stops signing at once. Every delivery attempt, retries included, is signed with the secret the endpoint holds at that moment, so return a non-2xx for a signature you cannot verify and the retry arrives signed with the new secret.
Requires webhooks:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The new secret, shown only here. The previous secret stops signing at once; retries of anything the endpoint rejects during the switch are re-signed with this one.
Field Type Description idrequiredstring signing_secretrequiredstring 64 hex characters.
secret_rotated_atrequiredstring - Format: date-time
noticerequiredstring - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: test keys cannot reach live resources here. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND: no such resource on this account.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.webhooks.rotateSecret('WEBHOOK_ID')
if (error) throw new Error(error.message)
console.log(data.signing_secret) // the old secret stopped signing: store this onecurl -X POST https://api.honkio.ca/v1/webhooks/ID/rotate-secret \
-H "Authorization: Bearer mk_live_YOUR_KEY"
HonkIO