Inbound · You call it
REST API Reference
Your POS calls BipBip to accept, reject, advance the status, and query orders. This is the counterpart of the Webhook Spec: once BipBip delivers an order to you, use this API to manage its lifecycle.
Base URL
https://api.bipbip.com.
Paths carry the prefix /api/v1/ with versioning in the path.
Authentication
Every request must include the
X-Bipbip-Api-Key
header with the value provided by the BipBip team during onboarding. We do not use Bearer tokens or OAuth for this API.
To obtain your API Keys, reach out to the BipBip team at [email protected].
# Every call must include this header
curl -H "X-Bipbip-Api-Key: <your-api-key>" \
https://api.bipbip.com/api/v1/Orders/<orderKey> Protect your API Key
Case-sensitive paths
/Orders/
must use a capital O literally — /orders/ returns 404.
Use the exact casing of each path documented here.
Idempotency-Key
All mutations (/accept,
/reject,
/status)
require the Idempotency-Key header.
The value must be a unique UUID v4 per logical attempt.
- Same key + same body within 24h → BipBip returns the cached response without re-executing.
- Same key + different body → HTTP 409 Conflict.
- New key → request processed normally.
- Missing header on mutations → HTTP 422 Unprocessable Entity.
{
"type": "https://errors.bipbip.com/idempotency-conflict",
"title": "Idempotency conflict",
"detail": "Idempotency-Key reused with a different request body.",
"status": 409,
"traceId": "00-abc...",
"meta": null
} Rate limits
Limits are applied per API Key and are active on all endpoints. If exceeded, you receive HTTP 429 — implement exponential backoff with jitter in your client.
| Window | Limit | Strategy |
|---|---|---|
| Fixed window | 100 requests / min | Resets every 60s |
| Sliding window | 1,000 requests / hour | Evaluated continuously |
Errors
The API follows the RFC 7807 Problem Details format. All errors return a JSON body with the fields
type,
title,
detail,
status,
traceId and
meta.
For validation errors (422), meta
includes a field → message list map.
| Code | Meaning |
|---|---|
| 401 Unauthorized | Missing or invalid API Key |
| 404 Not Found | orderKey does not exist or does not belong to the authenticated client |
| 409 Conflict | Idempotency-Key reused with a different body, order in wrong state for the transition, or invalid transition |
| 422 Unprocessable Entity | Invalid data in the body or missing Idempotency-Key header. The meta.errors field details the problematic fields. |
| 429 Too Many Requests | Rate limit exceeded — implement exponential backoff with jitter |
| 5xx | Server error — retry with backoff |
Generic error (401, 404, 409, 429)
{
"type": "https://errors.bipbip.com/not-found",
"title": "Order not found",
"detail": "The order ord_xxx does not exist or does not belong to the authenticated client.",
"status": 404,
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"meta": null
} Validation error (422)
{
"type": "https://errors.bipbip.com/validation",
"title": "Validation failed",
"detail": "One or more validation errors occurred.",
"status": 422,
"traceId": "00-abc...",
"meta": {
"errors": {
"reasonCode": ["The ReasonCode field is required."]
}
}
} Orders
Manage the lifecycle of orders delivered to you by BipBip via webhook. Mutation endpoints
require X-Bipbip-Api-Key
and Idempotency-Key.
/api/v1/Orders/{orderKey}/accept Accept an order after responding HTTP 200 to the creation webhook. Transitions the order from pending to accepted, cancels the acceptance timeout job, and publishes the order.accepted_by_external_merchant.v1 event. Body: { remoteOrderId?, estimatedPrepTimeMinutes? }. Idempotent: same Idempotency-Key + same body → cached response. Returns 202.
Example Response
{
"message": "Order accepted",
"data": {
"orderKey": "ord_7h3nXpQa2KvLmN9F",
"status": "accepted",
"acceptedAt": "2026-04-11T15:44:12Z",
"remoteOrderId": "POS-2026-04-11-00142"
}
} /api/v1/Orders/{orderKey}/reject Reject an order you can't fulfill. Transitions the order from pending to rejected (terminal). Requires a reasonCode (int). Body: { reasonCode*, reason?, notes? }. Use standard codes like OUT_OF_STOCK, STORE_CLOSED, or TOO_BUSY. Publishes order.rejected_by_external_merchant.v1. Idempotent. Returns 202.
Example Response
{
"message": "Order rejected",
"data": {
"orderKey": "ord_7h3nXpQa2KvLmN9F",
"status": "rejected",
"rejectedAt": "2026-04-11T15:44:30Z",
"reason": "Producto agotado"
}
} /api/v1/Orders/{orderKey}/status Advance the state of an accepted order. Valid transitions: accepted → preparing → ready → handedOver. Also allows cancellation (→ cancelled). Body: { newStatus* (MerchantStatus: pending/accepted/rejected/preparing/ready/handedOver/cancelled/driverAssigned), estimatedReadyAt? }. Once Ready, BipBip dispatches to the driver automatically. Publishes order.status_changed_by_external_merchant.v1. Returns 202.
Example Response
{
"message": "Status updated",
"data": {
"orderKey": "ord_7h3nXpQa2KvLmN9F",
"status": "preparing",
"changedAt": "2026-04-11T15:47:00Z"
}
} /api/v1/Orders/{orderKey} Query the current state of an order by its orderKey. Returns the full order snapshot: current status, timestamps for each transition (receivedAt, acceptedAt?, rejectedAt?, preparingAt?, readyAt?, driverAssignedAt?, handedOverAt?, cancelledAt?) and complete change history. Only returns orders belonging to the authenticated client. Does not require Idempotency-Key (read-only). Returns 200.
Example Response
{
"message": "Ok",
"data": {
"orderKey": "ord_7h3nXpQa2KvLmN9F",
"storeId": 42,
"brandId": 7,
"status": "preparing",
"merchantStatusReason": null,
"remoteOrderId": "POS-2026-04-11-00142",
"receivedAt": "2026-04-11T15:42:00Z",
"acceptedAt": "2026-04-11T15:44:12Z",
"rejectedAt": null,
"preparingAt": "2026-04-11T15:47:00Z",
"readyAt": null,
"driverAssignedAt": null,
"handedOverAt": null,
"cancelledAt": null,
"history": [
{
"fromStatus": null,
"toStatus": "pending",
"changedAt": "2026-04-11T15:42:00Z",
"actorType": "system",
"actorId": null,
"reason": null
}
]
}
} /api/v1/Orders List orders for the authenticated client with opaque cursor pagination. Query params: Cursor?, PageSize? (max 100), Status?, FromDate?, ToDate?. Ordered by creation date descending. Pass nextCursor from the previous response to fetch the next page. Returns 200.
Example Response
{
"message": "Ok",
"data": {
"items": [
{
"orderKey": "ord_7h3nXpQa2KvLmN9F",
"storeId": 42,
"status": "preparing",
"receivedAt": "2026-04-11T15:42:00Z",
"acceptedAt": "2026-04-11T15:44:12Z",
"remoteOrderId": "POS-2026-04-11-00142"
}
],
"nextCursor": "eyJsYXN0SWQiOjE3fQ",
"hasMore": true
}
} State machine
pending →
accepted /
rejected,
accepted →
preparing,
preparing →
ready →
handedOver.
The driverAssigned state is set automatically by BipBip between ready and handedOver (the merchant does not transition to this state, only reads it).
See the glossary for details.
Note: status
values in the REST API are camelCase lowercase (e.g. handedOver, driverAssigned),
unlike webhooks which use PascalCase.