Reference
Errors
Every error the API returns has an HTTP status and a stable code. General codes can come from any call; the others belong to one product.
General error codes
Every error is a flat JSON object: code, message (follows Accept-Language), messageEn, messageFr, statusCode, and an optional details field with more about what failed. A malformed request, such as a missing field or a value outside its documented bounds, returns 422 VALIDATION_ERROR with details naming the field. A request the framework itself rejects before your code runs, such as invalid JSON (400), a body over the size limit (413) or an unsupported content type (415), returns a Fastify FST_ERR_* code with an English-only message instead.
| HTTP | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 401 | API_KEY_REVOKED | This API key has been revoked. Use a different key. |
| 402 | INSUFFICIENT_BALANCE | Account balance too low |
| 402 | RENT_OWED | Rent is owed on a number released while suspended. Paid sends and number requests are refused until a top-up pays it |
| 402 | PAYMENT_REQUIRED | The account has not completed its first top-up. Live keys are blocked until then except a few account and pricing reads; test keys are unaffected. |
| 403 | FORBIDDEN | The API key lacks the permission this action needs, skip_consent_check was sent with a live key, the account is suspended or closed (see details.reason), or the id in the path belongs to another account |
| 403 | LIVE_KEY_REQUIRED | A test key was used for something only a live key can do. |
| 403 | PERMISSION_ESCALATION | A new or rotated key asked for permissions broader than the caller's own, without a password step-up. |
| 403 | KEY_FENCED | This key is restricted by its own allow or deny lists or by default-deny, so it cannot change those lists or the groups and contacts they include, change any key’s list settings, create keys, or rotate any key but itself. |
| 403 | ACCOUNT_NOT_VERIFIED | The account has not verified an owner phone number yet, required before a live send. |
| 403 | ACCOUNT_EMAIL_NOT_VERIFIED | The account has not verified its email address yet, required before creating or rotating an API key, live or test, or connecting an app in live mode. |
| 403 | BUSINESS_VERIFICATION_REQUIRED | Requests for more numbers, a higher sending volume, higher top-up limits and toll-free verification need a verified business. |
| 403 | SENDING_PAUSED | Live sending is paused on this account (details show when it resumes and why) |
| 404 | NOT_FOUND | No resource matches the given id. |
| 409 | DEAD_LETTER_ALREADY_REPLAYED | This event was already replayed, or a replay of it is in progress. Nothing was sent, and retrying won't help. |
| 409 | CONFLICT | A resource with that identifier already exists, or a key rotation failed because the key was already revoked, is a session key, or another request rotated it first |
| 409 | BUSINESS_VERIFICATION_NOT_EDITABLE | The business verification profile is in review, verified or revoked, so it cannot be changed or submitted. |
| 409 | TOPUP_CAP_REQUEST_PENDING | A top-up limit request is already pending. |
| 422 | VALIDATION_ERROR | Request body or query failed validation (see details) |
| 422 | IDEMPOTENCY_KEY_RESERVED | The Idempotency-Key starts with notify:, a prefix HonkIO reserves for its own sends. Use a key with a different prefix. |
| 422 | SIGNUP_CHALLENGE_REQUIRED | Signup needs a solved, unused signup challenge from GET /v1/accounts/signup-challenge, sent as altcha (details.reason: missing, invalid or reused) |
| 422 | WEBHOOK_LIMIT_REACHED | Reached the limit of 10 webhook endpoints per account. Delete one before registering another |
| 422 | TEMPLATE_CHANNEL_MISSING | A send named a template that has no part for its channel in any language. details.channel names the channel. A missing translation never causes it: the default language's part is used instead. |
| 422 | EMAIL_TEMPLATE_NOT_PUBLISHED | The template has no published version yet. Publish it before sending with it from a live key. A test key sends the draft and never gets this error. |
| 422 | EMAIL_TEMPLATE_VARIABLE_MISSING | A template variable has no value and no fallback. details.keys lists the missing ones. |
| 422 | EMAIL_RENDER_FAILED | The content could not be rendered: a variable uses syntax other than the plain double-brace form, or the text grew past its size limit once the variables were filled in. |
| 422 | TEMPLATE_LIMIT_REACHED | This account has reached the limit of 200 templates. Delete one to create another. |
| 422 | LIVE_MODE_REQUIRED | This action needs a live key. Toll-free verification, for one, exists in live mode only. |
| 429 | RATE_LIMITED | Too many requests. Slow down |
| 500 | INTERNAL_ERROR | An unexpected server error occurred. Retry |
| 502 | WEBHOOK_REPLAY_FAILED | The endpoint did not accept the replay. The event stays in the dead-letter queue |
| 503 | SERVICE_UNAVAILABLE | New registrations are temporarily disabled (POST /v1/accounts), or phone verification is temporarily unavailable (POST /v1/accounts/:id/phone-verification). Retry later |
Codes that belong to one product have their own sections below: SMS error codes and email error codes.
Getting 500 or 503 answers you can’t explain? status.honkio.ca shows live checks of the API and sending, and any incident we are working on.
SMS error codes
The codes below are specific to SMS, phone numbers, verification and CASL. Any call can also answer with the codes in the general section above, such as VALIDATION_ERROR, INSUFFICIENT_BALANCE and NOT_FOUND.
| HTTP | Code | Meaning |
|---|---|---|
| 403 | NUMBER_LIMIT_REACHED | Account has reached its phone number limit |
| 403 | PHONE_NUMBER_NOT_OWNED | The from number is not provisioned on this account. |
| 403 | ALLOW_LIST_BLOCKED | Recipient is not on the API key's ALLOW list |
| 403 | DENY_LIST_BLOCKED | Recipient is on the API key's DENY list |
| 403 | SEND_LIMIT_REQUEST_TOO_EARLY | Volume requests open once the account's probation period is over. |
| 403 | TOLL_FREE_NOT_VERIFIED | The toll-free number is not verified for SMS yet. Apply for verification, then send once it is approved. |
| 403 | BUSINESS_NUMBER_REQUIRED | Toll-free verification needs a CRA business number on your verified business profile. |
| 404 | VERIFICATION_NOT_FOUND | Verification ID not found or not owned by this account |
| 404 | CONTACT_NOT_FOUND | Contact not found |
| 404 | CONTACT_GROUP_NOT_FOUND | Contact group not found |
| 404 | CONTACT_GROUP_MEMBER_NOT_FOUND | That contact is not a member of this group |
| 404 | CONTACT_LIST_NOT_FOUND | Contact list not found |
| 404 | CONTACT_LIST_ENTRY_NOT_FOUND | Contact list entry not found |
| 409 | VERIFICATION_ALREADY_VERIFIED | This number has already been verified |
| 409 | PURCHASE_IN_PROGRESS | Another number purchase is in flight. Retry shortly |
| 409 | ALLOWANCE_REQUEST_PENDING | An allowance request is already awaiting review |
| 409 | PHONE_NUMBER_SUSPENDED | This number's monthly charge could not be collected. Top up to reactivate it. |
| 409 | CONSENT_REVOKED_BY_REVIEW | Consent not recorded: HonkIO revoked this recipient's consent after reviewing the upload it came from. It cannot be recorded again, by any route, unless HonkIO lifts the block. |
| 409 | SEND_LIMIT_REQUEST_PENDING | A volume request is already awaiting review. |
| 409 | NUMBER_IN_OPEN_VERIFICATION | The number already belongs to another open toll-free verification application. |
| 409 | COMPED_TOLL_FREE | Toll-free numbers aren't available on this account. |
| 409 | VERIFICATION_NOT_EDITABLE | The toll-free verification application cannot be changed or submitted in its current status. |
| 409 | IDEMPOTENCY_KEY_REUSED | The same Idempotency-Key was sent with a different to, from or body. |
| 409 | CONTACT_ALREADY_EXISTS | A contact with that phone number or email already exists |
| 409 | CONTACT_IN_USE | Remove the contact from its groups and lists before clearing its phone number |
| 409 | CONTACT_GROUP_ALREADY_EXISTS | A contact group with that name already exists |
| 409 | CONTACT_GROUP_MEMBER_EXISTS | Contact is already a member of this group |
| 409 | CONTACT_LIST_ALREADY_EXISTS | A contact list with that name already exists |
| 409 | CONTACT_LIST_ENTRY_EXISTS | This entry already exists in the list |
| 410 | VERIFICATION_EXPIRED | The verification code has expired |
| 422 | NON_CANADIAN_NUMBER | Not a valid Canadian E.164 number |
| 422 | UNDELIVERABLE_NUMBER | The number failed at the carrier three times running (for any customer); refused without charge for 90 days. |
| 422 | NOT_A_MOBILE_NUMBER | The destination is a landline or VoIP number. The carrier refuses it before sending; nothing is charged. |
| 422 | RESERVED_DESTINATION | The destination is in a reserved exchange (555-XXXX, N11, carrier test codes). Refused before anything is sent; nothing is charged. |
| 422 | MESSAGE_TOO_LONG | Body would exceed the carrier limit of 10 SMS segments (≈1,530 GSM-7 or 670 Unicode characters). Nothing is charged |
| 422 | MESSAGE_NOT_SCHEDULED | Only a SCHEDULED message can be moved or cancelled. details.current_status says what it is now |
| 422 | VERIFICATION_INVALID_CODE | Incorrect code. attempts_remaining shows how many tries are left |
| 422 | INVALID_ALLOWANCE_REQUEST | Requested allowance must exceed your current limit |
| 422 | LINK_SHORTENER_BLOCKED | Link shorteners are refused because carriers filter them. Use the full URL |
| 422 | BROADCAST_TOO_LARGE | Contact group too large for one broadcast (250 members by default). Split it and send in batches |
| 422 | CANNOT_ERASE_OWN_NUMBER | That number belongs to your account. Erasure is only for a subscriber's number |
| 422 | TOO_MANY_AREA_CODES | Search at most 25 area codes at a time |
| 422 | INVALID_PHONE_NUMBER | Not a valid E.164 phone number |
| 422 | CONTACT_LIST_ENTRY_INVALID | Each entry must specify exactly one of phone_number, contact_id or contact_group_id |
| 422 | CONTACT_HAS_NO_PHONE | The contact has no phone number, so it cannot join an SMS group or list |
| 422 | NOT_A_TOLL_FREE_NUMBER | The number is not one of your toll-free numbers, so it cannot be verified or send opt-in confirmations. |
| 429 | RECIPIENT_RATE_LIMITED | More than 30 messages to one recipient in an hour or 100 in a day; retry after the Retry-After header. |
| 429 | VERIFICATION_MAX_ATTEMPTS | Too many wrong attempts. This verification is locked |
| 429 | DAILY_LIMIT_REACHED | Daily sending limit reached (details show your limit and count). Request a higher volume once eligible |
| 429 | FANOUT_LIMIT_REACHED | This exact message already reached the maximum number of distinct recipients allowed in 24 hours |
| 429 | NUMBER_RATE_LIMITED | This sending number already has a full minute’s worth of message segments waiting for the carrier. Retry after the Retry-After delay |
| 429 | NUMBER_QUEUE_FULL | A broadcast would overfill a local sending number’s carrier queue (1,200 message segments; toll-free numbers have no such cap). Retry-After is set when waiting would make room; otherwise split the group or shorten the message |
| 429 | BROADCAST_LIMIT_REACHED | Broadcast limit reached for this account in the last 24 hours |
| 429 | SCHEDULED_LIMIT_REACHED | The account already holds 10,000 scheduled live messages or 1,000 scheduled test messages (details carry mode, limit, scheduled and requested). Nothing was scheduled or charged; cancel some, or wait for them to go out |
| 429 | OPT_IN_CONFIRMATION_LIMIT | Already 3 opt-in confirmations to this recipient in the last 24 hours. Try again later. |
| 451 | OPT_OUT_BLOCKED | Recipient has opted out, so the send is legally blocked |
| 451 | NO_CONSENT | No valid CASL consent on file |
| 451 | CONSENT_EXPIRED | Implied consent expired (CASL s. 10(10)) |
| 451 | DOUBLE_OPT_IN_REQUIRED | Toll-free send to a recipient who has not confirmed double opt-in. Send an opt-in confirmation and wait for their YES. |
| 501 | DNCL_COMING_SOON | The /v1/compliance/dncl endpoints are not in service. Texts are governed by CASL consent, not the DNCL, which covers telemarketing calls and faxes. |
| 501 | TOLLFREE_800_COMING_SOON | 1-800 numbers are not available yet. Choose another toll-free prefix or a local number. |
| 502 | CARRIER_ERROR | The carrier returned an error while sending. |
| 502 | PROVISIONING_FAILED | The carrier could not complete this number purchase. Nothing was charged. |
| 502 | NUMBER_SEARCH_FAILED | Number search is temporarily unavailable. |
| 502 | RELEASE_FAILED | The carrier did not accept the release. The number is still yours; retry shortly |
| 503 | CARRIER_UNAVAILABLE | The carrier could not be reached; nothing was sent or charged. Retry shortly. |
| 503 | CARRIER_THROTTLED | The carrier asked us to slow down and did not take the message. Nothing was charged; retry after the Retry-After delay with the same Idempotency-Key. As the error_code of a FAILED message, it means the carrier took the message and then dropped it from a full queue: that message is refunded, and resending it needs a new Idempotency-Key |
| 503 | CARRIER_TIMEOUT | The carrier did not answer in time, so the message may or may not have been sent. Its charge is held, and refunded once the carrier's records show it was not sent. Check the message status before sending again: a retry with the same Idempotency-Key returns the failed message instead of sending it again. |
Email error codes
Email calls can also answer with the codes in the general section above, such as VALIDATION_ERROR, INSUFFICIENT_BALANCE and NOT_FOUND.
| HTTP | Code | Meaning |
|---|---|---|
| 403 | EMAIL_DOMAIN_NOT_ALLOWED | The API key is restricted to certain sending domains, and this one isn't in its list. |
| 403 | TEST_KEY_REQUIRED | Only a test key can call this endpoint. |
| 404 | RECEIVED_EMAIL_NOT_FOUND | No received email with that id. |
| 409 | EMAIL_DOMAIN_ALREADY_EXISTS | The domain is already on this account. |
| 409 | EMAIL_DOMAIN_IN_USE | Another account holds this domain. details.retry_after says when an unverified claim lapses; a verified domain stays with its owner. |
| 409 | EMAIL_DOMAIN_HAS_INFLIGHT | The domain still has queued, scheduled or sending email. |
| 409 | EMAIL_IDEMPOTENCY_IN_PROGRESS | A request with this Idempotency-Key is still being processed. Retry the same key shortly rather than using a new one. |
| 409 | EMAIL_SUPPRESSION_NOT_REMOVABLE | The address unsubscribed or reported your email as spam. Only the recipient can reverse that, so it cannot be removed through the API. |
| 409 | EMAIL_TEMPLATE_ALIAS_TAKEN | Another template on this account already uses this alias. |
| 409 | EMAIL_TEMPLATE_IN_USE | A scheduled email uses this template. Cancel it, or wait until it's sent, then delete the template. |
| 409 | RECEIVING_REQUIRES_VERIFIED_DOMAIN | The domain must be verified for sending before receiving can be turned on. |
| 410 | ATTACHMENT_EXPIRED | The attachment or raw message is past its 40 day retention window. |
| 413 | EMAIL_ATTACHMENT_TOO_LARGE | Attachments exceed 25 MB. |
| 422 | EMAIL_INVALID_ADDRESS | An address is not a valid email address. |
| 422 | EMAIL_DOMAIN_NOT_VERIFIED | The from domain is not a verified sending domain on this account. |
| 422 | EMAIL_DOMAIN_INVALID | Not a valid domain name. |
| 422 | EMAIL_DOMAIN_LIMIT_REACHED | This account has reached its sending-domain limit (5 by default; failed domains do not count). Answered to adding a domain, or to verifying a failed domain that would take a slot back. Remove one or ask support to raise it. |
| 422 | EMAIL_TEST_ADDRESS_LIVE_KEY | A live key can't send to an address on test.honkio.ca; those addresses are for test keys only. |
| 422 | EMAIL_HEADER_INVALID | The from address or a header is malformed, or is one honkio sets itself. |
| 422 | EMAIL_ATTACHMENT_FETCH_FAILED | An attachment given by path could not be fetched. details.reason says why: blocked_address, http_status, timeout, too_large or network. |
| 422 | EMAIL_ATTACHMENT_TYPE_BLOCKED | The attachment is an executable or script type (.exe, .js, .bat, .jar and the like) that receiving mail servers reject. details.filename names it. Nothing is charged. |
| 422 | EMAIL_BATCH_TOO_LARGE | Too many recipients in one call. |
| 422 | EMAIL_COMMERCIAL_MULTI_RECIPIENT | A commercial email goes to exactly one recipient. Use a batch to reach several. |
| 422 | EMAIL_NOT_SCHEDULED | Only a scheduled email can be moved or cancelled. |
| 422 | EMAIL_TEMPLATE_UNDECLARED_VARIABLE | The template body uses a variable it doesn't declare. Add it to variables; details.keys lists them. |
| 422 | EMAIL_TEMPLATE_LIMIT_REACHED | This account has reached the limit of 200 templates, counting those made through /v1/templates. Delete one to create another. |
| 422 | SIMULATE_RECIPIENT_NOT_OWNED | Every simulated recipient must be your test address or a domain this account owns in test mode. |
| 422 | INBOUND_ADDRESS_DISABLED | Your managed inbound address is switched off. Turn it on before sending to it. |
| 429 | EMAIL_DAILY_LIMIT_REACHED | A new account's live email reached its limit of recipients for the last 24 hours. The details show the limit and when it lifts. |
| 429 | TEST_EMAIL_QUOTA_EXCEEDED | A test key has created 200 emails, or simulated 200 received emails, in the last 24 hours. Live keys are not affected. |
| 451 | EMAIL_SUPPRESSED | The recipient is on your suppression list. |
| 451 | EMAIL_NO_CONSENT | Commercial email needs CASL consent on file for the recipient. |
| 451 | EMAIL_OPT_OUT_BLOCKED | The recipient unsubscribed from this sender. |
| 503 | EMAIL_ATTACHMENTS_UNCONFIGURED | Attachment storage isn't configured, so emails with attachments can't be sent right now. |
Delivery failure codes
These never come back as an HTTP response: the call already answered 201 before SES tried to send. If delivery still fails, one of these appears as failure_code on the email.failed or email.rejected webhook, and the charge is refunded. A scheduled email is checked again when it comes due: if the account has been suspended or closed by then, or no longer holds the verified from domain, the email fails with ACCOUNT_SUSPENDED, ACCOUNT_CLOSED or EMAIL_DOMAIN_NOT_VERIFIED and is refunded the same way.
| Code | Meaning |
|---|---|
| SES_THROTTLING | SES throttled the send; the email failed and was refunded; send it again. |
| SES_MESSAGE_REJECTED | SES rejected the message outright, for example malformed content; the email failed and was refunded; fix the content and send it again. |
| SES_DOMAIN_NOT_VERIFIED | SES had not finished verifying the from domain, even though honkio's own check passed; the email failed and was refunded; wait for verification to finish, then send it again. |
| SES_ERROR | An SES error that doesn't fit the other codes; the email failed and was refunded; send it again. |
| EMAIL_ATTACHMENTS_UNAVAILABLE | The stored attachment bytes could not be read at send time; the email failed and was refunded; send it again. |
HonkIO Auth codes
Codes from the HonkIO Auth management API (/v1/auth-apps). It also returns the general codes.
| HTTP | Code | Meaning |
|---|---|---|
| 409 | AUTH_APP_HOSTNAME_TAKEN | Another app already holds this hostname. |
| 422 | AUTH_APP_HOSTNAME_INVALID | The hostname can’t be a sign-in page: use a subdomain you own, not an apex domain or a HonkIO domain. |
| 422 | AUTH_APP_REDIRECT_INVALID | A redirect URI isn’t valid: HTTPS, exact, no wildcard, fragment or credentials; localhost on test apps only. |
| 422 | AUTH_APP_NAME_INVALID | The app name or brand colour isn’t valid. |
| 422 | AUTH_APP_NAME_PROTECTED | The app name is too close to a protected brand. |
| 422 | AUTH_APP_PUBLIC_CLIENT | The app is a public client and has no secret to rotate. |
| 422 | AUTH_APP_FREE_LIMIT | The account already has a live Free app. Move that one to a paid plan, or make this one a test app. |
| 422 | AUTH_APP_LIMIT | The account has as many apps in this mode as it can: 10 test apps, 25 live apps. Delete one you no longer use. |
| 422 | AUTH_APP_HOSTNAME_LIMIT | The hostname needs a certificate, and the account’s apps already hold as many as they can at once: 3 for test apps, 25 for live apps. Delete an app you no longer use. |
| 503 | AUTH_APP_DOMAIN_UNAVAILABLE | Domain and certificate setup is briefly unavailable. Retry shortly. |
| 422 | AUTH_APP_PLAN_FEATURE | The app’s plan doesn’t include that sign-in method. Change the plan first. |
| 422 | AUTH_APP_METHODS_INVALID | The method settings aren’t valid: keep at least one method on, and on a live app, pick a number to send from before turning on text sign-in. |
| 422 | AUTH_APP_NUMBER_INVALID | That number can’t send sign-in texts. Use an active, SMS-capable number on this account. |
| 422 | AUTH_APP_SEND_FROM_INVALID | Sign-in email can only come from a verified live email domain on this account that the key may use. |
| 422 | AUTH_APP_HOSTNAME_CHANGE_NEEDS_FALLBACK | Moving to this hostname would stop passkeys working, and passkeys are the app’s only sign-in method. Turn on email or text sign-in first. |
| 422 | AUTH_APP_LOGO_INVALID | The logo must be a PNG, JPEG, WebP or GIF of at least 16×16 pixels, in the multipart part named logo. SVG isn’t accepted. |
| 413 | AUTH_APP_LOGO_TOO_LARGE | The logo is larger than 1 MB. |
| 503 | AUTH_APP_LOGO_UNAVAILABLE | Logo upload is briefly unavailable. Retry shortly. |
| 403 | AUTH_SECURITY_FEATURE_UNAVAILABLE | That security setting needs a plan the app isn’t on. VoIP blocking starts on Pro. |
| 409 | AUTH_SECURITY_BLOCKLIST_DUPLICATE | The value is already on the app’s blocklist. |
| 422 | AUTH_SECURITY_BLOCKLIST_INVALID | The blocklist value doesn’t fit its kind. The details say which form it needs. |
| 422 | AUTH_SECURITY_BLOCKLIST_FULL | The app already has 1,000 blocklist entries. Remove some, or block a whole domain, prefix or range instead. |
| 403 | AUTH_SECURITY_TEXTS_PAUSED_BY_HONKIO | The app’s sign-in texts are paused by HonkIO. Only HonkIO can resume them; contact support. |
| 409 | AUTH_SECURITY_TEXTS_PAUSE_CHANGED | The app’s sign-in texts were paused again while they were being resumed. Check why they are paused, then retry. |
| 402 | AUTH_PLAN_INSUFFICIENT_BALANCE | The balance can’t cover the plan change and any unpaid sign-in charges. Top up, then retry. |
| 404 | AUTH_PLAN_NO_SCHEDULED_CHANGE | The app has no scheduled plan change to cancel. |
| 422 | AUTH_PLAN_DOWNGRADE_OVER_LIMIT | The app has more returning users than the Free plan includes (this billing cycle or the last), so it can’t move to Free. details.active_users and details.limit give the figures. |
| 403 | AUTH_ORG_PLAN_REQUIRED | Organizations, roles and organization invitations need the Business plan. |
| 403 | AUTH_ORG_TWO_STEP_PLAN_REQUIRED | The plan doesn’t include that two-step setting: two-step needs Pro, and requiring it per organization or role needs Business. |
| 409 | AUTH_ORG_SLUG_TAKEN | Another organization in the app already uses this slug. |
| 409 | AUTH_ORG_ROLE_IN_USE | A member or a pending invitation still holds the role. Change their role first. |
| 409 | AUTH_ORG_MEMBERSHIP_EXISTS | The user is already a member of the organization. |
| 422 | AUTH_ORG_NAME_INVALID | The organization name or slug isn’t valid: a plain name of up to 100 characters with no link in it (no web address, / or :), and a slug of lowercase letters, digits and dashes. |
| 422 | AUTH_ORG_ROLE_INVALID | The role isn’t valid here: use admin, member or a role made for the organization. Built-in roles can’t be deleted. |
| 422 | AUTH_ORG_SIGN_UP_DOMAINS_INVALID | Sign-up domains must be up to 50 domain names, and the domains mode needs at least one. |
| 409 | AUTH_INVITATION_NOT_PENDING | The invitation was already accepted, revoked or has expired. |
| 422 | AUTH_INVITATION_INVALID | An invitation needs exactly one valid email or mobile number, a role only with an organization, and a redirect_url on one of the app’s redirect origins. |
| 409 | AUTH_USER_IDENTIFIER_TAKEN | Another user of the app already has this email address or mobile number. |
| 422 | AUTH_USER_IDENTIFIER_REQUIRED | A user must keep an email address or a mobile number. |
| 422 | AUTH_USER_IDENTIFIER_INVALID | The email address or mobile number isn’t valid. Mobile numbers must be Canadian. |
| 403 | STEP_UP_REQUIRED | This action needs a fresh confirmation that it’s you: get a step-up token for the scope named in details.scope, then retry with it. Deleting users in bulk always needs one (auth_users:bulk_delete); an export needs one from a dashboard session. |
| 403 | AUTH_APP_STEP_UP_REQUIRED | Replacing the client secret, changing the hostname, changing a user’s email or phone, deleting a user or removing a user’s passkey from a dashboard session needs a fresh confirmation that it’s you. API keys don’t. |
| 403 | AUTH_EXPORT_STEP_UP_REQUIRED | An export needs an auth_users:export step-up token in the X-Step-Up-Token header. |
| 409 | AUTH_EXPORT_IN_PROGRESS | An export of the app is already being prepared. Wait for it to finish. |
| 409 | AUTH_EXPORT_NOT_READY | The export is still being prepared. Try the link again in a minute. |
| 410 | AUTH_EXPORT_LINK_INVALID | The download link expired or was already used. Start a new export. |
| 503 | AUTH_EXPORT_UNAVAILABLE | Exports are briefly unavailable. Retry later. |
Push error codes
Errors specific to push, besides the usual validation and authentication errors:
| HTTP | Code | Meaning |
|---|---|---|
| 403 | PUSH_DISABLED | Push is turned off for this account. Nothing was sent or charged; contact support. |
| 404 | PUSH_APP_NOT_FOUND | No push app with that id on this account, or the app was deleted. Sending with its app_id, registering a device to it and managing it all answer this. |
| 404 | PUSH_DEVICE_NOT_FOUND | No push device with that id in this key’s mode. |
| 409 | PUSH_IDEMPOTENCY_IN_PROGRESS | The same Idempotency-Key was replayed while the first call was still being accepted. Retry shortly with the same key. |
| 409 | PUSH_DEVICE_LIMIT | Registering a device: the app already has its maximum of active devices in this mode (1,000,000 live, 1,000 test). Unregister devices you no longer send to. |
| 409 | DPA_PUSH_ACCEPTANCE_REQUIRED | Creating a push app: the account accepted HonkIO’s data processing agreement before it covered push notifications. Accept the current version in Settings, Data processing agreement. An account that never accepted the agreement is not asked. |
| 422 | PUSH_NO_TARGET | Give exactly one of to.user_id and to.device_id. |
| 422 | PUSH_PAYLOAD_TOO_LARGE | The final payload is over 4096 bytes. details.bytes_over says by how much. Nothing is charged. |
| 422 | PUSH_NO_CREDENTIAL | The app has no credential for the platform of any targeted device, and there is no fallback. |
| 422 | PUSH_CREDENTIAL_INVALID | Adding or replacing a credential: Apple or Google rejected it, or it is not the kind of key they issue. details give the provider, the environment when known, and the reason. |
| 422 | PUSH_NOT_SCHEDULED | Only a scheduled push can be moved or cancelled. |
| 429 | PUSH_DAILY_CAP | The account reached its daily push limit. |
| 501 | PUSH_COMING_SOON | Push is not switched on for the platform yet. |
| 503 | PUSH_PROVIDER_UNAVAILABLE | Returned when you upload or replace a credential and Apple or Google could not be reached to check it. Retry shortly. |
Notify error codes
Refusals come back as the usual error body. These codes belong to Notify; the others are in the error reference.
| HTTP | Code | Meaning |
|---|---|---|
| 404 | RECIPIENT_NOT_FOUND | No profile with that user_id in the key's mode, and no active push device for it. |
| 409 | RECIPIENT_LIMIT_REACHED | The account already holds its maximum of profiles in this mode: 1,000,000 live, 1,000 test. details.limit gives it. |
| 422 | NOTIFY_SENDER_REQUIRED | A channel that can reach the person has no sender. details.channel names it. |
| 422 | NOTIFY_CONTENT_REQUIRED | Nothing to send: give text (and a subject to email), or a template. details.field names what is missing. |
| 422 | NOTIFY_CONTENT_TOO_LARGE | What the notification would send on the channels that can reach the person, rendered, is over 2 MB. details.bytes and details.limit give the sizes. |
| 501 | NOTIFY_COMING_SOON | Notify is not switched on for the platform yet. |
HonkIO