post mate · docs

Webhooks

HMAC-signed outbound events, exponential-backoff retries, 30-day delivery log. Wire post mate into your own pipelines.

Webhooks let you subscribe to events on your post mate workspace — when a post publishes, when it fails, when a post is approved — without polling our API. Each delivery is HMAC-SHA256 signed so you can verify it came from us.

Manage webhooks at Settings → API or via the REST API (POST /v1/webhooks).

Event types

EventFires when
post.publishedA post successfully publishes to a network
post.failedA post fails after all retry attempts
post.scheduledA post enters the scheduled queue
post.approvedA pending-approval post is approved
post.changes_requestedA reviewer sends a post back to draft
post.metric_thresholdA post crosses a metric alert threshold

A single post fanning out to four networks generates four separate post.published events — one per platform.

Payload shape

{
  "event": "post.published",
  "timestamp": "2026-06-01T09:00:03.124Z",
  "data": {
    "post_id": "post_01HSXF…",
    "platform": "instagram",
    "external_url": "https://www.instagram.com/p/abc123/"
  }
}

post.metric_threshold example:

{
  "event": "post.metric_threshold",
  "timestamp": "2026-06-07T14:22:00.000Z",
  "data": {
    "alert_id": "uuid…",
    "post_id": "post_01HSXF…",
    "metric": "likes",
    "threshold": 1000,
    "value": 1042
  }
}

Verification

Every request includes:

X-PostMate-Timestamp: 1717228803
X-PostMate-Signature: sha256=2af1b34cf5…
X-PostMate-Event:     post.published
X-PostMate-Delivery:  uuid (idempotency key)

Verify the signature:

import crypto from 'node:crypto';

function verify(rawBody: string, headers: Headers, secret: string): boolean {
  const ts  = headers.get('x-postmate-timestamp')!;
  const sig = headers.get('x-postmate-signature')!.replace('sha256=', '');
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${ts}.${rawBody}`)
    .digest('hex');
  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(sig, 'hex');
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

Also reject requests where |now − timestamp| > 300 seconds to block replays.

Retries

AttemptDelay
1Immediate
21 minute
35 minutes
425 minutes

After 4 failed attempts the delivery is permanently failed. The 30-day delivery log is visible in Settings → API.

Via REST API

You can create and manage webhooks programmatically with a full-scope key:

# Create
curl -X POST https://post-mate.com/api/v1/webhooks \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.example.com/hook",
    "events": ["post.published", "post.failed"]
  }'
# → { "id": "…", "secret": "…" }   (secret shown once)

# List
curl https://post-mate.com/api/v1/webhooks \
  -H "Authorization: Bearer pm_live_…"

# Send test ping
curl -X POST https://post-mate.com/api/v1/webhooks/<id>/test \
  -H "Authorization: Bearer pm_live_…"

# Delete
curl -X DELETE https://post-mate.com/api/v1/webhooks/<id> \
  -H "Authorization: Bearer pm_live_…"

POST /v1/webhooks is idempotent: if a webhook with the same URL and event list already exists it returns the existing record instead of creating a duplicate (used internally by the n8n Trigger node).

Metric alerts

Create a rule that fires post.metric_threshold once when a post crosses an engagement value:

# Fire when any workspace post reaches 1 000 likes
curl -X POST https://post-mate.com/api/v1/metric-alerts \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "metric": "likes", "threshold": 1000 }'

# Scope to one post
curl -X POST https://post-mate.com/api/v1/metric-alerts \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "post_id": "…", "metric": "impressions", "threshold": 5000 }'

Supported metrics: impressions · views · likes · comments · shares · saves · reach

Each rule fires once. Delete and recreate to re-arm it.

Approval events

When approval mode is on, you can approve or reject a pending post via API and receive the matching webhook event in real-time:

# Approve — moves post to scheduled/publishing, emits post.approved
curl -X POST https://post-mate.com/api/v1/posts/<id>/approve \
  -H "Authorization: Bearer pm_live_…"

# Request changes — moves post to draft, emits post.changes_requested
curl -X POST https://post-mate.com/api/v1/posts/<id>/request-changes \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Please shorten the caption." }'

Local development

Use ngrok or Cloudflare Tunnel to expose localhost. Point a post mate webhook at the tunnel URL.

Plan

Webhooks and metric alerts require a Pro plan or active trial.

On this page