Guides
Errors
The authentication and consent errors come back from several endpoints. This page is the one place to look them up. Each guide has the fuller explanation for its own context.
Error shapes
Three shapes exist, so check which one you got before reading the code:
- Token-endpoint errors are JSON with an
errorfield, for example{"error":"invalid_grant"}. They come from the token endpoint (org token, client admin token, payment ticket). - Partner endpoint errors (customers, OTP, consent) are plain JSON with an
errorMessagefield, not the token-endpoint shape. - Bare status codes, such as
401,403and429with noerrorfield.
Tokens
| Error | HTTP | Where | Meaning | Retry? |
|---|---|---|---|---|
| — | 401 | Any endpoint that needs a token | Missing, malformed or expired token or credentials. | Get a fresh org token and retry. |
| — | 401 | Register or link customer, OTP calls, consent resend | The token was valid but not your organization’s own org token, for example a client admin or customer token. | Use the org token. |
| — | 403 | Create contract, milestone and parties, and the other calls that need a client admin token | The bearer was not a CLIENT_ADMIN token. | Use the client admin token. |
unauthorized_client | 400 | Client admin token | Password login is not enabled on this client. | Ask Waffy to enable it for the client, then retry. |
invalid_grant | 400 / 401 | Client admin token | Wrong admin username or password, or the account is disabled or locked. | Yes, once corrected. |
invalid_grant | 400 | Client admin token | The client_id you signed in with belongs to another organization (“Client does not belong to this user’s organization”). | Use one of your own organization’s clients. |
Customers, consent and OTP
| Error | HTTP | Where | Meaning | Retry? |
|---|---|---|---|---|
consent_rejected | 400 | Payment ticket | The customer declined your organization. | Final for that call. A fresh consent link, OTP verification or checkout login reverses it, then a retry succeeds. |
invalid_grant | 400 | Payment ticket | The customer has no link to this client at all. | Register or link the customer first, then retry. |
errorMessage | 400 | Send or verify OTP | Wrong or expired code, a missing field, or an unrecognizable phone number. Nothing is created or consented on a failed verify. | Send a new OTP and try again. |
errorMessage | 400 | Resend consent link | The customer is not linked to your organization yet. | Register or link the customer first. |
errorMessage | 404 | Resend consent link | No Waffy account exists for this phone number. | Register the customer first. |
| — | 502 | Send or verify OTP, register or link customer | A downstream step failed: sending the OTP, creating the customer or recording consent. | Yes, it is transient. |
More in Customers & consent.
Rate limits
| HTTP | Where | Meaning | Retry? |
|---|---|---|---|
| 429 | Send OTP | Your organization’s hourly OTP limit was reached. | After the window resets, or ask Waffy to raise it for legitimate traffic. |
| 429 | Resend consent link | Your organization’s hourly consent-link limit was reached. It is a separate counter from the OTP limit, counted per client. | After the window resets, or ask Waffy to raise it. |
Both limits are set by Waffy, not self-service. The dashboard shows the current value for each client.
Known behavior
start payment urlreturns a bare500, not404, for a milestone id that does not exist. It does not mean your request is malformed.- The
customer-token-exchangegrant used to get a payment ticket is not enabled in every environment yet. Confirm with Waffy which environments have it before relying on it outside dev.
Legacy errors
Organizations still on the legacy
/oauth/token flow see invalid_client (wrong client id or password, 401), invalid_grant (wrong username or password, 401), unsupported_grant_type (400), invalid_scope (400) and 429 for too many token requests. Cache tokens on your server.