# Errors > Every error the ONPAD API returns, what causes it, and how to fix it. > Source: https://onpad.in/docs/api/errors Every error has the same shape: ```json { "ok": false, "error": "message_rejected", "message": "This template requires exactly 2 parameter(s)." } ``` `error` is a stable code you can branch on. `message` is written for a human and may be reworded — do not match on it in code. ## How to treat each status | Code | Retry? | What it means | |---|---|---| | `400` | No | The request body is not valid JSON | | `401` | No | The key is wrong, revoked, or your plan has no API access | | `403` | No | The workspace is read-only | | `404` | No | No such message in this workspace | | `405` | No | Wrong HTTP method for this path | | `409` | No | The `Idempotency-Key` was used for a different request | | `422` | No | Something in the request is invalid. Fix it first | | `500` | **Yes** | Our side failed. Retry with the same `Idempotency-Key` | Only `500` is worth retrying. Everything else returns the same answer however many times you send it. --- ## 400 — invalid_json > Request body must be valid JSON. The body did not parse. Usually a trailing comma, a single-quoted string, or a form-encoded body sent without `Content-Type: application/json`. --- ## 401 — invalid_api_key > Provide a valid active API key. One of four things: 1. **No `Authorization` header**, or it is not in `Bearer ` form. 2. **The key is malformed.** Keys start with `wh_live_` followed by 32–80 characters of letters, digits, `_` or `-`. A truncated copy-paste fails here. 3. **The key was revoked**, or never existed. 4. **Your plan does not include API access.** This returns the same `401` on purpose — the API never reveals which workspaces or keys exist. Check the plan first if the key is definitely right. Call [`GET /status`](https://onpad.in/docs/api/status) to test a key on its own. --- ## 403 — workspace_read_only > Your trial has ended. This workspace is read-only. Choose a plan to resume sending and editing. Sending is paused because the workspace has no active plan. Reading still works; `GET /messages` and `GET /status` keep answering. Choose a plan in **Plans & billing**. Sending resumes immediately. --- ## 404 — message_not_found > Message not found. No message with that id exists **in this workspace**. A valid id belonging to another workspace also returns `404` rather than `403`. Check the id came from this workspace's key and was copied in full — it is a 36-character UUID. --- ## 405 — method_not_allowed > Method not allowed. `/messages` accepts `GET` and `POST` only. `PUT`, `PATCH` and `DELETE` are not supported — a queued message cannot be edited or cancelled through the API. --- ## 409 — duplicate idempotency key > This Idempotency-Key was already used for a different request. The key was used before, with a different body. Nothing was sent. Either make the key specific to this exact message, or stop changing the payload between retries — a timestamp inside the body is the usual culprit. See [Idempotency](https://onpad.in/docs/api/idempotency). --- ## 422 — message_rejected The request was understood but something in it is wrong. The `message` field names the problem exactly. ### Idempotency > Provide an Idempotency-Key header between 8 and 120 safe characters. The header is missing, too short, too long, or contains characters outside letters, digits, `.`, `_`, `:` and `-`. ### Recipient > Enter a valid recipient phone number with country code. After stripping separators, `to` must be 8 to 15 digits. The most common cause is a number without its country code — `9876543210` instead of `919876543210`. ### Message type > Message type must be text or template. `type` must be `"text"` or `"template"`. It defaults to `"template"` if omitted. ### Free text > Text body must be between 1 and 4096 characters. `text.body` is empty or too long. > The 24-hour customer service window is closed. Send an approved template instead. The recipient has not messaged you in the last 24 hours, so WhatsApp does not allow free text. This is Meta's rule. Send an approved template instead — it opens a fresh window when they reply. ### Template > Enter a valid approved template name. `template.name` is empty, longer than 512 characters, or contains anything other than lowercase letters, digits and underscores. > Enter a valid template language such as en_US. The language code is malformed. Use `en`, `en_US`, `hi`, `pt_BR` and similar. > This template is not approved or is unavailable in the selected language. Three possible causes, in order of likelihood: 1. The template exists but is **not approved** — check Templates. 2. The template is approved in a **different language** than the one requested. 3. The name is misspelled. > Media-header templates are not supported by this endpoint yet. The template has an image, video, document or location header. Use a campaign for these. ### Template parameters > Template parameters must be a list with at most 20 values. `template.parameters` must be a JSON array, not an object, and at most 20 entries. > Each template parameter must be text or a number. An entry was an object, an array or `null`. Convert it to a string first. > Template parameters cannot be empty or longer than 1024 characters. An entry was an empty string or too long. An empty variable is rejected by WhatsApp, so substitute a real value or use a template without that variable. > This template requires exactly N parameter(s). The count does not match the template's variables. ONPAD counts the distinct `{{n}}` placeholders in the approved body and expects exactly that many. ### Connection > Connect WhatsApp before syncing message templates. The workspace has no connected WhatsApp number. See [Connect WhatsApp](https://onpad.in/docs/connect-whatsapp). > The Meta access token has expired. Reconnect WhatsApp and try again. Meta's token is no longer valid. Reconnect from the setup page; no data is lost. --- ## 500 — internal_error > Message could not be queued. Something failed on our side and the message was **not** queued. **This is the one error to retry.** Use the same `Idempotency-Key`, so if the message did sneak through, the retry returns it instead of sending twice. If it keeps happening, send us the time and your key's prefix at [support@onpad.in](mailto:support@onpad.in) — every request is logged, so we can find it. --- ## Failures after a 202 A `202` means queued, not delivered. A message can still fail later, and that shows up as `status: "failed"` with a reason in `error` when you [look it up](https://onpad.in/docs/api/get-message). Common delivery failures: | Reason | Meaning | |---|---| | Invalid phone number | The number is not valid for WhatsApp | | Not on WhatsApp | The number exists but has no WhatsApp account | | Messaging limit reached | Meta's cap on new conversations in 24 hours | | Payment issue | Meta has no valid payment method on your WhatsApp Business Account | | Template paused or disabled | Meta paused the template, usually for poor quality | ONPAD retries up to 3 times with backoff for temporary failures. Permanent ones — an invalid number, an unapproved template — fail at once, since retrying cannot change the answer.