Pular para o conteúdo
Entrar Lista de espera
Docs/Guias/Repetir uma requisição sem duplicar

Repetir uma requisição sem duplicar

Quando a resposta se perde (a rede caiu, o tempo esgotou), você não sabe se o Praeko recebeu o pedido. Mande o cabeçalho Idempotency-Key e o servidor executa o pedido uma vez só: a repetição recebe a mesma resposta da primeira.

Sem o cabeçalho, nada mudaQuem já usa a API continua exatamente como estava. O cabeçalho é opcional em toda rota que o aceita.

Regras

Regra Valor
Onde vale Rotas autenticadas de POST, PATCH e DELETE de /v1 (chave de API ou sessão do painel). GET nunca é guardado; PUT já é repetível por natureza.
A chave De 1 a 255 caracteres ASCII visíveis, sem espaço. Use um UUID. Fora disso: 422 invalid_field.
Escopo Workspace, rota e chave. A mesma chave em outro workspace, ou em outra rota, é outra chave. Nenhuma resposta passa de um workspace para outro.
Prazo 24 horas depois do primeiro pedido.
Pedido igual Mesmo método, caminho, query e corpo (e o mesmo X-Praeko-Contract): repete a resposta guardada, com Idempotent-Replayed: true.
Pedido diferente Mesma chave com outro método, caminho, query ou corpo: 422 idempotency_key_reuse. Nada é executado.
Primeiro ainda em andamento 409 idempotency_in_progress, com Retry-After: 1. Repita em instantes.
Erro do servidor Resposta 5xx não é guardada: a chave fica livre e a nova tentativa executa de verdade.
Erro do cliente Resposta 4xx (validação, 404, 409…) é guardada e repetida. Corrija o pedido e use uma chave nova.
Resposta grande Acima de 256 KB só o status é guardado; repetir dá 409 idempotency_response_too_large. Consulte o recurso por GET.
Pedido órfão Se o servidor morrer no meio do pedido, a reserva é retomada depois de 2 minutos.
Ficam de fora PUT /v1/media/:id/parts/:part e PUT /v1/media/:id/content (bytes crus, já repetíveis: reenviar a mesma parte é seguro). A criação (POST /v1/media) e a conclusão (POST /v1/media/:id/complete) aceitam a chave.

Os erros de autenticação e o limite de requisições (401, 403, 429) são respondidos antes da chave e nunca são guardados.

Os três erros

Status `code` O que fazer
422 idempotency_key_reuse A chave já foi usada com outro pedido. Gere uma chave nova para o pedido novo.
409 idempotency_in_progress O primeiro pedido ainda roda. Espere o Retry-After e repita com a mesma chave.
409 idempotency_response_too_large A resposta original passou de 256 KB e não foi guardada. Leia o recurso por GET.

curl

Primeira vez, e a repetição idêntica
KEY=$(uuidgen)
curl -X POST https://praeko.app/v1/ideas \
  -H "Authorization: Bearer $PRAEKO_KEY" -H "X-Praeko-Contract: en" \
  -H "Content-Type: application/json" -H "Idempotency-Key: $KEY" \
  -d '{"title":"O bug que só aparecia na segunda-feira"}'

# a rede caiu e você não sabe se foi: repita IDÊNTICO, com a mesma chave
curl -i -X POST https://praeko.app/v1/ideas \
  -H "Authorization: Bearer $PRAEKO_KEY" -H "X-Praeko-Contract: en" \
  -H "Content-Type: application/json" -H "Idempotency-Key: $KEY" \
  -d '{"title":"O bug que só aparecia na segunda-feira"}'
# HTTP/2 200 … idempotent-replayed: true   (mesmo corpo, uma ideia só no quadro)

JavaScript com fetch

Repetir com a mesma chave
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function criarPost(post) {
  const key = crypto.randomUUID(); // uma chave por pedido, a mesma em todas as tentativas
  for (let i = 0; i < 3; i++) {
    try {
      const r = await fetch("https://praeko.app/v1/posts", {
        method: "POST",
        headers: { authorization: `Bearer ${process.env.PRAEKO_KEY}`, "x-praeko-contract": "en", "content-type": "application/json", "idempotency-key": key },
        body: JSON.stringify(post),
      });
      if (r.status === 409 && (await r.clone().json()).error.code === "idempotency_in_progress") { await sleep(1000); continue; }
      return r;
    } catch { /* a rede caiu: repete com a mesma chave */ }
  }
  throw new Error("sem resposta depois de 3 tentativas");
}

SDK (@praeko/sdk)

Cada chamada que escreve aceita a opção idempotencyKey. Com true, o SDK gera um UUID e reenvia o pedido com a mesma chave se a rede falhar, ou se vier 429 ou 5xx. Com uma string, você escolhe a chave (por exemplo, a de um job seu, para sobreviver a um reinício do processo).

JavaScript
import { Praeko } from "@praeko/sdk";
const praeko = new Praeko({ url: "https://praeko.app", key: process.env.PRAEKO_KEY });

// 1) o SDK gera o UUID e repete o POST com a mesma chave se a rede falhar
const post = await praeko.posts.create({ title, media: { video: video.id }, texts, items }, { idempotencyKey: true });

// 2) ou escolha a chave
await praeko.webhooks.create({ url: "https://exemplo.com.br/hooks/praeko", idempotencyKey: `hook-${jobId}` });

Sem idempotencyKey, o SDK não repete nenhum POST, PATCH ou DELETE (só GET e as partes de upload). Aceitam a opção: media.create e media.complete, posts.create, adopt, update, cancel, publishNow e scheduleYoutube, webhooks.create, rotateSecret e redeliver, ideas.create e import, apiKeys.create, youtube.reply e instagram.reply.

CLI

Terminal
praeko publish-now <id> --idempotency-key K
praeko webhook create --url https://exemplo.com.br/hooks/praeko --idempotency-key K

publish-now e webhook create mandam o cabeçalho. O CLI não repete sozinho: a opção serve para quem roda o comando de novo, por exemplo num script com tentativas.

O que já era seguro reenviar

Situação O que fazer
POST /v1/posts com o seu id Mande o seu próprio id no corpo: repetido, volta 409 id_exists e nada é duplicado. Vale mesmo sem Idempotency-Key.
Parte de mídia repetida Seguro: PUT /v1/media/:id/parts/:part sobrescreve a mesma parte.
Entrega de webhook repetida O Praeko-Delivery é igual em todas as tentativas: guarde os ids já tratados e ignore os repetidos.
POST /v1/insights/import Idempotente: faz upsert por rede e id.
POST /v1/ideas/import Idempotente pelo id antigo de cada ideia (só entram as que ainda não existem).
Dúvida ou erro nesta página? contato@praeko.appVer .md

Digite para buscar páginas, rotas e códigos de erro.