Beta: the Biskèt Partner API may still change before v1 is final. Sandbox access is by request:partners@bisket.ai.
Error catalogue
Errors are application/problem+json (RFC 9457) with a stable machine code. Codes may be added within v1; treat an unknown code by its HTTP status.
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_json | The body could not be parsed as JSON. |
| 400 | invalid_parameter | A path or query parameter is malformed (an id that is not a UUID, a limit out of 1–100, a bad cursor). |
| 400 | missing_idempotency_key | Every POST needs an `Idempotency-Key` header. |
| 401 | api_key_expired | The key passed its expiry date (keys live at most a year). |
| 401 | authentication_required | No `Authorization: Bearer …` header was sent. |
| 401 | invalid_api_key | The key is unknown or was revoked. The two cases answer the same on purpose. |
| 401 | wrong_environment | A `bk_test_` key was sent to the live host, or a `bk_live_` key to the sandbox. |
| 403 | grant_revoked | The restaurant disconnected your partner account. New orders are refused; existing orders and settlement continue. |
| 403 | grant_suspended | The connection to this location is suspended. |
| 403 | insufficient_scope | Your key, or the restaurant's grant, lacks the scope this operation needs. |
| 403 | partner_suspended | Biskèt suspended your partner account; every key is refused. |
| 404 | not_found | The object does not exist, or it is not visible to you (another partner's object, a location you are not connected to). |
| 405 | method_not_allowed | The path exists but not with this HTTP method; `Allow` lists the methods it takes. |
| 406 | not_acceptable | The `Accept` header excludes JSON. |
| 409 | cancellation_already_requested | A cancel request for this order is pending. |
| 409 | external_id_conflict | An order with this `external_id` exists with a different body. |
| 409 | idempotency_conflict | This `Idempotency-Key` was already used with a different request. |
| 409 | idempotency_in_progress | The first request with this key is still running. |
| 409 | invalid_state_transition | The order (or object) is not in a state that allows this action; `current_version` is included. |
| 409 | item_unavailable | A line is sold out, hidden from your channel, or off the menu; `errors[]` names it. |
| 409 | location_not_accepting_orders | The location is closed, paused or unreachable. |
| 409 | order_not_cancellable | The kitchen already started: a cancel is now a request the restaurant approves or rejects. |
| 409 | payment_already_open | A payment intent for this order is still open. |
| 409 | payment_not_required | The order is `collected_by: partner`, or already paid. |
| 409 | payout_not_cancellable | The restaurant already confirmed or disputed this payout. |
| 409 | pickup_manual_code_locked | Too many wrong manual codes for this order. |
| 409 | pickup_token_used | This order was already picked up with this token. |
| 409 | price_changed | A line's price no longer matches the menu; `current_menu_version` tells you which version to read. |
| 409 | redelivery_limit | This delivery was already redelivered the maximum number of times. |
| 409 | statement_not_issued | The statement is still open for its period. |
| 409 | webhook_endpoint_limit | You reached the maximum number of endpoints. |
| 412 | precondition_failed | Your `If-Match` names a version that is no longer current; `current_version` is included. |
| 413 | payload_too_large | The body is over 64 KiB. |
| 415 | unsupported_media_type | The body is not `application/json`. |
| 422 | amount_not_whole_gourdes | MonCash needs a whole number of gourdes. |
| 422 | collection_mode_not_allowed | This `collected_by` is not enabled for you, or the location cannot collect. |
| 422 | currency_not_supported | v1 exposes HTG only. |
| 422 | discount_exceeds_limit | The partner-funded discount exceeds your cap. |
| 422 | fulfillment_type_not_supported | The location or your account does not support this fulfillment type. |
| 422 | invalid_authorization_code | The Connect code is unknown, expired (10 min) or already used. |
| 422 | invalid_modifier_selection | A modifier group got too many, too few or unknown options. |
| 422 | payment_amount_mismatch | The payment amount is not subtotal + markup + delivery fee − discount. |
| 422 | payment_method_not_allowed | This payment method is not enabled for you. |
| 422 | pickup_token_expired | The token is older than its validity (8 h). |
| 422 | pickup_token_invalid | The scanned token is not a Biskèt pickup token (or was altered). |
| 422 | pickup_token_wrong_order | The token belongs to a different order. |
| 422 | pkce_verification_failed | The `code_verifier` does not match the `code_challenge` sent at the start of Connect. |
| 422 | redirect_uri_mismatch | The `redirect_uri` is not one Biskèt registered for you, byte for byte. |
| 422 | subtotal_mismatch | The `subtotal` is not the sum of the lines. |
| 422 | validation_failed | One or more fields are invalid; `errors[]` lists each with its JSON path and code. |
| 422 | variant_required | This item has sizes: a `variant_id` is required. |
| 422 | webhook_url_not_allowed | The URL is not https, or resolves to a private or reserved address. |
| 429 | rate_limited | You exceeded a rate limit; `Retry-After` says when to retry. |
| 500 | internal_error | A bug on Biskèt's side. |
| 502 | payment_provider_error | MonCash failed or did not answer. |
| 503 | service_unavailable | Maintenance, overload, or the database could not be reached. |