ReWords.AI API

Webhooks

Receba um webhook assinado da ReWords.AI quando uma edição termina e verifique o HMAC de X-Rewords-Signature em Node.js ou Python.

Passe callback_url em POST /edits. Quando o job chega a succeeded ou failed, fazemos POST nessa URL com o mesmo JSON que você receberia de GET /edits/{id}.

  • callback_url precisa ser uma URL https. A query string é mantida, então você pode acrescentar sua própria referência, como https://example.com/hooks/rewords?order=1234.
  • Responda com qualquer status 2xx em até 10 segundos para confirmar. Qualquer outra coisa — outro status, um timeout, um erro de conexão — conta como falha.
  • Uma entrega com falha é repetida 1, 5 e 30 minutos depois da tentativa anterior, então a última nova tentativa acontece cerca de 36 minutos depois da primeira. Depois disso paramos; GET /edits/{id} continua retornando o resultado.
  • Toda nova tentativa envia os mesmos bytes com a mesma assinatura. Por causa delas, você pode receber o mesmo job mais de uma vez: use o id da edição para ignorar um que você já tratou.
  • Cada entrega é assinada: X-Rewords-Signature: sha256=<64 caracteres hexadecimais>, um HMAC-SHA256 do corpo bruto da requisição usando o seu segredo de webhook. Use a string inteira do segredo, incluindo o prefixo whsec_, como chave do HMAC.

Seu segredo de webhook

Há um segredo de webhook por conta, compartilhado por todas as suas chaves. Ele fica na sua página de chaves de API. Você pode redefini-lo lá; o segredo antigo para de funcionar na hora, então atualize o seu receptor logo depois de redefinir.

Verifique a assinatura

Rejeite a requisição com 401 se a verificação falhar e não a processe. Reenviar não conserta uma assinatura inválida.

Node.js
import crypto from 'node:crypto';

export function verify(rawBody, header, secret) {
  if (typeof header !== 'string') return false;
  const expected = Buffer.from('sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex'));
  const received = Buffer.from(header);
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}
Python 3.8+
import hashlib, hmac
from typing import Optional

def verify(raw_body: bytes, header: Optional[str], secret: str) -> bool:
    if not header:
        return False
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header.encode(), expected.encode())

Verifique com os bytes brutos antes de interpretar o JSON — serializá-lo de novo muda a assinatura. No Express, por exemplo, leia o corpo com express.raw({ type: 'application/json' }).

Nesta página