Idempotency-Key varia por motor:
- Motor de CPF/CNPJ (
POST /analyses): o header é obrigatório. Sem ele (ou com valor vazio), a API responde400 bad_requestcom a mensagem “Idempotency-Key header required”. - Motor de Borderô (
POST /operations): o header é opcional. Presente, funciona como nos analyses (replay devolve200com o body original; key reusada com payload diferente devolve409 idempotency_conflict). Ausente, cada POST cria uma operação nova — e uma cobrança nova.
Idempotency-Key, repetir é sempre seguro: a API reconhece a repetição e devolve a resposta original, sem cobrar de novo.
Como funciona (os dois motores)
A deduplicação vale por uma janela de 24 horas a partir da primeira requisição.
Repare no status code:
202 significa “criei agora”; 200 significa “isto é um replay — nada novo foi criado nem cobrado”. Seu código pode tratar os dois como sucesso, já que o body é o mesmo.
O que conta como “mesmo conteúdo”
A comparação cobre o payload inteiro do POST, em cada motor:
No borderô, reenviar exatamente o mesmo multipart com a mesma key é um replay (
200). Trocar o arquivo, o ZIP de NFe ou qualquer campo mantendo a mesma key resulta em 409 idempotency_conflict.
Concorrência
Se duas requisições com a mesma key chegarem ao mesmo tempo, a primeira vence. A concorrente recebe409 enquanto a primeira ainda está em andamento. Não gere uma key nova nesse caso: aguarde um instante e consulte o resultado via GET (/analyses/{id} ou /operations/{id}), usando o id da resposta 202 original. Se você ainda não tem o id (por exemplo, a primeira chamada deu timeout no seu lado), repita o POST com a mesma key até receber 200 (replay) ou 202 (se a primeira chamada nunca chegou ao servidor).
Receita prática
- Derive a key do ID interno do seu job. Gere um UUID no momento em que o job (ou o borderô) é criado no seu sistema e persista junto com ele. UUID é o formato recomendado. Uma key por requisição pretendida — nunca reutilize a mesma key para documentos, arquivos ou jobs diferentes.
- Timeout ou 5xx → repita com a MESMA key. A resposta será a 202 original (se a primeira chamada não chegou) ou um replay 200 (se chegou). Nos dois casos, sem cobrança dupla.
- 4xx de validação → corrija e use uma key NOVA. A key antiga está amarrada ao conteúdo antigo: mesma key + conteúdo corrigido resulta em
409 idempotency_conflict.
Os Motores usam a mesma base da API 221b (
https://221b-api.sherlocker.com.br/api/v1), mas autenticam via Authorization: Bearer slhk_… — não via ?token=.Retry na prática
- CPF/CNPJ
- Borderô
- Primeira submissão → 202. Análise criada, tokens debitados.
- Replay (mesma key, mesmo body) → 200. O mesmo body JSON da 202, byte a byte — mesmo
id, mesmostokens_chargedebalance, mesmorequest_id. Nada foi criado nem cobrado de novo. - Mesma key, body diferente → 409. Por exemplo, a mesma key com um
purposeadicionado:
cURL
application/problem+json) — igual nos dois motores:
code (idempotency_conflict) é retornado tanto no conflito de conteúdo quanto na concorrência. Faça branching pelo code, não pelo texto de detail, que pode variar. Detalhes em Erros e idempotency_conflict.
Próximos passos
Ciclo de vida
Status e como fazer polling em cada motor
Cobrança
Quando os tokens são debitados e quando há estorno
Erros
Formato RFC 7807 e todos os códigos de erro