Webhook error codes (mpbx-webhooks)
Raised by the outbound webhook routes under /api/v1/webhooks (W7-API-02). Messages never contain
a signing secret, a signature or a receiver's answer; they name ids, field names and rules at most.
Guide: Outbound webhooks.
| Code | HTTP | Meaning | What to do |
|---|---|---|---|
MPBX-WEBHOOK-NOT-FOUND | 404 | No such endpoint in this company (another company's endpoint is invisible). | Check the id. |
MPBX-WEBHOOK-DELIVERY-NOT-FOUND | 404 | No such delivery in this company, or it was purged (delivered deliveries are kept 7 days, dead ones 30 days). | Check the id. |
MPBX-WEBHOOK-URL-INVALID | 400 | The URL is empty, longer than 2048 characters, not a URL, or has spaces, control characters or a fragment. | Send a plain https://host[:port]/path?query. |
MPBX-WEBHOOK-URL-BLOCKED | 400 | The URL is not allowed: not https, user info in the URL, a port below 1024 other than 443, a private, loopback, link-local (cloud metadata), carrier-grade NAT, documentation, multicast or reserved address (IPv4-mapped and NAT64 forms included), or an internal name (localhost, *.local, *.internal, a single label). The same check runs again on every delivery after name resolution. | Use a public https address. |
MPBX-WEBHOOK-EVENT-TYPE-UNKNOWN | 400 | An entry of event_types is not an event type or topic.* pattern you can subscribe to (audit.* and webhook.test never can), or it needs an event permission you do not hold company-wide (messaging:read for sms.*, call_history:read for cdr.written, ...; see "Who receives what" in the webhooks guide). Also when you change the URL of an endpoint whose filter names such events. | Use GET /api/v1/webhooks/event-types, which lists only what you may receive, or ask someone who holds the permission. |
MPBX-WEBHOOK-NAME-TAKEN | 409 | Another endpoint of the company has this name. | Choose another name. |
MPBX-WEBHOOK-FIELD-INVALID | 400 | A field is out of range: name (1 to 80 characters), rate_per_minute (1 to 6000), grace_period_seconds (0 to 604800), or more than 64 filter entries. | Fix the named field. |
MPBX-WEBHOOK-CHANGED | 409 | The endpoint changed between your read and your write. | Read it again and retry with the new ETag. |
MPBX-WEBHOOK-LIMIT-REACHED | 409 | The company already has 20 endpoints. | Delete one, or send more event types to one endpoint. |
MPBX-WEBHOOK-RATE-LIMITED | 429 | More than 10 test deliveries and redeliveries in a minute for the company. | Wait a minute (Retry-After: 60). |
MPBX-WEBHOOK-SECRET-UNREADABLE | 500 | The sealed signing secret of the endpoint cannot be opened (the master key was replaced without re-wrapping, or the row was damaged). Deliveries to it fail. | Rotate the secret (POST /webhooks/{id}/rotate-secret) and give the new one to the receiver. |
MPBX-WEBHOOK-NOT-REDELIVERABLE | 409 | The delivery is still pending (waiting for an attempt or a retry); only a delivered or dead delivery can be sent again. | Wait for it to finish, or look at its attempts. |
MPBX-WEBHOOK-LOG-UNAVAILABLE | 503 | The attempt log needs ClickHouse, which this install does not have, or a log row could not be read. Deliveries still work; only the history is missing. | Configure clickhouse.url. |
MPBX-WEBHOOK-ENDPOINT-DISABLED | 409 | A test was asked for an endpoint that is switched off. | Switch it on first (PATCH with enabled: true). |
Delivery error codes
A failed attempt stores a short machine code as the delivery's last_error (and in the attempt
log). It is never text from the receiver.
last_error | Meaning | Retried |
|---|---|---|
http_status | The receiver answered with a status outside 2xx (see last_status). A 3xx is a failure: redirects are never followed. Retry-After (seconds, at most one hour) lengthens the wait. | yes |
timeout | No answer within 10 seconds (connect within 5). | yes |
network | The connection or TLS handshake failed or broke. | yes |
dns | The host name did not resolve. | yes |
blocked | The destination resolved to an address that is not allowed (see MPBX-WEBHOOK-URL-BLOCKED). | no: dead at once |
too_large | The body is larger than 256 KiB. | no: dead at once |
rate_limit | Not a failure: the endpoint's rate_per_minute was used up, the delivery waits a few seconds (logged as deferred, no attempt counted). | n/a |