{"openapi":"3.1.0","info":{"title":"iEntrega — API pública","version":"1.0.0","description":"API de **leitura** das entregas. Autenticação por token no cabeçalho `Authorization: Bearer ient_…`,\ncom o escopo `deliveries:read`. A autorização é **deny-by-default**: um token válido de\noutra integração não lê entregas.\n\n**Criar entrega por API não existe** — esta versão é somente leitura. **Webhooks de saída também não existem.**\n\nCampos novos podem aparecer sem aviso; **ignore os que você não conhece**. Campos existentes não\nsão removidos nem renomeados dentro do `v1`.","contact":{"name":"iEntrega","email":"contato@ientrega.com","url":"https://ientrega.com/contato"},"license":{"name":"Termos de Uso do iEntrega","url":"https://ientrega.com/termos"}},"servers":[{"url":"https://ientrega.com/api","description":"iEntrega"}],"externalDocs":{"description":"Documentação da API","url":"https://ientrega.com/docs/api"},"security":[{"bearerAuth":[]}],"tags":[{"name":"Entregas","description":"Leitura das entregas da empresa do token."}],"paths":{"/v1/deliveries":{"get":{"tags":["Entregas"],"summary":"Lista as entregas","description":"Ordem `created_at` decrescente. Pagine seguindo `next_cursor` até ele vir `null` — **cursor, não offset**: com offset, uma entrega criada durante a paginação empurra a janela e você pula um registro, sem sinal nenhum.","operationId":"listDeliveries","parameters":[{"name":"status","in":"query","description":"Um ou mais estados, separados por vírgula. **Valor desconhecido é erro 400**, não filtro ignorado — assim um erro de digitação nunca devolve a lista inteira em silêncio.","required":false,"schema":{"type":"array","items":{"type":"string","enum":["PENDING_ASSIGNMENT","ASSIGNED","OUT_FOR_DELIVERY","IN_PROGRESS","COMPLETED","CANCELLED"]}},"style":"form","explode":false},{"name":"created_since","in":"query","description":"Só entregas criadas a partir deste instante (ISO 8601).","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updated_since","in":"query","description":"Só entregas alteradas a partir deste instante (ISO 8601). Útil para sincronizar estado — mas a ordenação continua por `created_at`.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","description":"Quantos itens por página (1 a 200).","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","description":"Cursor opaco vindo do `next_cursor` da página anterior. Cursor inválido é erro 400.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Página de entregas.","content":{"application/json":{"schema":{"type":"object","required":["ok","data","next_cursor"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"next_cursor":{"type":["string","null"],"description":"Passe em `cursor` para a próxima página. `null` quando acabou."}}}}}},"400":{"description":"Parâmetro inválido. O corpo diz qual.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"401":{"description":"Token ausente, inválido, revogado ou expirado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"Token válido, mas sem o escopo `deliveries:read`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"429":{"description":"Limite de requisições: 240/min por IP, 120/min por token. **Respeite o cabeçalho `Retry-After`** da resposta: ele diz em quantos segundos tentar de novo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}},"headers":{"Retry-After":{"description":"Quantos segundos esperar antes de repetir. Sempre presente no 429.","required":true,"schema":{"type":"integer","minimum":1}}}},"500":{"description":"Erro interno. Tente de novo; se persistir, fale com o suporte.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/deliveries/{id}":{"get":{"tags":["Entregas"],"summary":"Uma entrega","description":"Mesmo objeto do item da lista — quem guardou um `id` relê sem um segundo mapeamento.","operationId":"getDelivery","parameters":[{"name":"id","in":"path","required":true,"description":"O `id` da entrega. Id malformado devolve 404, não 500.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"A entrega.","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Delivery"}}}}}},"401":{"description":"Token ausente, inválido, revogado ou expirado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"Token válido, mas sem o escopo `deliveries:read`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"404":{"description":"Entrega não encontrada para este token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"429":{"description":"Limite de requisições: 240/min por IP, 120/min por token. **Respeite o cabeçalho `Retry-After`** da resposta: ele diz em quantos segundos tentar de novo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}},"headers":{"Retry-After":{"description":"Quantos segundos esperar antes de repetir. Sempre presente no 429.","required":true,"schema":{"type":"integer","minimum":1}}}},"500":{"description":"Erro interno. Tente de novo; se persistir, fale com o suporte.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Token emitido pelo iEntrega, com o escopo `deliveries:read`. Cole só o token: o `Bearer ` é acrescentado automaticamente."}},"schemas":{"Delivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Identificador da entrega. Use em `GET /v1/deliveries/{id}`."},"status":{"type":"string","enum":["PENDING_ASSIGNMENT","ASSIGNED","OUT_FOR_DELIVERY","IN_PROGRESS","COMPLETED","CANCELLED"],"description":"Estado atual da entrega."},"expected_delivery_date":{"type":["string","null"],"description":"Dia prometido (`YYYY-MM-DD`), não instante. `null` sem previsão (retirada também tem previsão)."},"is_pickup":{"type":"boolean","description":"O cliente busca no balcão de quem emitiu o documento. Muda o LOCAL, não o prazo: a previsão continua valendo (o dia em que a mercadoria fica disponível)."},"on_time":{"type":["boolean","null"],"description":"Pontualidade em TRÊS estados: `true` no prazo, `false` fora, `null` quando a pergunta não se aplica (ainda aberta ou sem previsão). Tratar `null` como `false` inventa atraso onde não há promessa."},"document":{"type":"object","properties":{"type":{"type":"string","description":"Tipo do documento fiscal (NFE, CTE, PEDIDO, …)."},"number":{"type":["string","null"],"description":"Número do documento."},"series":{"type":["string","null"],"description":"Série. String vazia quando não se aplica (PEDIDO, DUPLICATA)."},"external_ref":{"type":["string","null"],"description":"O identificador que esta entrega tem no sistema onde ela nasceu, quando houver. Serve para você correlacionar com os seus próprios registros."}},"required":["type","number","series","external_ref"],"additionalProperties":false,"description":"O documento fiscal que originou a entrega."},"recipient":{"type":"object","properties":{"name":{"type":["string","null"],"description":"Nome do destinatário."},"document":{"type":["string","null"],"description":"CNPJ ou CPF, sem formatação garantida."},"phone":{"type":["string","null"],"description":"Telefone (WhatsApp) do destinatário, só dígitos, como foi gravado. `null` quando falta."},"address":{"anyOf":[{"type":"object","properties":{"street":{"type":["string","null"],"description":"Logradouro."},"number":{"type":["string","null"],"description":"Número. Sempre texto, mesmo quando o valor é numérico."},"district":{"type":["string","null"],"description":"Bairro."},"city":{"type":["string","null"],"description":"Cidade."},"state":{"type":["string","null"],"description":"UF."},"zip":{"type":["string","null"],"description":"CEP."}},"required":["street","number","district","city","state","zip"],"additionalProperties":false,"description":"Endereço estruturado do destinatário."},{"type":"null"}],"description":"`null` quando o endereço não foi informado. A chave sempre existe, então a forma da resposta não muda entre entregas."}},"required":["name","document","phone","address"],"additionalProperties":false,"description":"Destinatário da entrega."},"location":{"type":"object","properties":{"map_link":{"type":["string","null"],"description":"O LOCAL DE ENTREGA como a operação informou: link de mapa (Google Maps, coordenada) ou endereço digitado. `null` quando falta — é o que deixa a entrega \"sem localização\". É independente de `recipient.address`, que é o cadastro do cliente e nunca vira destino. Em retirada (`is_pickup`) não é usado: o local é o balcão do emitente."},"latitude":{"type":["number","null"],"description":"Latitude do local de entrega, quando já resolvida a partir do `map_link`. `null` sem `map_link` ou enquanto não foi resolvida."},"longitude":{"type":["number","null"],"description":"Longitude do local de entrega. `null` nas mesmas condições da `latitude`."}},"required":["map_link","latitude","longitude"],"additionalProperties":false,"description":"Para onde a entrega vai. A coordenada sai só do `map_link` — nunca do endereço cadastral do cliente."},"driver":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Entregador vinculado, ou `null` se ainda não há."},"attempts_count":{"type":"integer","description":"Quantas tentativas de entrega já houve."},"timestamps":{"type":"object","properties":{"created_at":{"type":"string","description":"ISO 8601."},"updated_at":{"type":"string","description":"ISO 8601. Use com o filtro `updated_since`."},"assigned_at":{"type":["string","null"],"description":"Quando ganhou entregador."},"started_at":{"type":["string","null"],"description":"Quando saiu para entrega."},"completed_at":{"type":["string","null"],"description":"Quando a conclusão foi registrada. Para medir prazo, use `completed_at_effective`."},"completed_at_effective":{"type":["string","null"],"description":"Quando a entrega foi efetivamente concluída. **É este o campo para medir prazo** — ele pode ser anterior ao `completed_at`."},"cancelled_at":{"type":["string","null"],"description":"Quando foi cancelada."}},"required":["created_at","updated_at","assigned_at","started_at","completed_at","completed_at_effective","cancelled_at"],"additionalProperties":false,"description":"Marcos de tempo, todos em ISO 8601."},"cancelled_reason":{"type":["string","null"],"description":"Motivo do cancelamento, quando houver."},"tracking_url":{"type":["string","null"],"description":"Página pública de rastreio, quando disponível. **Não guarde como permanente**: pode passar a `null`, e por isso vale reler em vez de arquivar o endereço."},"proof_url":{"type":["string","null"],"description":"Página de verificação do comprovante. `null` enquanto não há selo."}},"required":["id","status","expected_delivery_date","is_pickup","on_time","document","recipient","location","driver","attempts_count","timestamps","cancelled_reason","tracking_url","proof_url"],"additionalProperties":false,"description":"Uma entrega.","$schema":"http://json-schema.org/draft-07/schema#"},"Erro":{"type":"object","required":["ok","error","code","hint","docs"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Mensagem legível. Não contém detalhe interno."},"code":{"type":"string","enum":["bad_request","unauthorized","forbidden","not_found","rate_limited","internal_error"],"description":"Identificador estável do erro. Decida por ele, não pelo texto de `error`."},"hint":{"type":"string","description":"O que fazer para resolver."},"docs":{"type":"string","format":"uri","description":"Onde está a documentação da API."}}}}}}