Idempotência
Repita uma requisição de envio com segurança, sem o risco de mandar o mesmo e-mail duas vezes.
#Como usar
Uma requisição de envio pode dar timeout depois de a Postal já ter aceitado o e-mail. Repetir sem cuidado manda o e-mail duas vezes. Para evitar isso, envie um identificador único da operação no cabeçalho Idempotency-Key:
cURL
curl -X POST https://api.postal.so/emails \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Idempotency-Key: order-10482-shipped" \
-H "Content-Type: application/json" \
-d '{
"from": "Loja Exemplo <[email protected]>",
"to": ["[email protected]"],
"subject": "Seu pedido #10482 saiu para entrega",
"html": "<p>O pedido <b>#10482</b> está a caminho.</p>"
}'
Node.js
const response = await fetch('https://api.postal.so/emails', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'order-10482-shipped',
},
body: JSON.stringify({
from: 'Loja Exemplo <[email protected]>',
to: ['[email protected]'],
subject: 'Seu pedido #10482 saiu para entrega',
html: '<p>O pedido <b>#10482</b> está a caminho.</p>',
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/emails",
headers={
"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}",
"Idempotency-Key": "order-10482-shipped",
},
json={
"from": "Loja Exemplo <[email protected]>",
"to": ["[email protected]"],
"subject": "Seu pedido #10482 saiu para entrega",
"html": "<p>O pedido <b>#10482</b> está a caminho.</p>",
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('emails', [
'headers' => [
'Authorization' => 'Bearer '.getenv('POSTAL_API_KEY'),
'Idempotency-Key' => 'order-10482-shipped',
],
'json' => [
'from' => 'Loja Exemplo <[email protected]>',
'to' => ['[email protected]'],
'subject' => 'Seu pedido #10482 saiu para entrega',
'html' => '<p>O pedido <b>#10482</b> está a caminho.</p>',
],
]);
$data = json_decode($response->getBody(), true);
Se a mesma chave chegar de novo em até 24 horas, com o mesmo corpo, a Postal não envia outra vez: devolve a resposta guardada da primeira requisição, com o mesmo status e o mesmo ID.
#Regras
- Vale para
POST /emails,POST /emails/batchePOST /events(um evento repetido não inicia a automação de novo). Nos outros endpoints, o cabeçalho é ignorado. - A chave tem de 1 a 256 caracteres; fora disso, a resposta é
400 invalid_idempotency_key. - As chaves valem por time: duas chaves de API do mesmo time compartilham as mesmas chaves de idempotência.
- Só respostas de sucesso (
2xx) são guardadas. Se a primeira tentativa falhou com422ou429, corrija e repita com a mesma chave. - Mesma chave com outro corpo, método ou caminho:
409 invalid_idempotent_request. - Mesma chave enquanto a primeira requisição ainda está em andamento:
409 concurrent_idempotent_requests. Espere um pouco e repita.
#Como escolher a chave
Use algo que identifique o motivo do envio, não a tentativa: order-10482-shipped, password-reset-8f2a91 ou um UUID gerado e salvo junto com o pedido. Gerar um UUID novo a cada tentativa anula a proteção.