How an error looks
{ "status": "FAIL", "message": "INVALID_PARAMETERS", "userMessage": "Set the origins allowed to embed the widgets first: …" }
message is the code to test in your code. userMessage, when present, is a sentence you can show or log: it says
what to fix. A successful answer is always { "data": … }.
The common ones
| Answer | Meaning | What to do |
|---|---|---|
401 INVALID_TOKEN | Wrong key, or the key does not have the permission of this endpoint. | Check the key’s permissions in Developer → API keys. A permission cannot be added later: create a new key. |
400 INVALID_PARAMETERS | A field is wrong or missing, or a setting is missing (for example the widget settings). | Read userMessage. |
402 QUOTA_EXCEEDED | 100 emails today (UTC) and no credit top-up yet. | Top up once in Settings → Plan & billing. |
403 WIDGET_PERMISSION_DENIED | The widget session does not include this widget. | Create the session with that widget in permissions. |
404 | The resource does not exist, or it belongs to another restaurant or workspace. | Check the id and the tenant. |
Restaurants and guests
| Code | Meaning |
|---|---|
422 INVALID_TENANT | tenant is not 1 to 64 characters among letters, digits, . _ : -, starting with a letter or digit. |
404 TENANT_NOT_FOUND | No restaurant with that tenant yet (on a read; sends create it). |
409 TENANT_CONSENT_NOT_ENABLED | Consent per restaurant is not on: the widget settings were never saved. |
409 TENANT_CONTACT_EMAIL_TAKEN | This restaurant already has a guest with that address. |
409 TENANT_CONTACT_EMAIL_LOCKED | The guest’s address cannot be changed in the Contacts widget. |
422 INVALID_TENANT_CONTACT, 422 TENANT_CONTACT_INVALID_EMAIL | A guest’s email or phone is not valid. |
422 TENANT_CONTACT_ROLE_EMAIL | A generic mailbox (info@, noreply@, support@): not added to a restaurant’s list. |
422 TENANT_CONTACT_DISPOSABLE_EMAIL | A throwaway mailbox domain (such as mailinator.com): not added to a restaurant’s list. |
422 TENANT_CONTACT_PASTE_TOO_LARGE | Too many addresses pasted at once in the Contacts widget. |
422 TENANT_CONSENT_EVIDENCE_REQUIRED, 422 TENANT_CONSENT_NEEDS_EVIDENCE | A marketing consent sent without its evidence. See consent. |
Sending
| Code | Meaning |
|---|---|
422 SENDER_NOT_ALLOWED | from / fromAddress is not under a domain verified in your workspace (for example a @gmail.com address). |
422 SENDER_NOT_FOUND | No sender with that senderId. |
422 SENDER_DOMAIN_NOT_VERIFIED | The sender’s domain is not verified yet. |
422 SENDER_NOT_ON_DOMAIN | The new sender’s address is not under that domain. |
422 SENDER_PARAM_CONFLICT | More than one of senderId, from, fromAddress. |
422 INVALID_SENDER_ADDRESS, 422 INVALID_REPLY_TO | Not a valid email address. |
422 MARKETING_CONSENT_REQUIRED, 422 TENANT_SUBSCRIPTION_REQUIRED | A marketing email to a guest who has not agreed to receive marketing. Nothing is sent. |
422 TENANT_TEMPLATE_MISMATCH | The template is another restaurant’s personalized copy. |
422 INVALID_SEND_AT | sendAt without its UTC offset, in the past, or more than 90 days ahead. |
422 SEND_AT_NOT_ALLOWED | Sign-in, verification and one-time-code emails cannot be scheduled. |
409 SCHEDULED_SEND_NOT_CANCELLABLE | The scheduled email is already being sent or was sent. |
Templates, events and rules
| Code | Meaning |
|---|---|
422 INVALID_EVENT_DATE | A date-time in the event without its UTC offset (write 2026-11-20T20:30:00+01:00). |
422 INVALID_AUTOMATION_RULE | A rule is not valid; userMessage says which field. |
422 MASTER_LOOKS_PROMOTIONAL | On PUT /public/v1/widgets/settings: a template marked as a service email (utility) reads like a promotion, so it cannot be an automatic message. Change its text, or make it a marketing template. |
Marketing protections
| Code | Meaning |
|---|---|
422 TENANT_DAILY_CAP_REACHED | The restaurant reached its daily marketing limit. See protections. |
422 TENANT_LIST_QUALITY | More than 20% of a list of 20 or more addresses is not usable: the whole campaign is refused. |
422 NO_VALID_RECIPIENTS | No usable address is left. |
409 CAMPAIGN_NO_ELIGIBLE_RECIPIENTS | Nobody left has agreed to receive marketing. |
409 MARKETING_SEND_ON_HOLD | Marketing for this restaurant is paused after complaints or bounces. |
422 TENANT_FOOTER_REQUIRED | The email would lose its unsubscribe footer. |
Brand (tenant profile)
| Code | Meaning |
|---|---|
422 INVALID_TENANT_PROFILE, 422 INVALID_TENANT_URL | A link is not a public https URL, or a social link is on the wrong network. |
422 INVALID_BRAND_COLOR | Not a hex color, or too close to white. |
422 BRAND_FIELD_LOCKED | Your app locked this field; the restaurant cannot change it. |
Limits
| Limit | Value |
|---|---|
| Emails per day before the first top-up | 100 (UTC day), all emails included |
| Daily marketing limit of a new restaurant | grows with good results, see protections |
| Widget session | 60 minutes by default, from 5 to 720 (expiresInMinutes) |
allowedOrigins | up to 20, exact https origins (http only for localhost), no wildcards |
| Master templates | up to 50 |
tenant | up to 64 characters |
sendAt | up to 90 days ahead |
| Send history widget | the latest 100 emails |