Outbound · Implemented by the POS

Webhook Spec

This document describes the outbound contract that BipBip uses to deliver new orders to the POS. It is the endpoint that the POS system must implement and expose so that BipBip can call it.

This is the counterpart of the REST API

BipBip → POS = webhook (this page). POS → BipBip = REST API. The integration guide explains how they fit together.

Transport contract

Closed transport contract — these parameters are fixed and not negotiated per merchant.

ParameterValue
Creation pathPOST {baseUrl}/v1/order/{remoteId}
Updates pathPUT {baseUrl}/v1/order/{remoteId}/{remoteOrderId}/events
Events on that pathcancelled, driver_assigned, driver_released, delivered — discriminated by body.event
VersioningIn the path (/v1/) — future versions can run in parallel
BodyJSON — schemas Order and OrderUpdateEvent
Timeout15 seconds per attempt
ACK (creation)HTTP 200 with { remoteOrderId } — required
ACK (status update)HTTP 200 — body ignored
Forward compatUnknown statuses and extra top-level fields must be tolerated → 200 OK and ignore

Signed headers

BipBip signs every request with HMAC-SHA256 over {timestamp}.{rawBody}using the shared secret from onboarding. The HMAC verification guide documents the full algorithm and code samples.

HeaderDescription
X-Bipbip-Signature-256HMAC-SHA256 in the format sha256=<hex> (lowercase)
X-Bipbip-TimestampUnix epoch in seconds. Rejected if it exceeds 300s (5 min) of skew.
X-Bipbip-Event-Typeorder.created on the creation webhook and menu.change.completed.v1 on the menu one. The spec does not declare it on the updates endpoint: there, discrimination is by body.event.
X-Bipbip-Schema-VersionPayload schema version. Currently 1.0. BipBip only bumps it on incompatible changes; adding new status values or other fields is additive and does not change the version.
X-Bipbip-Delivery-IdUnique UUID per dispatch. Use it for deduplication.

Authentication strategies

Beyond the HMAC signature —which always travels—, each webhook endpoint can configure one of three strategies in the Merchant Portal for an additional auth header. The strategy only controls whether that extra header is added; it never replaces the signature.

StrategyWhat it adds
hmac_only defaultHMAC-SHA256 signature only (X-Bipbip-Signature-256 + X-Bipbip-Timestamp). No Authorization header is sent.
static_headersAdds arbitrary HTTP headers (e.g. X-Api-Key, Authorization: Bearer <static-token>). Sensitive values are encrypted with AWS KMS and decrypted at dispatch time. Supports a 24h dual-window rotation.
oauth_client_credentialsBipBip obtains a Bearer token via OAuth 2.0 Client Credentials and injects Authorization: Bearer <token>. The token is cached (60s buffer before expiry); on a 401 from the merchant, BipBip invalidates the cache and retries once with a fresh token. Supports client_secret_post and client_secret_basic, scopes and extra params. 24h dual-window rotation for the client_secret.

The HMAC signature is ALWAYS present — regardless of strategy

All three strategies include the HMAC signature in X-Bipbip-Signature-256. The strategy only decides whether an additional auth header is added — it does not replace the signature.

Your POS must always validate the HMAC signature, whatever strategy is configured. There is no mTLS or custom basic-auth.


Retry policy

BipBip implements at-least-once delivery. Retries are re-enqueued without exponential backoff — the next attempt arrives within seconds, not minutes.

  • 5xx or network error → BipBip retries (up to maxRetries, default 3 total attempts, configurable per endpoint)
  • 4xx → terminal, BipBip does not retry
  • Timeout > 15s → treated as a failure and retried
  • HTTP 200 without remoteOrderId (creation only) → treated as a failure and retried
  • All retries carry the same X-Bipbip-Delivery-Id — deduplicate using that UUID

Creation retries exhausted

If every attempt of the order.created webhook fails, BipBip cancels the order internally (notifying the customer) and the order never reaches the POS.PUT /events calls that fail after every attempt are dropped — BipBip does not expose a separate failure event.

Endpoints

The POS must expose these two endpoints. The second is a single updates endpoint — the event type is discriminated by body.event(cancelled, driver_assigned, driver_released, delivered).

event is not the order status

event says what happened, not what state the order ended up in. Only cancelled and delivered have a counterpart in the resource state.

driver_assigned and driver_released belong to the driver cycle, which runs in parallel with the merchant's progress and does not modify it. An order can receive a driver_assigned while in preparing and stay in preparing.

What NOT to do: use event to overwrite the internal order status outside those two cases. The resource state is read with GET /api/v1/Orders/{orderKey} and never takes a driver value.

POST/v1/order/{remoteId}

Receive a new order

BipBip sends this webhook when an order is created. The POS verifies the HMAC signature, deduplicates with X-Bipbip-Delivery-Id, persists the order, and responds HTTP 200 with { remoteOrderId } in the body. The remoteOrderId value is required — BipBip uses it to compose the URL of subsequent updates.

Path parameters

remoteIdstringrequired
Store identifier in the POS (configured during onboarding). BipBip includes it in the URL so the POS can route to the correct branch.

Headers (signed by BipBip)

X-Bipbip-Signature-256stringrequired
HMAC-SHA256 over {timestamp}.{rawBody}, formatted as sha256=<hex>.
X-Bipbip-Timestampintegerrequired
Unix epoch in seconds. Reject if it exceeds 300s (5 min) of skew with the server's current time.
X-Bipbip-Event-Typestringrequired
Always order.created on this endpoint.
X-Bipbip-Delivery-IdUUIDrequired
Unique UUID per dispatch. Same value on all retries — use it for deduplication.

Body

(Order)Orderrequired
JSON payload with the full order data. Scroll down to the Order schema for the detail of each field.

Returns — 200 OK (required)

remoteOrderIdstringrequired
Internal POS ID for this order. BipBip persists it and uses it to compose the URL of subsequent PUT /events calls.
PUT/v1/order/{remoteId}/{remoteOrderId}/events

Order updates

Single endpoint for every update after creation. body.event discriminates between cancelled, driver_assigned, driver_released, and delivered. event says what happened, not the resource state: only cancelled and delivered modify it. driver_assigned can arrive more than once per order (driver reassignment). The POS MUST tolerate unknown values and respond 200 OK ignoring them. Only invoked if the creation webhook responded successfully.

Path parameters

remoteIdstringrequired
Store identifier in the POS.
remoteOrderIdstringrequired
Internal POS ID, returned in the response of the creation webhook.

Headers (signed by BipBip)

X-Bipbip-Signature-256stringrequired
HMAC-SHA256 over {timestamp}.{rawBody}.
X-Bipbip-Timestampintegerrequired
Unix epoch in seconds.
X-Bipbip-Schema-Versionstringrequired
Body schema version. Currently 1.0. Future versions bump it and may bring new top-level fields and new event values.
X-Bipbip-Delivery-IdUUIDrequired
Unique UUID per dispatch for deduplication.

This endpoint does not declare X-Bipbip-Event-Type

The spec lists only the four headers above. Route on body.event and do not make the handler depend on X-Bipbip-Event-Type being present here.

Body — discriminated by event

(OrderUpdateEvent)OrderUpdateEventrequired
Unified envelope with discriminator event. Four variants: cancelled (carries reason; modifies the status), driver_assigned (carries driver; can repeat; does not modify the status), driver_released (carries releasedDriver, reason, expectedNext; informational, does not modify the status), delivered (modifies the status).

Returns — 200 OK

(body)any
The response body is ignored by BipBip. Only the 200 status matters.

Lifecycle

Two parallel tracks

The status the merchant reports advances linearly. Driver assignment is not a step inside that cycle: it runs in parallel and does not modify it. BipBip starts looking for a driver while the order is still in preparing.

Order status (reported by the merchant)

pendingacceptedpreparingreadyhanded_over

Driver cycle (events, not statuses)

driver_assigneddriver_released(informational, no rollback)driver_assigned(reassignment)delivered

Practical consequence: driver_assigned can arrive at any point beforehanded_over, even before you reportready. Do not assume a fixed order betweenready and driver_assigned.

driver_assigned can arrive more than once

A BipBip operator may reassign the driver before delivery — and the internal system can also rotate drivers automatically. Each reassignment fires a new driver_assigned with the updated driver data, same schema as the first one.

Do: always show the most recently received driver. Do NOT: idempotize by orderKey + event and discard the second event — that leaves you displaying a driver that is no longer correct. Deduplicate by X-Bipbip-Delivery-Id.

The internal origin of the assignment (Auto / Operator / Driver hub) does not travel in the webhook — the payload is identical for all three cases.

driver_released is informational — do NOT roll back state

When driver_released arrives, the order logically remains in driver_assigned — it does not roll back to ready or any earlier state.

Do: clear the displayed driver in the POS UI and wait for the next driver_assigned with the new driver. The expectedNext field hints the next expected event (driver_reassignment).

delivered does not shield you from a later cancelled

The cancelled event can arrive even after delivered: a refund or an incident reverses an order that was already delivered.

Do NOT: treat delivery as a final state that blocks a later cancellation. Charge reconciliation depends on that cancellation.

Updates are tied to creation success

If the creation webhook (order.created) never reached the POS with HTTP 200, BipBip does not send any subsequent PUT /events for that order.

Forward compatibility — REQUIRED

BipBip may add new values to event and extra top-level fieldswithout bumping the schema version. The POS MUST:

  • Gracefully ignore unrecognized event values → respond 200 OK.
  • Do not treat unknown top-level fields as errors.

Menu-change webhook

A third endpoint, independent of the order lifecycle. BipBip calls it when it finishes applying a menu change, and it carries its own event type: X-Bipbip-Event-Type: menu.change.completed.v1.

POST/v1/menu/change/{changeKey}

Receive a menu-change confirmation

BipBip calls this endpoint once it finishes applying a menu change. Application is asynchronous and best-effort per store: status aggregates the overall result (applied, partial, failed) and results details each store+entity pair. It is a result notification with no side effect — if retries are exhausted, BipBip marks the delivery as failed internally but does NOT revert or cancel any change or order. The POS verifies the HMAC signature, deduplicates using X-Bipbip-Delivery-Id and responds 200 OK (body ignored).

When it fires

Applied via REST
When BipBip finishes applying a menu change the merchant requested through the inbound REST API (/api/v1/menu/...). The changeKey matches the changeId returned in the prior 202 Accepted.
Restaurant-initiated change
When the restaurant changes availability directly (not via the API), BipBip mints the changeKey automatically. The payload is identical in both cases. You can query the change status with GET /api/v1/menu/changes/{changeKey}.

Path parameters

changeKeystringrequired
Opaque change-request identifier. Format: chg_ followed by 16 base62 characters (e.g. chg_9mZ2kP7qR4tW1xYs). Matches the changeId from the prior 202 Accepted when the change was requested via REST.

Headers (signed by BipBip)

X-Bipbip-Signature-256stringrequired
HMAC-SHA256 over {timestamp}.{rawBody}, format sha256=<hex>.
X-Bipbip-Timestampintegerrequired
Unix epoch in seconds. Reject if it exceeds 300s (5 min) of skew.
X-Bipbip-Event-Typestringrequired
Always menu.change.completed.v1 on this endpoint. Use it to route to the matching handler.
X-Bipbip-Schema-Versionstringrequired
Payload schema version. Currently 1.0.
X-Bipbip-Delivery-IdUUIDrequired
Unique UUID per dispatch. Same value on all retries — use it for deduplication.

Body

(MenuChangeCompletedWebhook)MenuChangeCompletedWebhookrequired
Aggregate result of the change (status) plus the per-store detail (results). Jump to the MenuChangeCompletedWebhook schema for each field.

Returns — 200 OK

(body)any
The response body is ignored by BipBip. Retries on 5xx/network; 4xx is terminal.

Result notification, no side effect

Unlike order.created —whose total failure cancels the order—, if this webhook's retries are exhausted, BipBip marks the delivery as failed internally but does not revert or cancel any change or order.

Already-applied changes stay applied; you simply won't have received the confirmation. You can query the status with GET /api/v1/menu/changes/{changeKey}.

Per-store modifierOption overrides: persisted, but currently a customer-facing no-op

When the confirmed change includes a store-level price or name for a modifierOption, an applied: true result means BipBip persisted the override — but the BipBip app does not yet reflect it to the end customer.

The REST API flags these combos with pendingCustomerRollout: true in GET /api/v1/menu/capabilities.


Schema v1.0

Schemas

Definition of the JSON bodies BipBip sends and the expected ACK back. The headerX-Bipbip-Schema-Version: 1.0identifies this version. Additive changes (new status values or optional fields) do not bump it — existing integrators keep working as long as they tolerate unknown values.

Each schema declares required (required) and optional (optional) fields. Optional fields may be absent or take the value null as indicated in the description.

Order

The v1.0 payload BipBip sends to the POS when a new order is created (POST /v1/order/{remoteId}, X-Bipbip-Event-Type: order.created). Designed under the data-minimization principle: only the fields the POS needs to cook, invoice, and charge the order are included.

Identification

orderKeystringrequired
Opaque order identifier in BipBip. Format: ord_ followed by 16 base62 characters. Use it when invoking the BipBip REST API to accept, reject, or advance the order's status.
displayCodestringrequired
Human-friendly order code shown to the customer in the BipBip app. Useful for support cases ("my order 355156479…"). It is not unique across stores — combine with storeRemoteId if global uniqueness is required.
storeRemoteIdstringrequired
Store identifier. Same value configured in the BipBip BackOffice, mirrored in the URL path. Also included in the body as a defense against logs that truncate the URL.
currencystringrequired
ISO 4217 code (e.g. HNL).
createdAtISO-8601required
UTC timestamp of order creation in BipBip.
expiresAtISO-8601required
Acceptance deadline. If the order is not accepted before this timestamp, BipBip auto-cancels it and notifies the merchant via a cancellation webhook.

Fulfillment & customer

fulfillmentFulfillmentrequired
Fulfillment type and timing. Discriminator: type = delivery | pickup.
typeenumrequired
delivery (BipBip driver picks up and delivers) | pickup (customer comes to the store).
isExpressbooleanrequired
true if the customer paid for express delivery → prioritize in the kitchen. Always false on pickup.
prepareByISO-8601required
UTC timestamp when the order must be ready. The kitchen schedules against this value.
driverPickupAtISO-8601 | nulloptional
When the BipBip driver will arrive to pick up the order. Required when type=delivery; null on pickup.
customerPickupAtISO-8601 | nulloptional
When the customer will arrive at the store. Required when type=pickup; null on delivery.
customerCustomer | nulloptional
Customer information. Populated only on pickup orders so staff can call the customer to the counter. On delivery, null.
firstNamestringrequired
Customer's first name. Only field in v1.0 — data minimization. Last name and contact info are NOT exposed to the merchant.

Payment & totals

paymentPaymentrequired
Methods applied (combinable: cash + card + bips) and amount to collect at handover. The sum of methods[].amount equals summary.grandTotal.
methods[]PaymentMethod[]required
List of methods. Each one with type (cash | card | bips) and amount.
amountToCollectdecimalrequired
Amount the merchant must collect from the customer at handover (sum of methods[].amount where type requires handover collection).
changeFordecimal | nulloptional
If the customer will pay in cash and needs change, indicates the bill they will pay with (e.g. customer pays with 500, total 350 → changeFor: 500). null if not applicable.
summarySummaryrequired
Aggregated totals for fast reconciliation. Formula: grandTotal = subtotal + taxes − discounts + additionalCharges.
subtotaldecimalrequired
Sum of items[].lineTotal before taxes and discounts.
taxesdecimalrequired
Total taxes (sum of items[].tax).
discountsdecimalrequired
Sum of discounts[].amount applied to the order.
additionalChargesdecimalrequired
Sum of charges[].amount (delivery_fee, service_fee, etc.).
grandTotaldecimalrequired
Final amount the customer pays. Equals subtotal + taxes − discounts + additionalCharges.
charges[]Charge[]required
Itemized charges added to the customer's bill. Empty array if none apply. Each element is an object with the fields below.
codeenumrequired
Charge type. Values: delivery_fee, service_fee, driver_tip, others (closed enum).
amountdecimalrequired
Charge amount.
billedByenumrequired
Who bills it: bipbip | merchant. Determines who issues the fiscal document for this charge.
discounts[]Discount[]required
Discounts applied to the order. Empty array if there are no discounts. Each discount declares who absorbs the cost.
codestringrequired
Discount identifier (e.g. "PROMO15", "first_order").
amountdecimalrequired
Discount amount.
fundedByenumrequired
Who absorbs the cost: bipbip | merchant.

Order lines

items[]Item[]required
Order product lines. Each item includes price, tax, and modifiers. Minimum 1.
codestring | nulloptional
BipBip internal product code. null when there is no BipBip mapping.
remoteCodestring | nulloptional
Product code in the POS catalog. Fallback: use code if remoteCode is null.
namestringrequired
Product name as the customer sees it.
quantityintegerrequired
Quantity ordered.
unitPricedecimalrequired
Unit price before taxes and modifiers.
taxdecimalrequired
Tax applied to this line (not to unitPrice).
lineTotaldecimalrequired
Line total: (unitPrice × quantity) + modifiers + tax.
notestring | nulloptional
Free-form customer note for this line (e.g. "no onions").
modifierGroups[]ItemModifierGroup[]required
Modifier groups applied to the item. Empty array if no modifiers were chosen.

Notes & invoicing

customerNotestring | nulloptional
Free-form customer note for the entire order (e.g. "leave at the lobby with the guard, Apt 502"). Takes the value null if no note exists.
invoiceInvoice | nulloptional
Tax-credit data. null when the customer did not request it (predominant case: end consumer).
taxIdstringrequired
Customer's RTN (Honduran national tax ID).
businessNamestringrequired
Business name associated with the RTN to issue the tax credit.

Fulfillment

Fulfillment type and timing. The type field discriminates the variant: delivery (BipBip driver picks up and delivers) or pickup (customer comes to the store). Each variant populates only one of the two pickup timestamps.

Fields

typeenumrequired
Fulfillment discriminator. delivery: BipBip driver picks up and delivers. pickup: customer comes to the store.
isExpressbooleanrequired
true if the customer paid for express delivery → prioritize in the kitchen. Always false on pickup.
prepareByISO-8601required
UTC timestamp when the order must be ready. The kitchen schedules against this value.
driverPickupAtISO-8601 | nulloptional
When the BipBip driver will arrive. Required when type=delivery; null on pickup.
customerPickupAtISO-8601 | nulloptional
When the customer will arrive at the store. Required when type=pickup; null on delivery.

Customer

Minimal customer information. Only firstName is included so the cashier can call the customer to the counter ("Order for Ana"). Last name, phone, and email are not included. Only present on pickup orders; on delivery, customer = null.

Fields

firstNamestringrequired
Customer's first name. Only field in v1.0 — data minimization.

Payment

Payment information. The customer can combine multiple methods on a single order (e.g. 30 in Bips + 200 by card + 277 in cash). Convention: cash is collected at handover; card and bips are pre-paid in the app.

Fields

methods[]PaymentMethod[]required
Methods applied (minimum 1). The sum of methods[].amount equals summary.grandTotal.
typeenumrequired
Payment instrument: cash (handover collection), card (pre-paid in the app), bips (pre-paid loyalty credits).
amountdecimalrequired
Amount paid with this method.
amountToCollectdecimalrequired
Amount the merchant must collect at handover. Equals the sum of methods[].amount where type=cash. 0.00 if completely pre-paid.
changeFordecimal | nulloptional
Bill the customer plans to pay with. Only included if there is a cash method. null if completely pre-paid.

Summary

Aggregated totals for fast reconciliation. Formula: grandTotal = subtotal + taxes − discounts + additionalCharges.

Fields

subtotaldecimalrequired
Sum of unitPrice × quantity of items before taxes. The merchant's revenue line.
taxesdecimalrequired
Sum of tax × quantity of items. Taxes to remit.
discountsdecimalrequired
Sum of discounts[].amount (positive value).
additionalChargesdecimalrequired
Sum of charges[].amount.
grandTotaldecimalrequired
Total the customer paid. Equals the sum of payment.methods[].amount.

Charge

Charge added to the customer's bill. code is a closed enum; new codes require a major schema bump with prior announcement.

Fields

codeenumrequired
Charge type. Closed enum. Values: delivery_fee, express_fee, service_fee, driver_tip, small_order_fee.
amountdecimalrequired
Charge amount (positive value).
billedByenumrequired
Charge recipient: bipbip (BipBip invoices it; not merchant revenue) | merchant (merchant revenue).

Discount

Discount applied to the order. In v1.0 (MVP) BipBip emits a single entry with code: "GENERIC" when there is a discount; future iterations will break out coupons, loyalty, etc.

Fields

codestringrequired
Identifier. In v1.0 BipBip emits a generic code=GENERIC. Future iterations will break out coupons, loyalty levels, etc.
namestringrequired
Discount visible label.
amountdecimalrequired
Discount amount (positive value).
fundedByenumrequired
Who absorbs the cost: bipbip (BipBip funds it; merchant receives full price) | merchant (merchant funds it; impacts revenue).

Invoice

Tax-credit data. Only present when the customer requested an invoice with their RTN and business name. When populated, both fields are required. null in the predominant case (end consumer).

Fields

taxIdstringrequired
Customer's RTN (Honduras). Required to issue the tax credit.
businessNamestringrequired
Customer's business name. Required to issue the tax credit.

Item

Product line. Each item carries the BipBip catalog code (code) and the merchant POS code (remoteCode) — the latter falls back to code if not configured.

Fields

codestringrequired
Product code in the BipBip catalog. Stable, opaque identifier. If the product was registered without a code in BipBip, it can be empty — treat that as a data-quality signal.
remoteCodestringrequired
Product code in the merchant POS catalog, as configured by the brand. If no proper remoteCode was configured, this field falls back to code (BipBip catalog).
namestringrequired
Product visible name.
quantityinteger ≥ 1required
Quantity ordered.
unitPricedecimalrequired
Unit price before taxes.
taxdecimalrequired
Tax amount per unit of the item.
lineTotaldecimalrequired
Line total: (unitPrice + tax) × quantity + modifiers. Provided for fast reconciliation; the POS can recompute it locally.
notestring | nulloptional
Free-form customer instruction for the item (e.g. "no onions, extra sauce"). null if no note exists.
modifierGroups[]ItemModifierGroup[]required
Modifier groups applied to the item. Empty array if no modifiers were selected.

ItemModifierGroup & ModifierOption

Modifiers applied to an item. Modifiers are grouped by type (e.g. "Extras", "Crust type", "Drink"). Each group carries at least one selected option.

ItemModifierGroup

codestringrequired
Modifier group code in the BipBip catalog.
namestringrequired
Group visible name (e.g. "Extras", "Crust type").
options[]ModifierOption[]required
Options selected within the group. Minimum 1.
codestringrequired
Option code in the BipBip catalog.
remoteCodestringrequired
Option code in the POS catalog. Falls back to code if no proper remoteCode was configured.
namestringrequired
Option visible name.
quantityinteger ≥ 1required
Number of units selected.
unitPricedecimalrequired
Option unit price. 0.00 when included in the base item (e.g. free upgrade).

OrderAck

POS response to the creation webhook. remoteOrderId is required: BipBip persists it and uses it to compose the URL of future updates. Responses without this field are considered failed and are retried.

Fields

remoteOrderIdstringrequired
Internal POS order identifier. BipBip stores it in integration_order.remote_order_id and uses it to compose the updates webhook URL (PUT /v1/order/{remoteId}/{remoteOrderId}/events). Responses without this field are retried.

OrderUpdateEvent

Unified envelope for every update of an order. event discriminates the event: cancelled, driver_assigned, driver_released, delivered. Event-specific fields (reason, driver, releasedDriver, expectedNext) appear only in the corresponding event.

event describes what happened, not the resource state

Driver events (driver_assigned, driver_released) do not modify the order status. Only cancelled and delivered have a counterpart in it.

Forward compatibility — REQUIRED

New events may be added without a schema bump. The POS MUST respond 200 OK and ignore unknown values of event, and tolerate unknown top-level fields.

Fields

orderKeystringrequired
Opaque BipBip order identifier (format ord_ + 16 base62 chars). Can be used when invoking the REST API.
remoteOrderIdstringrequired
Internal POS identifier, same value returned in the original OrderAck. Included for convenience; the path parameter is authoritative.
eventenumrequired
Discriminator. Current values: cancelled (carries reason; modifies the status), driver_assigned (carries driver; can repeat on reassignment; does not modify the status), driver_released (carries releasedDriver, reason, expectedNext; informational, no rollback, does not modify the status), delivered (modifies the status). New values may be added without a bump; on an unknown value, respond 200 OK and ignore.
occurredAtISO-8601required
UTC timestamp of when the update occurred.
reasonstring | nulloptional
Origin label of the update. Populated when event=cancelled (values: customer_requested, operator_action, acceptance_timeout, delivery_failed) or when event=driver_released (value: manual_release). New values may be added without a bump — treat informatively.
driverOrderEventDriveroptional
Identity of the assigned driver. Populated when event=driver_assigned; absent on others. Important: this event can arrive more than once per order — each arrival carries the updated driver and the POS must always show the most recent one.
fullNamestringrequired
Driver's full name as registered in BipBip.
phonestring | nulloptional
Phone number in international format. null if the driver has not registered one or marked it private.
releasedDriverOrderEventDriveroptional
Identity of the released driver. Populated only when event=driver_released; absent on others. Same type as driver (fullName required, phone optional).
fullNamestringrequired
Full name of the driver who was released.
phonestring | nulloptional
Phone of the released driver. null if private.
expectedNextstring | nulloptional
Hint for the next expected event. Populated only when event=driver_released. Current value: driver_reassignment (BipBip is rotating the driver; the next driver_assigned will carry the new one). New values may be added without a bump — treat informatively.

OrderEventDriver

Identity of a driver inside an OrderUpdateEvent. It is the type of driver (when event = driver_assigned) and also of releasedDriver (when event = driver_released). Absent on other events. Can be received more than once per order — each time with the data of the currently assigned driver.

Fields

fullNamestringrequired
Driver's full name as registered in BipBip.
phonestring | nulloptional
Phone in international format. null if the driver has not registered one or marked it private.

MenuChangeCompletedWebhook

v1.0 payload BipBip sends once it finishes applying a menu change (POST /v1/menu/change/{changeKey}, X-Bipbip-Event-Type: menu.change.completed.v1). Application is best-effort per store: results reports each store's individual result and status aggregates the total. Nullable fields (errorCode, errorMessage) are omitted from the JSON when their value is null.

Fields

changeKeystringrequired
Opaque change-request identifier. Format: chg_ + 16 base62 characters. Matches the path value and the changeId returned in the original request's 202 Accepted.
statusenumrequired
Aggregate result. applied (success across every store in the change request), partial (some applied and some failed — see results), failed (failed on every store).
submittedAtISO-8601required
UTC timestamp of when the merchant requested the change.
completedAtISO-8601required
UTC timestamp of when BipBip finished applying the change.
results[]MenuChangeResult[]required
Individual result for each attempted (store, entity) pair. One item per store-and-change combination in the change request.
storeRemoteIdstringrequired
Merchant store where the change was attempted.
targetEntitystringrequired
Menu entity affected. Values in use: product, modifierOption, localProduct.
targetCodestringrequired
Code of the affected entity in the catalog.
appliedbooleanrequired
true if the change applied successfully on this store; false if it failed.
errorCodestring | nulloptional
Stable error code when applied=false (e.g. STORE_OFFLINE, PRODUCT_NOT_FOUND). Omitted from the JSON on success.
errorMessagestring | nulloptional
Human-readable message describing the failure cause when applied=false. Omitted from the JSON on success.

MenuChangeResult

Result of applying a menu change to a specific store. errorCode and errorMessage are present only when applied = false; they are omitted from the JSON otherwise.

Fields

storeRemoteIdstringrequired
Identifier of the merchant store where the change was attempted. Matches the value configured in BipBip's BackOffice.
targetEntitystringrequired
Menu entity affected by the change. Values in use: product, modifierOption, localProduct.
targetCodestringrequired
Code of the affected entity in the catalog.
appliedbooleanrequired
true when the change applied successfully on this store; false when it failed (in which case errorCode and errorMessage are populated).
errorCodestring | nulloptional
Stable, machine-processable error code when applied = false (e.g. STORE_OFFLINE, PRODUCT_NOT_FOUND). Omitted from the JSON on success.
errorMessagestring | nulloptional
Human-readable error message describing the failure cause when applied = false. Omitted from the JSON on success.

MerchantErrorResponse

Suggested shape for the POS error response body. BipBip only considers the HTTP status to decide retries — the body is informative. Any JSON shape or an empty body is accepted; this schema aims for consistency across merchants.

Fields (all optional)

errorstringoptional
Short machine-processable code (e.g. invalid_payload, duplicate_delivery).
messagestringoptional
Human-readable message for debugging.
timestampISO-8601optional
Time the error was generated on the POS server.