Skip to main content
When a customer places an order on any connected channel, Fire spark POSTs the order to the HTTPS URLs you register in the dashboard. Your integration does not poll for new tickets.

How orders reach your kitchen

1

Customer places the order

Storefront or a channel closes the cart. Fire spark starts fulfillment and notifies any matching webhooks.
2

The order reaches a subscribed status

Subscribe to order.status.changed and pick the statuses you care about (injecting, preparing, and so on). Named events cover void, fulfill, refund, and reverse.
3

Create the kitchen ticket

For handoff to POS or RMS, include injecting in those statuses. The payload has the full order — create the ticket as sent.
4

Report the next status from your POS

Call Update order status with the next fulfillment status. Fire spark may send another webhook.
Kitchen handoff is order.status.changed with data.status injecting. There is no separate injection event. Create the ticket from the payload as sent.

Configure your endpoint

Register HTTPS URLs under Settings → Webhooks in the Fire spark dashboard (up to 10 per environment). Each environment has its own endpoints, and an order only notifies the endpoints of its environment. Choose Webhook or Callback.
  • Webhook — fire-and-forget after that node’s work is closed (persisted, settled, callbacks finished). A waiting node is WAITING before the POST. An automatic next node is notified before it is entered. A terminal is notified after the run is finalized. A failed callback does not send that node’s webhook. Pick one or more events. For order.status.changed you must also pick the statuses that should fire (injecting, paid, preparing, …).
  • Callback — Fire spark waits for your 2xx when a node that lists this endpoint is entered. Events do not apply. You can register the same URL once as each type.
Webhooks created before signing support only stored a one-way hash. Rotate (regenerate) the secret in the dashboard if you need HMAC verification.

Signature

When a secret is present, Fire spark sets:
<hex> is HMAC-SHA256 of the raw JSON body using the secret shown once at create/rotate time (whsec_…).

Event types

There is no order.created or order.updated event. Subscribe to the events that match how you run the kitchen:
A webhook subscribed to both order.status.changed (status voided) and order.voided receives two POSTs. Use type plus id to tell them apart. data.status is the status that triggered that POST.

Values you will receive

These are the closed sets. Everything else on data.order follows Get order.

type and headers

data.status, current_states, next_states

Always lowercase snake_case. Hyphens become underscores (awaiting-pickup-time → awaiting_pickup_time). data.status is always in current_states. next_states lists the upcoming happy-path statuses you can advance this order to from here — not the statuses just entered. Terminals (fulfilled, voided, refunded, reversed) are omitted; they still fire named events when entered. Use a value from next_states when you PATCH order status. These are not a fixed enum — they are the fulfillment statuses configured for the merchant. Default Fire spark paths use: The merchant can add other keys (same snake_case pattern: a-z, 0-9, underscores). Subscribe to the keys shown in Settings → Webhooks. Named events fire only for these keys: delivered does not fire order.fulfilled. Subscribe to order.status.changed and include delivered if you need that step.

data.order status fields

Delivery

Webhooks: one attempt per POST, 10 second timeout. Any 2xx counts as success. Fire spark does not retry automatically. Callbacks: first POST is immediate. After each failure, wait min(1000 × 2^failureCount, 30000) ms and retry while failureCount < retries (default 3 → 4 POSTs max). Each POST uses the endpoint timeout (default 5s, max 300s). Invalid JSON for a registered schema (today INJECTING) counts as a failure. If retries are exhausted, Fire spark enters VOIDED (unpaid) or REVERSED (paid) and does not wait for PATCH.

Webhook payload

Every delivery is the same envelope:

data object

data.status is this delivery’s trigger. current_states is the full picture right now — the trigger plus any other statuses still in progress (for example kitchen and delivery at the same time). next_states is what you can PATCH next from those current statuses. If two subscribed statuses are entered together, you get one POST per status, each with the same current_states and next_states. order.fulfillment_status is the latest fulfillment status on the order. order.status is the overall lifecycle (OPEN, CLOSED, …), not the webhook trigger.

Callback response (INJECTING)

When a fulfillment node mapped to INJECTING invokes a callback, a 2xx is not enough. Return JSON:
Both fields use the same id rules as other external ids (1–64 characters, a-zA-Z0-9_-). Fire spark stores them on order.metadata so they appear on Get order and later webhook payloads. A 2xx with a body that fails this schema counts as a failed attempt.

Kiosk pagers (metadata.pager)

When a kiosk channel uses pagers, the customer types the number of the pager they took before paying. Fire spark saves it on order.metadata.pager, so it comes with the INJECTING callback and later webhooks:
metadata.pager is null or missing when pagers are off, when the chosen payment method doesn’t use them, or when the customer skipped an optional pager. Print the number on the ticket so staff can find the customer.

Handling kitchen handoff

  1. Subscribe to order.status.changed and include injecting.
  2. Read data.status, data.order_id, scope ids, and the full data.order.
  3. Map fulfillment_id, store_id, channel_id, brand_id, and line id values to your POS catalog (same external ids as menu sync).
  4. Create the ticket using totals, customer, payment, and fulfillment fields as sent. Include order.metadata.pager.number when present.
  5. Return HTTP 2xx quickly.
  6. When the kitchen moves on, PATCH order status with the next fulfillment status.
Guard against duplicate tickets: the same order_id can be delivered more than once. Key on envelope id, or on order_id plus data.status.

Fetching an order manually

Call Get order with the external order_id when you need to reconcile. Requires the orders:read scope. Every webhook already includes the full order object, so this is optional.

Get order

Retrieve the full order by external id

Update order status

Report the next fulfillment status from your POS