Saltar para o conteúdo principal
POST
/
api
/
v1
/
webhooks
/
kds
/
order-status
Status do pedido KDS
curl --request POST \
  --url https://app.fire.rest/api/v1/webhooks/kds/order-status \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <x-api-key>' \
  --data '
{
  "eventType": "<string>",
  "providerEventId": "<string>",
  "occurredAt": "<string>",
  "orderId": "<string>",
  "eventId": "<string>",
  "stationName": "<string>",
  "metadata": {}
}
'
{
  "received": true,
  "duplicate": false,
  "eventId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "webhookEventId": "9e6c8af8-af80-4967-9422-c096ab43c0e7",
  "status": "queued",
  "firstReceivedAt": "2026-05-26T18:30:00.512Z",
  "message": "Event accepted and queued for processing."
}
Este endpoint é de entrada — seu Sistema de Tela de Cozinha (KDS) faz POST nele sempre que um pedido avança na cozinha: a cozinha começou a prepará-lo, ficou pronto para entrega, ou foi despachado (entregue / retirado). O Fire autentica a requisição, correlaciona com o pedido, aplica idempotência e um guard anti-regressão, e registra o evento no seu log de eventos KDS para observabilidade.
Este endpoint é assíncrono. O Fire autentica, roda o guard de source-of-truth + tenancy, deduplica e enfileira o evento — então responde 202 Accepted com um webhookEventId (tipicamente em menos de 100 ms). O evento é registrado um instante depois por um worker em segundo plano (normalmente em ~2 segundos). Para verificar o resultado, consulte GET /v1/webhooks/events/{webhookEventId}. Problemas corrigíveis pelo cliente (payload inválido, eventId errado, tenant errado) são rejeitados sincronamente com 4xx antes do 202.
Um evento de dispatch, vários reportes de status. Diferente do callback fiscal — onde cada ação carrega seu próprio eventId — o KDS reporta toda a jornada (preparingreadydispatched) contra um eventId: o que o Fire emitiu ao despachar o pedido ao seu device. São distinguidos por eventType, não por eventId. Veja Idempotência e a jornada.

Tipos de evento

O ciclo de vida do KDS tem uma ordem estrita — um pedido é preparado antes de ficar pronto, e fica pronto antes de ser despachado:
eventTypeSignificadoRank
order.preparingA cozinha começou a preparar o pedido1
order.readyO pedido está preparado e pronto para entrega / retirada2
order.dispatchedO pedido saiu da cozinha (entregue ou retirado) — terminal3
Os valores são minúsculos, com ponto (order.preparing, não ORDER_PREPARING).

Autenticação

Este endpoint requer uma API key vendor-scoped com o escopo webhooks:kds (binding de conta + vendor). O Fire valida que o pedido pertença a essa conta e vendor. Keys sem o escopo, ou sem binding de vendor, são rejeitadas com 403 Forbidden.
x-api-key
string
obrigatório
Sua API key vendor-scoped do Fire com escopo webhooks:kds. Gere uma em Developers → Gestão de API para a conta/vendor cujos pedidos esta key vai reportar.
Authorization
string
Bearer <token> opcional — aceito como alternativa legada ao x-api-key. Envie um ou outro.

Corpo da requisição

eventType
string
obrigatório
O evento de ciclo de vida do KDS. order.preparing, order.ready ou order.dispatched (minúsculo, com ponto).
providerEventId
string
obrigatório
O id próprio do seu KDS para esta entrega. Armazenado para auditoria/forense — não é a chave de idempotência. O Fire deduplica por (orderId, eventId, eventType), então você pode enviar um providerEventId novo a cada retentativa. Use o id de evento nativo do seu KDS se tiver; senão, um UUID.
occurredAt
string
obrigatório
Timestamp ISO 8601 UTC de quando o evento ocorreu no KDS — não quando foi enviado.
orderId
string
obrigatório
UUID do pedido no Fire. Corresponde a data.orderId nos eventos de pedido. O Fire correlaciona o evento com este pedido; ele deve existir previamente.
eventId
string
obrigatório
UUID de correlação — o event.id do envelope que o Fire emitiu ao despachar o pedido ao seu device. Ecoe-o exato; nunca o invente.
  • Verificação de fonte da verdade. Um eventId que não referencie um evento do Fire para esse pedido é rejeitado com 400 antes do 202.
  • Um eventId para toda a jornada. Envie o mesmo eventId para preparing, ready e dispatched desse dispatch — são distinguidos por eventType. (Cada dispatch a um device diferente carrega seu próprio eventId, então dois devices nunca colidem.)
stationName
string
Estação do KDS de origem, opcional (ex. Cozinha quente, Despacho 1). Armazenada para observabilidade.
metadata
object
Saco livre opcional de campos extras. Armazenado como está, sem validação.

Exemplos

Os três reportes do mesmo dispatch compartilham um eventId (o do dispatch) e diferem apenas no eventType e providerEventId:
order.preparing
{
  "eventType": "order.preparing",
  "providerEventId": "evt_2026-05-26_000122",
  "occurredAt": "2026-05-26T18:28:00.000Z",
  "orderId": "9f1c0e8a-1234-4abc-9def-0123456789ab",
  "eventId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "stationName": "Cozinha quente"
}
order.ready
{
  "eventType": "order.ready",
  "providerEventId": "evt_2026-05-26_000123",
  "occurredAt": "2026-05-26T18:30:00.000Z",
  "orderId": "9f1c0e8a-1234-4abc-9def-0123456789ab",
  "eventId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "stationName": "Cozinha quente"
}
order.dispatched
{
  "eventType": "order.dispatched",
  "providerEventId": "evt_2026-05-26_000124",
  "occurredAt": "2026-05-26T18:42:11.000Z",
  "orderId": "9f1c0e8a-1234-4abc-9def-0123456789ab",
  "eventId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "stationName": "Cozinha quente"
}

Resposta

Em caso de sucesso o endpoint responde 202 Accepted — o evento foi autenticado, validado, deduplicado e enfileirado. Um 202 não significa que o evento já foi registrado; isso acontece de forma assíncrona. Use o endpoint de status para confirmar. O body traz dois ids distintos: eventId é o id que você enviou (echo), webhookEventId é o id do Fire para o registro enfileirado. Mesma forma que o callback fiscal.
received
boolean
Sempre true quando a requisição foi aceita e enfileirada.
duplicate
boolean
true quando esta tripla exata (orderId, eventId, eventType) já foi ingerida — o registro existente é retornado e nada é re-enfileirado. false para um reporte novo (incluindo um eventType diferente do mesmo dispatch — isso é um passo novo, não uma duplicata).
eventId
string
Echo do eventId que você enviou (o event.id do dispatch).
webhookEventId
string
O id do Fire para o registro enfileirado. Passe-o para GET /v1/webhooks/events/{webhookEventId} para consultar o resultado. Em uma duplicata é o mesmo id retornado na primeira vez.
status
string
Status atual na fila — queuedprocessingprocessed (e retry / failed / dead / ignored).
firstReceivedAt
string
Timestamp ISO 8601 UTC de quando o Fire recebeu pela primeira vez este reporte. Estável entre retentativas.
message
string
Resumo legível.
{
  "received": true,
  "duplicate": false,
  "eventId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "webhookEventId": "9e6c8af8-af80-4967-9422-c096ab43c0e7",
  "status": "queued",
  "firstReceivedAt": "2026-05-26T18:30:00.512Z",
  "message": "Event accepted and queued for processing."
}

Verificar o resultado

Como o processamento é assíncrono, o 202 apenas confirma que o evento foi enfileirado. Para ver se foi registrado, consulte o endpoint de status com o webhookEventId retornado pelo 202:
GET https://app.fire.rest/api/v1/webhooks/events/{webhookEventId}
x-api-key: <sua key webhooks:kds>
status
string
Ciclo de vida da fila: queuedprocessingprocessed (concluído) · failed / dead (desistiu após retentativas) · retry (aguardando a próxima tentativa) · ignored (tratado, sem ação — ex. um duplicado ou um evento não-avançante).
attempts
number
Tentativas de processamento até agora.
result
object | null
Em caso de sucesso, o resultado do worker — ex. { "kind": "recorded" } (avançou o pedido) ou { "kind": "ignored" } (não-avançante).
error
object | null
{ "message": "…" } quando a última tentativa falhou; null caso contrário.
Um 404 é retornado para ids desconhecidos — ou ids de outro tenant — sem vazar existência. Autentique com a mesma key webhooks:kds que usou para o evento.

Idempotência e a jornada

O Fire deduplica pela tripla (orderId, eventId, eventType)não por providerEventId (que você pode regenerar livremente). É isso que faz a jornada funcionar:
CenárioResultado
preparing, depois ready, depois dispatchedmesmo eventId, eventType diferentecada um é um passo novo202 duplicate:false. O mesmo eventId é esperado, não um conflito
O mesmo reporte reenviado — mesma (orderId, eventId, eventType)202 duplicate:true — registro existente retornado, não reprocessado
eventId não emitido pelo Fire para esse orderId400
Pedido/evento fora da conta + vendor da sua API key403
Auth store momentaneamente inacessível503 — transitório, retente
Esta é a diferença chave em relação ao callback fiscal. Lá, um eventId carrega exatamente uma ação, então reusá-lo para outro eventType é um conflito (409). Aqui, um eventId de dispatch carrega legitimamente toda a jornada (preparingreadydispatched) — o eventType é o que distingue os passos. Devices diferentes recebem eventIds de dispatch diferentes, então seus reportes nunca colidem.

Anti-regressão

O status do pedido nunca deve retroceder. O Fire rastreia o estágio máximo alcançado pelo pedido (order.dispatched > order.ready > order.preparing) e compara cada evento de entrada com ele:
  • Um evento que avança o pedido (ex. order.ready depois de order.preparing) é registrado como o novo status.
  • Um evento que não avança — uma regressão (ex. order.preparing chegando depois de order.ready) ou uma repetição do mesmo status — ainda é registrado para observabilidade, mas marcado como não-avançante com um motivo, e não retrocede o pedido.
Isso torna o endpoint seguro contra entregas fora de ordem ou atrasadas: envie os eventos em qualquer ordem e o Fire mantém o pedido no seu estágio mais avançado.

Relacionado

Injetar pedido

O endpoint de injeção que cria o pedido que este evento referencia.

Callback fiscal

O webhook de entrada irmão — mesmo modelo async + idempotência + correlação.

Autenticação

Como funcionam as API keys, escopos e o binding de parceiro e vendor.