_tag you can switch on, a message meant for your logs, and a feedback line saying where to report the error if it does not tell you what to change:
_tag (and code where present), never on the message text — messages may change, tags won’t.
Status codes
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.
If an error does not tell you what to change, or the API does something these docs say it should not, send feedback and cite the request’s x-request-id.
Error tags
DeveloperApiUnprocessable is a 422 carrying code, message, and optional details. DeveloperApiRateLimited is a 429 carrying retry_after in seconds and the matching Retry-After HTTP header.
Booking error codes
Booking mutation bodies reject unknown fields with400, including misspelled optional fields such as expectedVersion instead of expected_version. Idempotency keys must contain 1–255 characters.
400:invalid_slot_token,expired_slot_token,invalid_window,invalid_cursor,invalid_phone,location_required,invalid_blackout_dates; configuration schema failures include validation paths.409:stale_version(details.expected/actual),stale_blackout_dates,stale_configuration,idempotency_key_reused,overlapping_booking,slot_unavailable,hold_expired,hold_consumed,not_changeable,not_cancellable,illegal_transition(details.from_status),waitlist_closed,operation_in_progress(details.operation_id,details.retry_after,details.reason).422:bookings_not_enabled,party_size_out_of_bounds,outside_booking_window,large_party_inquiry_required,date_blocked,capability_unsupported,guest_contact_required,guest_messaging_unavailable,payment_instrument_required,configuration_missing,configuration_rejected,provider_rejected.
operation_in_progress, retry the original request with its original key. If details.reason is replay_window_expired, stop automatic retries and contact Maple with the operation ID. Never use a new key to work around an uncertain provider outcome. See Take bookings.
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.