Errors
Every non-2xx response from every endpoint uses one JSON envelope — there are no special cases to parse:
The envelope
| Field | Type | Meaning |
|---|---|---|
code | string | Stable machine-readable error code. Branch on this, never on message text. |
message | string | Human-readable description. May change between releases. |
retryable | boolean | true when the caller may safely retry the same
request. Pair retries with the same idempotencyKey and
sends can never double-fire.
|
requestId | string | Server-assigned correlation ID. Quote it in support requests to trace the exact request. |
Error codes and HTTP status
| Code | HTTP | Retryable | What it means |
|---|---|---|---|
validation | 400 | No | The request body or parameters failed validation. The message lists each offending field as `path: problem`; fix the request before retrying. |
unauthenticated | 401 | No | Missing or invalid Authorization header. Check that the bearer token is your current API key. |
forbidden | 403 | No | The key is valid but does not own the resource (e.g. another tenant’s notification ID) or lacks the required role. |
not_found | 404 | No | No resource with that ID — or no route at all (unknown paths return the same envelope). |
conflict | 409 | No | The request conflicts with current state, e.g. reusing an idempotencyKey with a different body, or cancelling an already-terminal notification. |
gone | 410 | No | The resource existed but is permanently gone (expired/rotated). |
rate_limit | 429 | Yes | Too many requests. Back off and retry with the same idempotencyKey. |
internal_error | 500 | Varies | Unexpected server failure. Honor the retryable flag on the response; include the requestId when contacting support. |
not_implemented | 501 | No | The endpoint exists in the spec but is not enabled on this deployment. |
Retries and idempotency
POST /v1/notifications is idempotent on the request body's
idempotencyKey, scoped to your account. The safe retry loop
is: keep the key fixed, retry only when retryable is
true (or on a network failure where no response arrived), and
treat an HTTP 200 replay as "already sent" — the original
record comes back instead of a duplicate send.
When to contact support
Repeated internal_error responses, or any behavior that
contradicts this page, belongs in our inbox:
support@textycally.com. Include
the requestId and a timestamp; we log both ends of every
request.