API reference
Push
Send push notifications through APNs and FCM with your own credentials.
/v1/push/appsList push apps
push:rNode.js SDKhonkio.push.apps.list()Requires push:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
limitquery | string | 1 to 100. Default 50. |
cursorquery | string | next_cursor from the previous page. |
Responses
200A page of push apps, newest first.
Field Type Description data[]requiredobject[] idrequiredstring papp_…
namerequiredstring apnsrequiredobject The APNs key's identifiers and health. The key itself is never returned. Null when the app has no APNs key.
- Can be null
key_idrequiredstring - Can be null
team_idrequiredstring - Can be null
bundle_idrequiredstring - Can be null
sandbox_statusrequiredstring The key against the APNs sandbox: valid once a send or check succeeds, invalid once Apple rejects the key itself.
- One of: unverified | valid | invalid
production_statusrequiredstring The key against APNs production.
- One of: unverified | valid | invalid
sandbox_coveredrequiredboolean Whether the key covered the sandbox at upload (verified valid, or Apple could not be asked). An uncovered environment's invalid is the key's scope, not a fault.
production_coveredrequiredboolean Whether the key covered production at upload.
fcmrequiredobject The FCM service account's project and health. The service account itself is never returned. Null when the app has none.
- Can be null
project_idrequiredstring - Can be null
statusrequiredstring The service account against FCM.
- One of: unverified | valid | invalid
webrequiredobject Web push: the app's VAPID key pair, generated with the app or imported. The private key is never returned. Null for an app made before web push that has no pair yet.
- Can be null
vapid_public_keyrequiredstring The VAPID public key (P-256, uncompressed, base64url): pass it to pushManager.subscribe() as applicationServerKey.
subjectrequiredstring The contact set for browser push services (VAPID subject): https://honkio.ca by default, or a mailto: of the account's verified email, or a mailto: address or https: URL on one of its verified sending domains. A push goes out with the default while the set one no longer qualifies (its domain was removed or lapsed).
importedrequiredboolean True when you imported the pair, false when HonkIO generated it.
created_atrequiredstring When the pair was generated or imported.
- Format: date-time
- Can be null
require_encryptionrequiredboolean True: every iOS and Android delivery is encrypted to the device's own key, and a device registered without encryption_public_key is refused (ENCRYPTION_KEY_MISSING), never sent in plaintext and never charged. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291). False: devices with a key get encrypted pushes, the rest plaintext.
placeholder_titlerequiredstring The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
placeholder_bodyrequiredstring The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
created_atrequiredstring - Format: date-time
has_morerequiredboolean next_cursorrequiredstring Pass it as cursor for the next page. Null on the last page.
- 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.
- 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.push.apps.list({ limit: 20 })
if (error) throw new Error(error.message)
for (const app of data.data) console.log(app.id, app.name)curl https://api.honkio.ca/v1/push/apps \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/appsCreate a push app
push:wNode.js SDKhonkio.push.apps.create()Requires push:w.
Request body
A name, and an APNs key, an FCM service account or both (either can be added later with PATCH).
| Field | Type | Description |
|---|---|---|
namerequired | string | Your name for the app, up to 100 characters, with no link in it.
|
apns | object | The APNs .p8 key (EC P-256, as Apple issues it) with its key_id, team_id and bundle_id. Checked against the sandbox and production before it is saved; never returned. |
key_p8required | string | The .p8 file's contents, BEGIN and END lines included.
|
key_idrequired | string | The 10-character Key ID Apple shows for the key.
|
team_idrequired | string | Your Apple Developer Team ID.
|
bundle_idrequired | string | The app's bundle identifier, sent as apns-topic.
|
fcm | object | The Firebase service account that sends for the app. Checked with Google before it is saved; never returned. |
service_account_jsonrequired | string | The service account's JSON key file, as a string.
|
placeholder_title | string | The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
|
placeholder_body | string | The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
|
require_encryption | boolean | True refuses any iOS or Android delivery that cannot be encrypted: a device registered without encryption_public_key is skipped with ENCRYPTION_KEY_MISSING, never sent in plaintext and never charged. False (the default) encrypts for each device that has a key and sends plaintext to the rest. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291) and needs no device key. It applies to pushes already scheduled or queued too. A dashboard session turning it off steps up first. |
Responses
201The app, with each credential's status.
Field Type Description idrequiredstring papp_…
namerequiredstring apnsrequiredobject The APNs key's identifiers and health. The key itself is never returned. Null when the app has no APNs key.
- Can be null
key_idrequiredstring - Can be null
team_idrequiredstring - Can be null
bundle_idrequiredstring - Can be null
sandbox_statusrequiredstring The key against the APNs sandbox: valid once a send or check succeeds, invalid once Apple rejects the key itself.
- One of: unverified | valid | invalid
production_statusrequiredstring The key against APNs production.
- One of: unverified | valid | invalid
sandbox_coveredrequiredboolean Whether the key covered the sandbox at upload (verified valid, or Apple could not be asked). An uncovered environment's invalid is the key's scope, not a fault.
production_coveredrequiredboolean Whether the key covered production at upload.
fcmrequiredobject The FCM service account's project and health. The service account itself is never returned. Null when the app has none.
- Can be null
project_idrequiredstring - Can be null
statusrequiredstring The service account against FCM.
- One of: unverified | valid | invalid
webrequiredobject Web push: the app's VAPID key pair, generated with the app or imported. The private key is never returned. Null for an app made before web push that has no pair yet.
- Can be null
vapid_public_keyrequiredstring The VAPID public key (P-256, uncompressed, base64url): pass it to pushManager.subscribe() as applicationServerKey.
subjectrequiredstring The contact set for browser push services (VAPID subject): https://honkio.ca by default, or a mailto: of the account's verified email, or a mailto: address or https: URL on one of its verified sending domains. A push goes out with the default while the set one no longer qualifies (its domain was removed or lapsed).
importedrequiredboolean True when you imported the pair, false when HonkIO generated it.
created_atrequiredstring When the pair was generated or imported.
- Format: date-time
- Can be null
require_encryptionrequiredboolean True: every iOS and Android delivery is encrypted to the device's own key, and a device registered without encryption_public_key is refused (ENCRYPTION_KEY_MISSING), never sent in plaintext and never charged. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291). False: devices with a key get encrypted pushes, the rest plaintext.
placeholder_titlerequiredstring The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
placeholder_bodyrequiredstring The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- 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.
- 403LIVE_KEY_REQUIRED: a push app is shared by test and live traffic, so a test key can read apps and register test devices but not create, change or delete them. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 409DPA_PUSH_ACCEPTANCE_REQUIRED: the account accepted the data processing agreement before it covered push notifications. Accept the current version in the dashboard (Settings, Data processing agreement) first. An account that never accepted the agreement is not asked.The standard error body.
- 422PUSH_CREDENTIAL_INVALID: Apple or Google rejected the credential (details carry provider, environment and reason), or VALIDATION_ERROR.The standard error body.
- 429RATE_LIMITED: at most 20 credential uploads and changes an hour per account (creating an app, or a PATCH that carries apns or fcm). Retry-After says when.The standard error body.
- 500Unexpected server error.The standard error body.
- 503PUSH_PROVIDER_UNAVAILABLE: Apple or Google could not be reached to check the credential; nothing was saved. Try again shortly.The standard error body.
Example
const { data: pushApp, error } = await honkio.push.apps.create({
name: 'Acme mobile',
apns: {
keyP8: process.env.APNS_KEY_P8 ?? '',
keyId: 'ABC123DEFG',
teamId: 'TEAM123456',
bundleId: 'ca.acme.app',
},
fcm: { serviceAccountJson: process.env.FCM_SERVICE_ACCOUNT_JSON ?? '' },
})
if (error) throw new Error(error.message)
console.log(pushApp.id)curl -X POST https://api.honkio.ca/v1/push/apps \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Courier"
}'/v1/push/apps/{id}Get a push app
push:rNode.js SDKhonkio.push.apps.get()Requires push:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The app.
Field Type Description idrequiredstring papp_…
namerequiredstring apnsrequiredobject The APNs key's identifiers and health. The key itself is never returned. Null when the app has no APNs key.
- Can be null
key_idrequiredstring - Can be null
team_idrequiredstring - Can be null
bundle_idrequiredstring - Can be null
sandbox_statusrequiredstring The key against the APNs sandbox: valid once a send or check succeeds, invalid once Apple rejects the key itself.
- One of: unverified | valid | invalid
production_statusrequiredstring The key against APNs production.
- One of: unverified | valid | invalid
sandbox_coveredrequiredboolean Whether the key covered the sandbox at upload (verified valid, or Apple could not be asked). An uncovered environment's invalid is the key's scope, not a fault.
production_coveredrequiredboolean Whether the key covered production at upload.
fcmrequiredobject The FCM service account's project and health. The service account itself is never returned. Null when the app has none.
- Can be null
project_idrequiredstring - Can be null
statusrequiredstring The service account against FCM.
- One of: unverified | valid | invalid
webrequiredobject Web push: the app's VAPID key pair, generated with the app or imported. The private key is never returned. Null for an app made before web push that has no pair yet.
- Can be null
vapid_public_keyrequiredstring The VAPID public key (P-256, uncompressed, base64url): pass it to pushManager.subscribe() as applicationServerKey.
subjectrequiredstring The contact set for browser push services (VAPID subject): https://honkio.ca by default, or a mailto: of the account's verified email, or a mailto: address or https: URL on one of its verified sending domains. A push goes out with the default while the set one no longer qualifies (its domain was removed or lapsed).
importedrequiredboolean True when you imported the pair, false when HonkIO generated it.
created_atrequiredstring When the pair was generated or imported.
- Format: date-time
- Can be null
require_encryptionrequiredboolean True: every iOS and Android delivery is encrypted to the device's own key, and a device registered without encryption_public_key is refused (ENCRYPTION_KEY_MISSING), never sent in plaintext and never charged. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291). False: devices with a key get encrypted pushes, the rest plaintext.
placeholder_titlerequiredstring The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
placeholder_bodyrequiredstring The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- 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.
- 404PUSH_APP_NOT_FOUND: no push app with that id 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: pushApp, error } = await honkio.push.apps.get('APP_ID')
if (error) throw new Error(error.message)
console.log(pushApp.name, pushApp.apns?.sandbox_status, pushApp.fcm?.status)curl https://api.honkio.ca/v1/push/apps/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/apps/{id}Update a push app
push:mNode.js SDKhonkio.push.apps.update()Requires push:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Request body
The fields to change. An apns or fcm block replaces that credential whole and is checked again.
| Field | Type | Description |
|---|---|---|
name | string | Your name for the app, up to 100 characters, with no link in it.
|
apns | object | The APNs .p8 key (EC P-256, as Apple issues it) with its key_id, team_id and bundle_id. Checked against the sandbox and production before it is saved; never returned. |
key_p8required | string | The .p8 file's contents, BEGIN and END lines included.
|
key_idrequired | string | The 10-character Key ID Apple shows for the key.
|
team_idrequired | string | Your Apple Developer Team ID.
|
bundle_idrequired | string | The app's bundle identifier, sent as apns-topic.
|
fcm | object | The Firebase service account that sends for the app. Checked with Google before it is saved; never returned. |
service_account_jsonrequired | string | The service account's JSON key file, as a string.
|
placeholder_title | string | The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it. Null clears it.
|
placeholder_body | string | The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it. Null clears it.
|
web_push_subject | string | The contact sent to browser push services with each web push (VAPID subject): a mailto: of the account's verified email, or a mailto: address or https: URL on one of your verified sending domains (or a name under one); anything else is 422 VALIDATION_ERROR. Null goes back to the default, https://honkio.ca. If the domain stops being verified, pushes go out with the default until it is again. The key pair stays, so no browser has to subscribe again.
|
require_encryption | boolean | True refuses any iOS or Android delivery that cannot be encrypted: a device registered without encryption_public_key is skipped with ENCRYPTION_KEY_MISSING, never sent in plaintext and never charged. False (the default) encrypts for each device that has a key and sends plaintext to the rest. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291) and needs no device key. It applies to pushes already scheduled or queued too. A dashboard session turning it off steps up first. |
Responses
200The updated app.
Field Type Description idrequiredstring papp_…
namerequiredstring apnsrequiredobject The APNs key's identifiers and health. The key itself is never returned. Null when the app has no APNs key.
- Can be null
key_idrequiredstring - Can be null
team_idrequiredstring - Can be null
bundle_idrequiredstring - Can be null
sandbox_statusrequiredstring The key against the APNs sandbox: valid once a send or check succeeds, invalid once Apple rejects the key itself.
- One of: unverified | valid | invalid
production_statusrequiredstring The key against APNs production.
- One of: unverified | valid | invalid
sandbox_coveredrequiredboolean Whether the key covered the sandbox at upload (verified valid, or Apple could not be asked). An uncovered environment's invalid is the key's scope, not a fault.
production_coveredrequiredboolean Whether the key covered production at upload.
fcmrequiredobject The FCM service account's project and health. The service account itself is never returned. Null when the app has none.
- Can be null
project_idrequiredstring - Can be null
statusrequiredstring The service account against FCM.
- One of: unverified | valid | invalid
webrequiredobject Web push: the app's VAPID key pair, generated with the app or imported. The private key is never returned. Null for an app made before web push that has no pair yet.
- Can be null
vapid_public_keyrequiredstring The VAPID public key (P-256, uncompressed, base64url): pass it to pushManager.subscribe() as applicationServerKey.
subjectrequiredstring The contact set for browser push services (VAPID subject): https://honkio.ca by default, or a mailto: of the account's verified email, or a mailto: address or https: URL on one of its verified sending domains. A push goes out with the default while the set one no longer qualifies (its domain was removed or lapsed).
importedrequiredboolean True when you imported the pair, false when HonkIO generated it.
created_atrequiredstring When the pair was generated or imported.
- Format: date-time
- Can be null
require_encryptionrequiredboolean True: every iOS and Android delivery is encrypted to the device's own key, and a device registered without encryption_public_key is refused (ENCRYPTION_KEY_MISSING), never sent in plaintext and never charged. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291). False: devices with a key get encrypted pushes, the rest plaintext.
placeholder_titlerequiredstring The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
placeholder_bodyrequiredstring The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- 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.
- 403LIVE_KEY_REQUIRED for a test key; STEP_UP_REQUIRED when a dashboard session turns require_encryption off without an api_keys:elevate step-up; FORBIDDEN when the key lacks push modify permission, or the account is suspended or closed.The standard error body.
- 404PUSH_APP_NOT_FOUND: no push app with that id on this account.The standard error body.
- 422PUSH_CREDENTIAL_INVALID: Apple or Google rejected the credential (details carry provider, environment and reason), or VALIDATION_ERROR (including a web_push_subject that is not the account's own: its verified email, or on one of its verified sending domains).The standard error body.
- 429RATE_LIMITED: at most 20 credential uploads and changes an hour per account (creating an app, or a PATCH that carries apns or fcm). Retry-After says when.The standard error body.
- 500Unexpected server error.The standard error body.
- 503PUSH_PROVIDER_UNAVAILABLE: Apple or Google could not be reached to check the credential; nothing was saved. Try again shortly.The standard error body.
Example
// requireEncryption: refuse (and never charge) a device that registered no encryption key.
const { error } = await honkio.push.apps.update('APP_ID', { name: 'Acme mobile (prod)', requireEncryption: true })
if (error) throw new Error(error.message)curl -X PATCH https://api.honkio.ca/v1/push/apps/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme mobile (prod)",
"require_encryption": true
}'/v1/push/apps/{id}Delete a push app
push:dNode.js SDKhonkio.push.apps.delete()Requires push:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 204Deleted.
- 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: a push app is shared by test and live traffic, so a test key can read apps and register test devices but not create, change or delete them. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404PUSH_APP_NOT_FOUND: no push app with that id 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.push.apps.delete('APP_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/push/apps/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/apps/{id}/web/vapid-keysGenerate or import the web push key pair
push:mNode.js SDKhonkio.push.web.setVapidKeys()Requires push:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Request body
Replace the app's web push (VAPID) key pair: send nothing to generate a new one, or both keys to import your own. A new public key retires every browser registered on the app, in both modes (push_device.deactivated, reason VAPID_KEY_REPLACED), until it subscribes again; importing the pair already in place retires none.
| Field | Type | Description |
|---|---|---|
public_key | string | To import: the P-256 public key, uncompressed, base64url (the applicationServerKey your site subscribed with).
|
private_key | string | To import: the matching 32-byte private key, base64url. Encrypted at rest and never returned.
|
subject | string | The VAPID subject, as web_push_subject on PATCH: a mailto: of the account's verified email, or a mailto: address or https: URL on one of your verified sending domains. Left out keeps the current one; null goes back to the default.
|
Responses
200The app, with its new web push public key (web.vapid_public_key). The private key is never returned. When the public key changed, every browser registered on the app (both modes) was retired with VAPID_KEY_REPLACED, and one push_app.vapid_key_replaced webhook reports how many in each mode (no push_device.deactivated per browser).
Field Type Description idrequiredstring papp_…
namerequiredstring apnsrequiredobject The APNs key's identifiers and health. The key itself is never returned. Null when the app has no APNs key.
- Can be null
key_idrequiredstring - Can be null
team_idrequiredstring - Can be null
bundle_idrequiredstring - Can be null
sandbox_statusrequiredstring The key against the APNs sandbox: valid once a send or check succeeds, invalid once Apple rejects the key itself.
- One of: unverified | valid | invalid
production_statusrequiredstring The key against APNs production.
- One of: unverified | valid | invalid
sandbox_coveredrequiredboolean Whether the key covered the sandbox at upload (verified valid, or Apple could not be asked). An uncovered environment's invalid is the key's scope, not a fault.
production_coveredrequiredboolean Whether the key covered production at upload.
fcmrequiredobject The FCM service account's project and health. The service account itself is never returned. Null when the app has none.
- Can be null
project_idrequiredstring - Can be null
statusrequiredstring The service account against FCM.
- One of: unverified | valid | invalid
webrequiredobject Web push: the app's VAPID key pair, generated with the app or imported. The private key is never returned. Null for an app made before web push that has no pair yet.
- Can be null
vapid_public_keyrequiredstring The VAPID public key (P-256, uncompressed, base64url): pass it to pushManager.subscribe() as applicationServerKey.
subjectrequiredstring The contact set for browser push services (VAPID subject): https://honkio.ca by default, or a mailto: of the account's verified email, or a mailto: address or https: URL on one of its verified sending domains. A push goes out with the default while the set one no longer qualifies (its domain was removed or lapsed).
importedrequiredboolean True when you imported the pair, false when HonkIO generated it.
created_atrequiredstring When the pair was generated or imported.
- Format: date-time
- Can be null
require_encryptionrequiredboolean True: every iOS and Android delivery is encrypted to the device's own key, and a device registered without encryption_public_key is refused (ENCRYPTION_KEY_MISSING), never sent in plaintext and never charged. Browsers (web) are never refused for it: web push is always encrypted to the browser (RFC 8291). False: devices with a key get encrypted pushes, the rest plaintext.
placeholder_titlerequiredstring The title Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- Can be null
placeholder_bodyrequiredstring The body Apple and Google see on an encrypted push, shown if the device cannot decrypt it.
- 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.
- 403LIVE_KEY_REQUIRED for a test key; STEP_UP_REQUIRED for a dashboard session without an api_keys:elevate step-up; FORBIDDEN when the key lacks push modify permission, or the account is suspended or closed.The standard error body.
- 404PUSH_APP_NOT_FOUND: no push app with that id on this account.The standard error body.
- 422VALIDATION_ERROR: only one of the two keys, a key not on P-256, a private key that does not match the public key, or a subject that is not an https: URL or a mailto: address, or not the account's own (its verified email, or on one of its verified sending domains).The standard error body.
- 429RATE_LIMITED: at most 20 credential uploads and changes an hour per account (creating an app, or a PATCH that carries apns or fcm). Retry-After says when.The standard error body.
- 500Unexpected server error.The standard error body.
Example
// No keys: generate a new pair. Both keys: import yours.
const { data: pushApp, error } = await honkio.push.web.setVapidKeys('APP_ID')
if (error) throw new Error(error.message)
console.log(pushApp.web?.vapid_public_key)curl -X POST https://api.honkio.ca/v1/push/apps/ID/web/vapid-keys \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/devicesList registered devices
push:rNode.js SDKhonkio.push.devices.list()Requires push:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
app_idquery | string | |
user_idquery | string | |
activequery | string | true or false. |
limitquery | string | 1 to 100. Default 50. |
cursorquery | string | next_cursor from the previous page. |
Responses
200A page of devices in the calling key's mode, newest first.
Field Type Description data[]requiredobject[] idrequiredstring pdev_…
app_idrequiredstring user_idrequiredstring Your own id for the person.
platformrequiredstring web is a browser's push subscription.
- One of: ios | android | web
apns_environmentrequiredstring The APNs environment of an iOS device; null for Android and web.
- One of: sandbox | production
- Can be null
encryption_key_idrequiredstring The id of the encryption key the device registered (the first 16 characters of base64url(SHA-256(public key))), sent as kid in each push encrypted to it. Null when it registered none, and always null for web. The key itself is never returned.
- Can be null
activerequiredboolean False once the device was retired; a retired device is never sent to.
deactivated_reasonrequiredstring Why it was retired: UNREGISTERED or INVALID_TOKEN (Apple or Google; INVALID_TOKEN too for a browser subscription its push service no longer knows, or that HonkIO can no longer read), APP_MISMATCH (a token for another app, on a credential that has worked), DEVICE_LIMIT (the per-user limit), APP_DELETED (its app was deleted), VAPID_KEY_REPLACED (a browser, when the app's web push key pair was replaced), VAPID_KEY_MISMATCH (a browser whose push service refused the app's key five times in a row over at least a day), DUPLICATE (a second row for the same browser subscription, left by an encryption key rotation; the other row stays active), DELETED (you unregistered it) or RECIPIENT_DELETED (you deleted the recipient profile for its user_id). Null while active.
- Can be null
last_seen_atrequiredstring When the token was last registered.
- Format: date-time
created_atrequiredstring - Format: date-time
has_morerequiredboolean next_cursorrequiredstring Pass it as cursor for the next page. Null on the last page.
- 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.
- 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.push.devices.list({ userId: 'user_1042' })
if (error) throw new Error(error.message)
for (const device of data.data) console.log(device.id, device.platform, device.active)curl https://api.honkio.ca/v1/push/devices \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/devicesRegister a device token
push_devices:wNode.js SDKhonkio.push.devices.register()Requires push_devices:w.
Request body
A device token, or a browser's push subscription, for one of your users. Registering a known token or subscription refreshes it, and moves it to user_id if that changed.
| Field | Type | Description |
|---|---|---|
app_idrequired | string | The push app the device belongs to.
|
token | string | The APNs or FCM device token, as the platform gives it to your app. Required for iOS and Android; not sent for web.
|
platformrequired | string | ios, android or web.
|
user_idrequired | string | Your own id for the person, up to 255 characters. A send to this user_id reaches each of their active devices and browsers.
|
apns_environment | string | sandbox or production, required for iOS: the APNs environment the build registered with (debug builds use the sandbox).
|
subscription | object | Web only, and required there: the browser's PushSubscription as its toJSON() gives it. The endpoint must be a browser push service (Google, Mozilla, Apple or Microsoft) over HTTPS. |
endpointrequired | string | The push service URL the browser was given.
|
expirationTime | number | As the browser gives it; not stored.
|
keysrequired | object | The browser's keys the payload is encrypted to (RFC 8291). |
p256dhrequired | string | The browser's P-256 public key, base64url.
|
authrequired | string | The 16-byte auth secret, base64url.
|
encryption_public_key | string | iOS and Android only (refused for web: web push is already encrypted to the browser, RFC 8291, and needs no device key). The public key the HonkIO push package generated on the device: base64url (no padding) of the 65-byte uncompressed P-256 point. Pushes to this device are then encrypted to it, so Apple and Google never see their content. Devices are matched by token: registering the same token again without this field keeps its stored key, but a new token (an APNs or FCM token refresh) is a new device with no key, so send the key with every token (the packages give it with the token). A new key replaces the old one. null removes it: on an app with require_encryption the device then gets no pushes until it registers a key again; without require_encryption its pushes go in plaintext, which is why require_encryption is the guard against a key being removed.
|
Responses
200The device, registered or refreshed.
Field Type Description idrequiredstring pdev_…
app_idrequiredstring user_idrequiredstring Your own id for the person.
platformrequiredstring web is a browser's push subscription.
- One of: ios | android | web
apns_environmentrequiredstring The APNs environment of an iOS device; null for Android and web.
- One of: sandbox | production
- Can be null
encryption_key_idrequiredstring The id of the encryption key the device registered (the first 16 characters of base64url(SHA-256(public key))), sent as kid in each push encrypted to it. Null when it registered none, and always null for web. The key itself is never returned.
- Can be null
activerequiredboolean False once the device was retired; a retired device is never sent to.
deactivated_reasonrequiredstring Why it was retired: UNREGISTERED or INVALID_TOKEN (Apple or Google; INVALID_TOKEN too for a browser subscription its push service no longer knows, or that HonkIO can no longer read), APP_MISMATCH (a token for another app, on a credential that has worked), DEVICE_LIMIT (the per-user limit), APP_DELETED (its app was deleted), VAPID_KEY_REPLACED (a browser, when the app's web push key pair was replaced), VAPID_KEY_MISMATCH (a browser whose push service refused the app's key five times in a row over at least a day), DUPLICATE (a second row for the same browser subscription, left by an encryption key rotation; the other row stays active), DELETED (you unregistered it) or RECIPIENT_DELETED (you deleted the recipient profile for its user_id). Null while active.
- Can be null
last_seen_atrequiredstring When the token was last registered.
- Format: date-time
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.
- 404PUSH_APP_NOT_FOUND: no push app with that id on this account.The standard error body.
- 409PUSH_DEVICE_LIMIT: the app already has its maximum of active devices in this mode (1,000,000 live, 1,000 test).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: device, error } = await honkio.push.devices.register({
appId: 'APP_ID',
token: 'DEVICE_TOKEN',
platform: 'ios',
userId: 'user_1042',
apnsEnvironment: 'production',
encryptionPublicKey: 'DEVICE_PUBLIC_KEY', // the key the HonkIO push package made on the device
})
if (error) throw new Error(error.message)
console.log(device.id, device.active, device.encryption_key_id)curl -X PUT https://api.honkio.ca/v1/push/devices \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"app_id": "papp_0123456789abcdef01234567",
"platform": "ios",
"user_id": "user_42"
}'/v1/push/devices/{id}Unregister a device
push_devices:dNode.js SDKhonkio.push.devices.delete()Requires push_devices:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 204Unregistered.
- 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.
- 404PUSH_DEVICE_NOT_FOUND: no device with that id in this key's mode.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.push.devices.delete('DEVICE_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/push/devices/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/pushList pushes
push:rNode.js SDKhonkio.push.list()Newest first. Each push carries accepted_count, the devices Apple or Google accepted it for (the per-device results are on GET /v1/push/{id}).
Requires push:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
app_idquery | string | |
user_idquery | string | |
statusquery | string | One of queued, sending, sent, failed, fell_back. |
created_afterquery | string | ISO 8601 date-time with an offset: created at or after. |
created_beforequery | string | ISO 8601 date-time with an offset: created at or before. |
limitquery | string | 1 to 100. Default 50. |
cursorquery | string | next_cursor from the previous page. |
Responses
200A page of pushes in the calling key's mode, newest first, each with accepted_count.
Field Type Description data[]requiredobject[] idrequiredstring app_idrequiredstring statusrequiredstring scheduled: accepted with scheduled_at and waiting for it. cancelled: a scheduled push cancelled before it went out; what it reserved was given back.
- One of: scheduled | queued | sending | sent | failed | fell_back | cancelled
torequiredobject user_idrequiredstring - Can be null
device_idrequiredstring - Can be null
titlerequiredstring - Can be null
bodyrequiredstring - Can be null
datarequiredobject Null once purged.
- Can be null
badgerequiredinteger - Can be null
soundrequiredstring - Can be null
thread_idrequiredstring - Can be null
ttlrequiredinteger Seconds.
- Can be null
priorityrequiredstring - One of: high | normal
- Can be null
collapse_keyrequiredstring - Can be null
encryptedrequiredboolean The app's require_encryption when the push was sent: true means every delivery was encrypted or refused with ENCRYPTION_KEY_MISSING. Each delivery's encrypted says what it got (false for a browser: web push is encrypted to it by RFC 8291, not with a device key).
device_countrequiredinteger Devices the push was sent to (and charged for) at intake; devices refused for a missing encryption key are not counted.
accepted_countinteger Devices and browsers whose push service (Apple, Google, Mozilla or Microsoft) accepted the push. On GET /v1/push and GET /v1/push/{id}; not on the send response.
free_countrequiredinteger Deliveries covered by the monthly free allotment, net of refunds.
charge_millicentsrequiredinteger What the push cost, exactly, in CAD millicents, net of refunds.
cost_centsrequiredinteger Whole cents this push debited from the balance.
fallbackrequiredobject - Can be null
smsrequiredobject torequiredstring - Can be null
fromrequiredstring - Can be null
bodyrequiredstring - Can be null
fallback_message_idrequiredstring - Can be null
fallback_reasonrequiredstring - Can be null
failure_coderequiredstring - Can be null
failure_messagerequiredstring - Can be null
body_purged_atrequiredstring - Format: date-time
- Can be null
livemoderequiredboolean sent_atrequiredstring - Format: date-time
- Can be null
scheduled_atrequiredstring When a scheduled push is (or was) due to go out. Null on a push sent at once.
- Format: date-time
- Can be null
expires_atrequiredstring The expires_at a scheduled push was given: the latest it may go out. Null when none was given, which means scheduled_at plus 24 hours. One that cannot go out by then fails with failure_code SCHEDULED_SEND_EXPIRED and is refunded.
- Format: date-time
- Can be null
created_atrequiredstring - Format: date-time
updated_atrequiredstring - Format: date-time
deliveries[]object[] Each device's delivery result. On GET /v1/push/{id} only.
idrequiredstring device_idrequiredstring Null once the device is deleted (30 days after it was deactivated); the delivery result stays.
- Can be null
providerrequiredstring webpush: a browser's push service.
- One of: apns | fcm | webpush
provider_message_idrequiredstring - Can be null
statusrequiredstring - One of: pending | accepted | rejected | retrying
billedrequiredboolean encryptedrequiredboolean Whether it was sent encrypted to the device's own key.
error_coderequiredstring Why it was rejected, e.g. DEVICE_TOKEN_INVALID, APP_MISMATCH, CREDENTIAL_INVALID, NO_CREDENTIAL, ENCRYPTION_KEY_MISSING (the app requires encryption and the device registered no key: not sent, not charged), PAYLOAD_REJECTED or PROVIDER_ERROR.
- Can be null
attemptsrequiredinteger created_atrequiredstring - Format: date-time
updated_atrequiredstring - Format: date-time
has_morerequiredboolean next_cursorrequiredstring Pass it as cursor for the next page. Null on the last page.
- 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.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.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.push.list({ status: 'failed', limit: 20 })
if (error) throw new Error(error.message)
for (const push of data.data) console.log(push.id, push.status)curl https://api.honkio.ca/v1/push \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/pushSend a push notification
push:wNode.js SDKhonkio.push.send()Sends to every active device of to.user_id, or to one to.device_id. Answers 202 with the push queued and the number of devices targeted. Each accepted live delivery costs $5.00 per 1,000 after the first 2,500 each calendar month (Toronto time), which are free; rejected deliveries are refunded. With fallback.sms, a push that no device accepts is sent as a text instead, under every rule POST /v1/messages applies; the key needs messages:w for that (403 FORBIDDEN otherwise), and still needs it when the fallback fires. data is at most 4096 bytes serialized and 64 keys. collapse_key (1 to 64 visible ASCII characters) lets a newer push replace an older one with the same key. 403 PUSH_DISABLED when push is turned off for the account; 422 PUSH_PAYLOAD_TOO_LARGE when the final provider payload, after encryption, is over 4096 bytes; 429 PUSH_DAILY_CAP over the daily push limit. The same Idempotency-Key returns the original push; with a different body it is 409 IDEMPOTENCY_KEY_REUSED. A key starting with notify: is reserved for HonkIO: 422 IDEMPOTENCY_KEY_RESERVED. With scheduled_at (1 minute to 30 days ahead) the push is accepted with status scheduled and charged now for the devices targeted now, and counts against the daily limit of the day it is due. When it is due it is sent like any other push: an account suspended or with push turned off since fails it and refunds it, a device deactivated since is a rejected (refunded) delivery, and the fallback text runs every /v1/messages rule at that moment. Until then PATCH /v1/push/{id} moves it and DELETE /v1/push/{id} cancels it and refunds the charge. In place of title and body, template (a template's id or alias), variables and language (en or fr) send that template's push part, rendered: a live key the published version, a test key the draft. A language without a push part uses the default language's; a template with no push part answers 422 TEMPLATE_CHANNEL_MISSING. fallback.sms.body stays inline text: a fallback from a template comes with Notify.
Requires push:w.
Parameters
| Parameter | Type | Description |
|---|---|---|
Idempotency-Keyheader | string |
|
Request body
One push: an app, a target, and a title, a body, data or a template.
| Field | Type | Description |
|---|---|---|
app_idrequired | string | The push app to send with.
|
torequired | object | Exactly one of user_id (every active device of that user) or device_id (one device). |
user_id | string | Your own id for the person.
|
device_id | string | One registered device (pdev_…).
|
title | string | The notification title, up to 1000 characters. Not with a template.
|
body | string | The notification text, up to 4000 characters. Required unless you send data or a template; not with a template.
|
template | string | A template's id or alias (/v1/templates): its push part is rendered and sent in place of title and body, held to their limits. A live key sends the published version, a test key the draft. 422 TEMPLATE_CHANNEL_MISSING when it has no push part.
|
variables | object | Values for the template's variables. One with neither a value nor a fallback refuses the send (422 EMAIL_TEMPLATE_VARIABLE_MISSING, details.keys). Only with template. |
language | string | en or fr: the template's language version. When it has no push part, the default language's is sent. Only with template; left out, the default language.
|
data | object | String values for your app, at most 64 keys and 4096 bytes as JSON. With no title and no body the push is a silent background push, without badge or sound, to each device that gets it unencrypted; a device with an encryption key gets the placeholder alert instead. |
badge | integer | The iOS badge number to show, 0 to clear it.
|
sound | string | The sound to play: a sound file bundled in the app, or default.
|
thread_id | string | Groups notifications on iOS (thread-id) and Android (tag).
|
ttl | integer | Seconds Apple or Google keeps trying to deliver while the device is offline, up to 28 days. 0 means now or never.
|
priority | string | high (the default) or normal. Normal lets the device save power and may delay delivery.
|
collapse_key | string | 1 to 64 visible ASCII characters, no spaces: a newer push with the same key replaces an older one not yet shown. |
fallback | object | A text to send instead when no device accepts the push. The key needs messages:w. |
smsrequired | object | |
torequired | string | The mobile number to text, E.164.
|
fromrequired | string | One of your numbers, E.164.
|
bodyrequired | string | The text, up to 1600 characters.
|
scheduled_at | string | Send later: an ISO 8601 date-time with an offset, 1 minute to 30 days ahead.
|
expires_at | string | The latest the scheduled send may go out: 1 minute to 24 hours after scheduled_at, and only with it. Without it, scheduled_at plus 24 hours. A send that cannot go out by then fails with SCHEDULED_SEND_EXPIRED and is refunded.
|
Responses
202Default Response
Field Type Description idstring statusstring scheduled, queued, sending, sent, failed, fell_back or cancelled. scheduled: accepted with scheduled_at and waiting for it; cancelled: a scheduled push cancelled before it went out, its charge refunded.
scheduled_atstring When a scheduled push is (or was) due to go out. Null on a push sent at once.
- Format: date-time
- Can be null
expires_atstring The expires_at a scheduled push was given: the latest it may go out. Null when none was given, which means scheduled_at plus 24 hours.
- Format: date-time
- Can be null
livemodeboolean device_countinteger Devices targeted at intake.
collapse_keystring Sent as APNs apns-collapse-id and FCM android.collapse_key: a newer push with the same key replaces an older one not yet shown. Null when none was given.
- Can be null
free_countinteger Deliveries covered by the monthly free allotment, net of refunds.
charge_millicentsinteger What the push cost, exactly, in CAD millicents (1/1000 of a cent): accepted billed deliveries times the price, net of refunds for rejected ones.
cost_centsinteger Whole cents this push debited from the balance, often 0 because prepaid credit is spent first. Approximate once rejected deliveries are refunded (the refund returns millicents to a pool shared with email); charge_millicents is the exact figure.
- 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.
- 4XXDefault Response
- 5XXDefault Response
Example
const { data: push, error } = await honkio.push.send({
appId: 'APP_ID',
to: { userId: 'user_1042' },
title: 'Your code',
body: '123456',
}, { idempotencyKey: 'login-code-1042-2026-11-03' })
if (error) throw new Error(error.message)
console.log(push.id, push.status, push.device_count)curl -X POST https://api.honkio.ca/v1/push \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"app_id": "papp_0123456789abcdef01234567",
"to": {
"user_id": "user_42"
}
}'/v1/push/usageFree pushes used this month
push:rNode.js SDKhonkio.push.usage()Requires push:r.
Responses
200This month's free allotment and use.
Field Type Description monthrequiredstring The calendar month, Toronto time: YYYY-MM.
free_monthlyrequiredinteger Free live deliveries each month.
free_usedrequiredinteger Free live deliveries used this month. Always 0 for a test key: test sends are free and never count.
- 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.push.usage()
if (error) throw new Error(error.message)
console.log(data)curl https://api.honkio.ca/v1/push/usage \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/{id}Get a push by id
push:rNode.js SDKhonkio.push.get()Requires push:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200Default Response
Field Type Description idstring statusstring scheduled, queued, sending, sent, failed, fell_back or cancelled. scheduled: accepted with scheduled_at and waiting for it; cancelled: a scheduled push cancelled before it went out, its charge refunded.
scheduled_atstring When a scheduled push is (or was) due to go out. Null on a push sent at once.
- Format: date-time
- Can be null
expires_atstring The expires_at a scheduled push was given: the latest it may go out. Null when none was given, which means scheduled_at plus 24 hours.
- Format: date-time
- Can be null
livemodeboolean device_countinteger Devices targeted at intake.
collapse_keystring Sent as APNs apns-collapse-id and FCM android.collapse_key: a newer push with the same key replaces an older one not yet shown. Null when none was given.
- Can be null
free_countinteger Deliveries covered by the monthly free allotment, net of refunds.
charge_millicentsinteger What the push cost, exactly, in CAD millicents (1/1000 of a cent): accepted billed deliveries times the price, net of refunds for rejected ones.
cost_centsinteger Whole cents this push debited from the balance, often 0 because prepaid credit is spent first. Approximate once rejected deliveries are refunded (the refund returns millicents to a pool shared with email); charge_millicents is the exact figure.
- 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.
- 4XXDefault Response
Example
const { data: push, error } = await honkio.push.get('PUSH_ID')
if (error) throw new Error(error.message)
for (const delivery of push.deliveries ?? []) console.log(delivery.device_id, delivery.status, delivery.error_code)curl https://api.honkio.ca/v1/push/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/push/{id}Reschedule a scheduled push
push:mNode.js SDKhonkio.push.update()Only while the push is scheduled (otherwise 422 PUSH_NOT_SCHEDULED). The charge is unchanged. The push counts against the daily limit of its new day: 429 PUSH_DAILY_CAP when that day is full. Sends push.rescheduled.
Requires push:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Request body
The new send time of a scheduled push.
| Field | Type | Description |
|---|---|---|
scheduled_atrequired | string | An ISO 8601 date-time with an offset, 1 minute to 30 days ahead.
|
expires_at | string | The latest it may go out: 1 minute to 24 hours after the new scheduled_at, or null for scheduled_at plus 24 hours. Left out, the stored expires_at is kept if it still fits the new scheduled_at, and dropped (back to the 24 hour default) if it does not.
|
Responses
200The push's new send time.
Field Type Description idrequiredstring statusrequiredstring - One of: scheduled
scheduled_atrequiredstring - Format: date-time
expires_atrequiredstring The expires_at now stored, or null for scheduled_at plus 24 hours.
- Format: date-time
- 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.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND (details.resource "push"): no push with that id in the calling key's mode.The standard error body.
- 422PUSH_NOT_SCHEDULED (only a scheduled push can be moved; details.current_status says what it is now) or VALIDATION_ERROR (scheduled_at must be 1 minute to 30 days ahead; expires_at 1 minute to 24 hours after it).The standard error body.
- 429PUSH_DAILY_CAP: the day the push would move to is already at the daily push limit. The details show the limit and when it resets.The standard error body.
- 500Unexpected server error.The standard error body.
- 4XXDefault Response
Example
const { data, error } = await honkio.push.update('PUSH_ID', { scheduledAt: '2026-10-01T14:00:00Z' })
if (error) throw new Error(error.message)
console.log(data.scheduled_at, data.expires_at) // expires_at: null means scheduled_at plus 24 hourscurl -X PATCH https://api.honkio.ca/v1/push/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"scheduled_at": "2026-10-01T14:00:00Z"
}'/v1/push/{id}Cancel a scheduled push
push:dNode.js SDKhonkio.push.cancel()Only while the push is scheduled (otherwise 422 PUSH_NOT_SCHEDULED). What it reserved is given back (the charge refunded, free deliveries returned to the month) and push.cancelled is sent. Cannot be undone.
Requires push:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 204Cancelled: the charge refunded and free deliveries returned to the month.
- 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 (details.resource "push"): no push with that id in the calling key's mode.The standard error body.
- 422PUSH_NOT_SCHEDULED: only a scheduled push can be cancelled; details.current_status says what it is now.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.
- 4XXDefault Response
Example
const { error } = await honkio.push.cancel('PUSH_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/push/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"
HonkIO