_tag you can switch on and a message meant for your logs:
_tag (and code where present), never on the message text — messages may change, tags won’t.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | The request is malformed or references invalid values | Fix the request; don’t retry unchanged |
401 | Missing, malformed, or unrecognized credential, or an inactive app | Check the Authorization header and key |
403 | Valid credential, but not allowed (see code below) | Adjust scopes or environment |
404 | The resource doesn’t exist or isn’t visible to your credential | Verify the id and that you’re connected |
409 | The request conflicts with current state | Resolve the conflict (e.g. the location is already connected) |
5xx | A problem on Maple’s side | Retry with exponential backoff |
4xx bodies are safe to surface to your own logs and dashboards. 5xx responses should be retried with backoff — the order decision and webhook replay endpoints are replay-safe, so retrying them is harmless.
Error tags
_tag | Status | Notes |
|---|---|---|
DeveloperApiBadRequest | 400 | Malformed request, or invalid values such as unknown event types. For menu publishing, the message lists every validation issue. |
DeveloperApiUnauthorized | 401 | The bearer credential is missing, malformed, expired, or belongs to an inactive app. |
DeveloperApiForbidden | 403 | Carries a code: insufficient_scope or wrong_environment. |
DeveloperApiNotFound | 404 | The resource doesn’t exist or your credential can’t see it. |
DeveloperApiConflict | 409 | The request conflicts with current state, e.g. connecting a location another app already holds. |
The 403 codes
A DeveloperApiForbidden always tells you why:
insufficient_scope— the credential is valid but lacks a scope the endpoint requires. CheckGET /v1/meagainst the scopes table.wrong_environment— you used a test credential against live data or vice versa. The credential’s prefix fixes its environment.
Handling errors well
- Switch on
_tag/code, log themessage. The tag is your control flow; the message is for humans debugging. - Don’t retry
4xxunchanged. They mean the request needs to change. The one nuance: a409may clear once the conflicting state is resolved. - Retry
5xxwith exponential backoff. Add jitter to avoid retry storms. - Treat write retries as safe. Order decisions and webhook replay are replay-safe, so a retry after a timeout won’t double-apply.