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_urlprecisa ser uma URLhttps. A query string é mantida, então você pode acrescentar sua própria referência, comohttps://example.com/hooks/rewords?order=1234.- Responda com qualquer status
2xxem 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
idda 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 prefixowhsec_, 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.
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);
}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' }).
Imagens
Como enviar imagens para a API da ReWords.AI — URL, base64, data URL ou upload multipart —, os limites de tamanho e formato, o tratamento de EXIF e transparência, os arquivos de resultado e como as caixas viram pixels.
Erros
Formato de erro da API da ReWords.AI, códigos de status HTTP e códigos de erro, e quais erros são cobrados.