Webhooks da OpenAI que aguentam um handler de 45 segundos.
Seu handler faz trabalho de verdade: RAG, outra chamada ao modelo, uma transação no banco. A OpenAI dá a ele poucos segundos. O AnyHook responde 200 em cerca de 1 s e dá ao seu handler até o timeout do seu plano para terminar, dentro da franquia de computação do plano.
O problema do tempo
As background responses, os jobs de batch e os jobs de fine-tuning da OpenAI informam o resultado por HTTP e esperam um 2xx em poucos segundos; depois, tentam de novo por até 72 horas. No momento em que seu handler faz algo interessante, como encadear uma segunda chamada ao modelo, fazer uma busca vetorial ou chamar a Stripe, você estoura esse prazo.
Quando você estoura o prazo, a OpenAI tenta de novo. Seu handler roda outra vez. Agora você paga pelos tokens duas vezes e o sistema que depende dele recebe duplicatas. A solução não é um timeout maior; é um padrão que separa a confirmação do recebimento do processamento.
Substituição direta: troque a URL do webhook
Seu handler atual não precisa mudar. O AnyHook responde à OpenAI na edge em cerca de 1 s e depois encaminha o payload verificado para seu endpoint, com novas tentativas (retries), replay e log de eventos.
// 1. Point OpenAI's webhook URL at your AnyHook inbound:
// https://in.anyhook.net/{user-slug}/{app-slug}
//
// 2. Keep your existing handler, it now has all the time it needs.
// AnyHook re-signs every delivery with AnyHook-Signature.
import OpenAI from "openai";
import { verifyWebhook } from "anyhook-verify";
const openai = new OpenAI();
export async function POST(req: Request) {
const ok = await verifyWebhook(req, process.env.ANYHOOK_SIGNING_SECRET!);
if (!ok) return new Response("invalid signature", { status: 401 });
// OpenAI's own event, byte for byte: { type: "response.completed", data: { id }, ... }
const event = await req.json();
if (event.type !== "response.completed") return new Response("ok");
const response = await openai.responses.retrieve(event.data.id);
// Run anything here. AnyHook already returned 200 to OpenAI.
// If you fail, AnyHook retries with backoff (up to 10 attempts on Scale).
await ragPipeline(response); // 25s
await secondModelCall(response); // 18s
await persistResult(response); // 2s
return new Response("ok", { status: 200 });
}Perguntas que as equipes fazem
- Perco a verificação de assinatura da OpenAI?
- Não. A OpenAI assina com o padrão Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature). Defina a origem do app como Standard Webhooks e cole o segredo de assinatura do webhook (whsec_...): o AnyHook verifica a assinatura na edge, rejeita falsificações e depois assina de novo cada entrega para seu endpoint com o AnyHook-Signature.
- O que acontece se meu handler ficar fora do ar por uma hora?
- O AnyHook coloca o evento na fila e tenta de novo com backoff exponencial: até 3 tentativas no Free, 5 no Pro, 10 no Scale. Cada tentativa fica registrada no log e disponível para replay no painel. A OpenAI vê um 200 e segue em frente.
- Quais eventos da OpenAI isso cobre?
- Tudo o que a OpenAI envia por webhook: background responses (response.completed e seus irmãos failed, cancelled e incomplete), jobs de batch, jobs de fine-tuning e execuções de eval. Streaming não é webhook: é um stream que seu código lê diretamente, então nunca passa pelo AnyHook.
Troque uma URL. Mantenha seu handler de OpenAI.
O plano Free cobre 10 mil eventos / mês. Sem SDK: aponte os webhooks de OpenAI para sua URL de entrada do AnyHook.