Webhooks
Receba notificações HTTP assinadas quando suas publicações forem publicadas, agendadas ou falharem, e quando uma imagem terminar de ser gerada, e verifique a assinatura.
https://post.adaptlypost.com/post/api/v1/webhooksRegistre um endpoint de webhook. Cada webhook recebe todos os eventos, assinados com seu segredo.
Criar, atualizar, excluir e testar um webhook exige webhooks.manage (Administrador e Editor). Listar e ler webhooks exige webhooks.read, que chaves de Colaborador não têm.
Parâmetros do corpo
| Parâmetro | Tipo | Descrição |
|---|---|---|
urlOBRIGATÓRIO | string | Endpoint http(s) acessível publicamente que receberá as entregas de eventos. Hosts privados são rejeitados. Máx. 10 webhooks por espaço de trabalho. |
Eventos
Cada webhook registrado recebe todos os eventos a seguir. O nome do evento é enviado no payload e no cabeçalho x-adaptly-event, para que você possa filtrar do seu lado.
| Evento | Descrição |
|---|---|
post.published | Todas as plataformas da publicação publicaram com sucesso |
post.partially_failed | Algumas plataformas publicaram, outras falharam |
post.failed | A publicação falhou em todas as plataformas |
post.scheduled | Uma publicação foi agendada |
account.unauthorized | Uma plataforma rejeitou o token de uma conta; a conta fica unauthorized até ser reconectada |
image.completed | Uma imagem iniciada com POST /ai/images terminou; data.image.imageUrl está pronta para usar |
image.failed | Uma imagem iniciada com POST /ai/images falhou; data.image.error indica o motivo |
Conteúdo do evento
Cada entrega é um corpo JSON com id, event, createdAt e data. data traz post, a publicação completa no mesmo formato de GET /api/v1/social-posts/:id, nos eventos post.*; account (id, platform, displayName, pageId no Facebook, status e o motivo da plataforma) em account.unauthorized; e image (jobId, sessionId, prompt e depois imageUrl e imageId, ou error) nos eventos image.*. Uma entrega de teste envia o evento webhook.test com o id do webhook e a lista de eventos.
Verificação de assinaturas
Cada entrega é assinada com o segredo do seu webhook (whsec_...). Calcule um HMAC-SHA256 sobre "{timestamp}.{rawBody}" e compare com o cabeçalho x-adaptly-signature antes de confiar no payload.
O segredo é exibido apenas uma vez
O segredo de assinatura (whsec_...) é retornado apenas na resposta à solicitação de criação, nunca em respostas de listagem, obtenção ou atualização. Guarde-o com segurança. Se você perdê-lo, exclua o webhook e crie um novo.const crypto = require('crypto');
const expected =
'sha256=' +
crypto
.createHmac('sha256', webhookSecret)
.update(`${req.headers['x-adaptly-timestamp']}.${rawBody}`)
.digest('hex');
const isValid = expected === req.headers['x-adaptly-signature'];Entrega e novas tentativas
Seu endpoint deve responder com status 2xx em 10 segundos. Entregas com falha são repetidas até 5 vezes com backoff exponencial. Entregas podem chegar mais de uma vez, torne seu handler idempotente. Uma entrega para um host privado ou interno é recusada e registrada com um erro.
Desativação automática
Após 20 entregas com falha consecutivas, o webhook é desativado automaticamente. Reative-o via PATCH { "active": true } ou pelo painel.Gerenciando webhooks
Os webhooks são gerenciados com os seguintes endpoints, com a mesma autenticação por chave de API:
GET /api/v1/webhooks # list registered webhooks
GET /api/v1/webhooks/:id # get one webhook
PATCH /api/v1/webhooks/:id # update url or active
DELETE /api/v1/webhooks/:id # delete a webhook
POST /api/v1/webhooks/:id/test # send a signed webhook.test eventVocê também pode gerenciar webhooks visualmente pelo painel, na página API e agentes de IA.
Especificação OpenAPI
Uma especificação OpenAPI 3.0 legível por máquina de toda a API REST: incluindo webhooks e o esquema do payload de eventos, está disponível publicamente. Importe-a no Make, n8n ou qualquer ferramenta compatível com OpenAPI.
curl https://post.adaptlypost.com/post/api/v1/openapi.jsoncurl --request POST \
--url https://post.adaptlypost.com/post/api/v1/webhooks \
--header 'Authorization: Bearer <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://your-server.com/webhook"
}'curl --request POST \
--url https://post.adaptlypost.com/post/api/v1/webhooks/<webhook-id>/test \
--header 'Authorization: Bearer <api-key>'POST <your-url>
x-adaptly-event: post.published
x-adaptly-webhook-id: wh_abc123
x-adaptly-timestamp: 1784643600
x-adaptly-signature: sha256=3f5a...
{
"id": "deliver-webhook-...",
"event": "post.published",
"createdAt": "2026-07-21T14:20:00.000Z",
"data": {
"post": {
"id": "post_xyz789",
"status": "COMPLETED",
"recurringPostId": "rp_abc123",
"occurrenceAt": "2026-07-21T14:19:00.000Z",
"platforms": [
{
"platform": "TWITTER",
"status": "PUBLISHED",
"platformPostId": "1234567890",
"publishedAt": "2026-07-21T14:19:58.000Z"
}
]
}
}
}
POST <your-url>
x-adaptly-event: account.unauthorized
{
"id": "deliver-webhook-...",
"event": "account.unauthorized",
"createdAt": "2026-09-13T09:10:00.000Z",
"data": {
"account": {
"id": "conn_jkl012",
"platform": "FACEBOOK",
"displayName": "Your Page",
"pageId": "123456789012345",
"status": "unauthorized",
"reason": "Error validating access token: Sessions for the user are not allowed because the user is not a confirmed user."
}
}
}
POST <your-url>
x-adaptly-event: image.completed
{
"id": "deliver-webhook-...",
"event": "image.completed",
"createdAt": "2026-09-20T10:02:31.000Z",
"data": {
"image": {
"jobId": "generate-image-8f2a1c40-6d3b-4e91-b7c2-0a5d9e13f846",
"sessionId": "b31c7a44-2f19-4c85-9d60-7e2af4c81b93",
"prompt": "a red bicycle leaning against a yellow wall, soft morning light",
"imageUrl": "https://cdn.adaptlypost.com/ai-images/ai-studio-4c81b93.png",
"imageId": "d7e44a10-93bc-4f27-8ae5-1b06c2f4d938"
}
}
}{
"id": "wh_abc123",
"url": "https://your-server.com/webhook",
"active": true,
"secret": "whsec_c99807...",
"createdAt": "2026-07-21T14:00:00.000Z",
"updatedAt": "2026-07-21T14:00:00.000Z",
"lastSuccessAt": null,
"lastFailureAt": null,
"disabledAt": null
}