Integrar
Idempotência
A API deduplica escrita repetida em 60 segundos mesmo sem header — e o Idempotency-Key é a camada que você controla.
Repetir uma escrita nunca duplica o efeito dela. São duas camadas independentes: uma que age sozinha, sempre, e outra que você controla pelo header Idempotency-Key. Quem só conhece a segunda se surpreende com a primeira.
A janela automática de 60 segundos
Na prática: dois POST /contacts com o mesmo corpo, em sequência, criam um contato. O segundo responde 200 (não 201) com idempotency_replay: true e o mesmo contato de antes. É o que protege contra o duplo clique e contra o retry cego de um timeout.
Quando ela atrapalha
Se você quiser mesmo criar dois registros idênticos em seguida — dois contatos de mesmo nome, sem telefone nem e-mail, por exemplo — precisa diferenciá-los (um campo, uma etiqueta) ou esperar a janela virar. Caso contrário o segundo some, com 200 e sem erro nenhum.
Com Idempotency-Key: a camada que você controla
Mande Idempotency-Key com um valor único por operação lógica do seu lado — um UUID por tentativa de negócio, não um por requisição HTTP. Aí a proteção deixa de valer 60 segundos e passa a valer enquanto a chave viver.
curl -X POST https://api.growthaisystem.com/api/v1/contacts \
-H "Authorization: Bearer gos_SEU_TOKEN_AQUI" \
-H "Idempotency-Key: 6f1c0a9e-6a1e-4c2f-9f3a-1c0a9e6a1e4c" \
-H "Content-Type: application/json" \
-d '{"name":"Novo contato"}'Mesmo corpo, mesma chave
A API não executa de novo: devolve o resultado da primeira execução. Numa criação o status também muda — 201 na primeira vez, 200 nas repetições.
O corpo devolvido é lido fresco do banco no momento da repetição, não é um retrato guardado: se alguém editou o registro entre a sua primeira chamada e o seu retry, você recebe o estado atual. O que está garantido é que a escrita não aconteceu duas vezes — não que a foto seja idêntica.
Corpo diferente, mesma chave
409 idempotency_conflict. A API nunca adivinha qual das duas versões você queria, e nunca substitui a execução original em silêncio. Gere uma chave nova para a operação nova.
Quando a primeira tentativa falhou
Repetir com a mesma chave re-executa de verdade. Uma Ação que terminou em erro não fica presa devolvendo o erro velho para sempre: o retry roda o handler de novo e você recebe o resultado novo (sucesso, ou um erro novo). É esse comportamento que torna seguro repetir com chave fixa.
Escopo e limites da chave
- Namespace. A chave é isolada por chave de API + método + padrão de rota. O padrão é
/contacts/:id, não/contacts/c_123: reusar a mesmaIdempotency-Keyem dois PATCH de contatos diferentes devolve409 idempotency_conflict(corpos diferentes) ou o resultado do primeiro (corpos iguais). Regra prática: um valor por operação, nunca um valor fixo por integração. - Tamanho. A chave é cortada em 200 caracteres. Duas chaves que só diferem depois do 200º caractere viram a mesma.
- Validade. O registro de deduplicação é podado aos 30 dias. Depois disso a mesma chave volta a ser "nova" e a escrita executa outra vez. Idempotência é rede para retry de minutos ou horas, não memória de longo prazo.
Onde o idempotency_replay aparece — e onde não
A deduplicação vale em todas as 17 rotas de escrita que passam pelo Núcleo. Mas só 5 delas dizem isso no corpo da resposta:
| Rota | Como avisa que foi repetição |
|---|---|
POST /contacts | idempotency_replay: true + status 200 em vez de 201 |
POST /contacts/upsert | idempotency_replay: true + status 200 |
PATCH /contacts/:id | idempotency_replay: true |
POST /opportunities | idempotency_replay: true + status 200 |
POST /appointments | idempotency_replay: true + status 200 |
| as outras 12 escritas do Núcleo | não avisam — respondem como se tivessem executado agora |