# Flow API errors, and how to fix each one

> SkedX Flow API errors return JSON with an "error" message (the messaging and hook requests also include "ok": false). By status: 400 — Flow’s own checks (to required; template_name required; variables must be a flat list; callback_data 512 characters or fewer) or WhatsApp’s refusal passed through (template not approved, wrong number of values, wrong language), and "reason": "window_closed" for free text outside the 24-hour window; 401 — "Valid API key required", or a hook’s proof is wrong; 402 — the messaging wallet is empty or its daily limit is reached; 403 — the key lacks the permission named, or "The Flow API is not enabled for this account yet"; 404 — the id isn’t in your workspace; 409 — no WhatsApp number connected; 413 — a hook body over 256 KB; 422 — the customer opted out, or a hook’s rule refused the call; 429 — OTP or hook limits. Retry only 429 and 5xx, waiting longer each time.

Product: SkedX Flow · Topic: APIs & Developers · Draft — steps not yet re-verified in the live product

When Flow refuses a request it says why in plain words, and a refused request sends nothing. Read the status first: only 429 and the 500s are worth retrying automatically. Everything else needs a change on your side, and the message says which.

## Step 1: 400 — something in the request

Flow’s own checks name the field: “to required”, “template_name required”, “variables must be a flat list of values” (1, 2), “callback_data must be 512 characters or fewer”. WhatsApp’s refusals come back as 400 too, in WhatsApp’s words — a template that isn’t approved, too few or too many values, a wrong language. `"reason": "window_closed"` means free text outside the 24-hour window: send a template.

## Step 2: 401 — the key, or a hook’s proof

“Valid API key required”: the key is missing, mistyped or revoked. Check the header reads exactly `Authorization: Bearer sk_flow_…`, with one space after `Bearer`; lost or revoked, [create a new key](https://skode.ai/help/flow/developers/create-an-api-key/). On an inbound hook, 401 means the caller’s secret, password or signature is wrong — the message says which ([how hooks check](https://skode.ai/help/flow/developers/secure-an-inbound-hook/)).

## Step 3: 402 — the wallet

“Your messaging wallet is empty — top it up to send.” Nothing was sent. The same answer comes when the workspace reaches its daily spending limit. Top up and sending works again at once. Have your system alert a person on `402`, so messages never stop without anyone noticing.
Open it directly: https://flow.skode.ai/settings/?tab=wallet

## Step 4: 403 — a permission, or a feature that’s off

The message names the permission the key lacks, such as `contacts:read` — create a key with that box ticked. “The Flow API is not enabled for this account yet” or “Inbound hooks are not enabled for this account yet” means the Developers tools are switched off for your workspace — message us. For one-time codes, `otp_disabled` means OTP is off in Settings.

## Step 5: 404 — not in your workspace

“Contact not found” or “Conversation not found”: the id doesn’t exist in the workspace the key belongs to. Use an id your own key listed. A hook address that was deleted answers `404` too.

## Step 6: 409 — no WhatsApp number to send from

The workspace has no connected WhatsApp number. Connect one in **Settings -> Channels**, or reconnect it if it shows as disconnected.
Open it directly: https://flow.skode.ai/settings/?tab=channels

## Step 7: 413 and 422 — too big, or not allowed

**413**: an inbound hook’s body was over 256 KB — send less. **422**: the customer opted out of your messages (“This contact has opted out of messages from you.”), or an inbound hook’s own rule refused the call. Don’t retry.

## Step 8: 429 — slow down

Only one-time codes and inbound hooks have limits of their own: an OTP limit (`rate_limited`), a hook’s 300 calls a minute, or the daily cap you set on a hook. Wait, then retry with a longer gap each time; if the traffic is real, raise the hook’s cap.

## Step 9: The 500s — our side

A `500`, `502` or `503` is a fault on our side or WhatsApp’s. Retry after a short wait, then longer. If it keeps happening, message us with the time and the request you sent.

## Common questions

### Which errors should my code retry?

Only `429` and the 500s — waiting a little longer each time (for example 5 s, 30 s, 2 min). Every other error will fail the same way again until something changes.

### Is anything charged when a request fails?

Flow’s own checks — a 401, 402, 403, 404 or 409, and the 400s that name a field — happen before anything is sent. For one-time codes, a code that can’t be delivered is refunded.

### The error text isn’t English I recognise.

A 400 that doesn’t look like Flow’s own messages is WhatsApp’s explanation, passed through as it came. The most common: a template name that isn’t approved on your number, or the wrong number of values.

## Useful links
- Flow API reference — every request’s possible answers: https://flow.skode.ai/docs/
- Wallet in Flow — for 402: https://flow.skode.ai/settings/?tab=wallet
- Channels in Flow — for 409: https://flow.skode.ai/settings/?tab=channels

Videos and screenshots © 2026 SkedX, with sample data only. Share and link to them freely; copying the SkedX product or its design is not allowed. Terms: https://skode.ai/terms/

## Related guides
- Create an API key: https://skode.ai/help/flow/developers/create-an-api-key/
- Send a WhatsApp template over the API: https://skode.ai/help/flow/developers/send-a-whatsapp-template-over-the-api/
- Secure an inbound hook: https://skode.ai/help/flow/developers/secure-an-inbound-hook/
- Send your first WhatsApp template in 5 minutes: https://skode.ai/help/flow/developers/send-your-first-template-in-5-minutes/
- Contacts and conversations over the API: https://skode.ai/help/flow/developers/contacts-and-conversations-api/
- Send and check one-time codes (OTP): https://skode.ai/help/flow/developers/send-and-check-one-time-codes/
- Move your WhatsApp API calls from Interakt to Flow: https://skode.ai/help/flow/developers/move-your-api-calls-from-interakt/
- Why WhatsApp held back some of your messages: https://skode.ai/help/flow/templates/why-whatsapp-held-back-some-messages/

Source: https://skode.ai/help/flow/developers/flow-api-errors/