Webhooks
Receba um POST assinado quando um post é agendado ou termina, verifique a assinatura, trate as novas tentativas e consulte o histórico de entregas.
Em vez de consultar GET /v1/posts/:id em laço, cadastre uma URL e a Postmatic avisa.
Eventos
| Evento | Quando |
|---|---|
post.scheduled | Um agendamento foi aceito (POST /v1/posts com scheduledFor, ou retry agendado). |
post.published | Todos os destinos publicaram. |
post.partial | Pelo menos um destino publicou e pelo menos um falhou. |
post.failed | Todos os destinos falharam (inclusive agendamento perdido, MISSED). |
Um post agendado emite post.scheduled e depois um evento final. Um post imediato emite só o final. Cancelar pela API não emite nada. Um POST /v1/posts/:id/retry gera um novo evento final quando terminar.
Cadastrar
curl -X POST https://api.uat.postmatic.dev/v1/notifications \
-H "x-access-key: pm_live_…" \
-H "content-type: application/json" \
-d '{ "eventTypes": ["post.published", "post.partial", "post.failed"], "webhook": { "url": "https://seu-app.com/hooks/postmatic" } }'A resposta traz webhook.secret (whsec_…) uma única vez. Guarde-o. profileId restringe aos posts de um profile; onlyScheduledPosts: true manda eventos finais só de posts que foram agendados.
Teste o destino antes ou depois de salvar com POST /v1/notifications/test ({ "notificationId": "ntf_…" } ou { "webhook": { "url": "…" } }).
Verificar a assinatura
Cada entrega é um POST com Content-Type: application/json e estes headers:
| Header | Valor |
|---|---|
X-Postmatic-Event-Id | Id do evento (evt_…). Use como chave de deduplicação. |
X-Postmatic-Event-Type | Ex.: post.published. |
X-Postmatic-Timestamp | Unix timestamp em segundos. |
X-Postmatic-Signature | sha256= + HMAC-SHA256 hex de <timestamp>.<corpo cru>. |
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(secret: string, headers: Record<string, string>, rawBody: string): boolean {
const ts = headers['x-postmatic-timestamp'];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // 5 min de tolerância
const expected = `sha256=${createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex')}`;
const given = headers['x-postmatic-signature'] ?? '';
return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}Assine sobre o corpo cru (não reserialize o JSON). Responda 2xx em menos de 10 segundos e processe depois.
Payload
{
"version": "2026-09-01",
"id": "evt_…",
"type": "post.published",
"createdAt": "2026-09-09T12:00:00.000Z",
"projectId": "proj_…",
"profileId": null,
"data": {
"post": {
"id": "post_…", "status": "published", "content": "Novidade no ar.",
"scheduledFor": null, "publishedAt": "2026-09-09T12:00:00.000Z",
"mediaItems": [{ "type": "image", "url": "https://…/foto.jpg" }],
"links": { "api": "https://api.uat.postmatic.dev/v1/posts/post_…" }
},
"platforms": [{
"platform": "instagram", "integrationId": "int_…", "profileId": null,
"status": "published", "platformPostId": "1790…", "platformPostUrl": "https://www.instagram.com/p/…/",
"publishedAt": "2026-09-09T12:00:00.000Z", "errorCode": null, "errorMessage": null, "warningMessage": null
}]
}
}Novas tentativas
Sem 2xx em 10 segundos, a Postmatic tenta de novo depois de 30 s e de 2 min (3 tentativas no total), com o mesmo corpo e o mesmo id. Depois disso a entrega fica failed no histórico. Duplicatas são possíveis: deduplique pelo id.
Histórico
GET /v1/notifications/:id/deliveries lista cada evento entregue à assinatura, com status (pending, delivered, failed), attempt, responseStatus e error.