Skip to main content
Naasher Documentation

Webhooks

Receive signed Naasher events, verify HMAC over the raw body, and process deliveries safely.

Naasher sends signed events to registered HTTPS destinations so an authorized system can react to recorded state changes. Webhooks are available on the Teams and Agency plans.

Register an endpoint

Create a registration under Settings → Developers → Webhooks, or use the REST API:

curl -X POST https://api.naasher.com/api/sdk/v1/webhooks \
  -H "x-naasher-api-key: $NAASHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/hooks/naasher", "events": ["post.published", "post.failed"] }'

The signing secret is shown once. Store it in a secret manager, separate production and test endpoints, and rotate it after exposure or ownership changes.

Event catalog

EventRecorded transition
post.createdA post record was created
post.scheduledA post was scheduled
post.publishingProvider publishing began
post.publishedA provider target reported success
post.failedA provider target reported failure
post.deletedA post record was deleted
channel.connectedA social account was connected
channel.disconnectedA social account was disconnected
channel.token_expiringA provider grant is approaching expiry
channel.token_expiredReconnection is required
inbox.comment_receivedA supported comment arrived
report.weeklyThe weekly report is ready
queue.lowA recurring publishing queue is nearly empty
webhook.testA manual delivery test was requested

An event reports Naasher's recorded transition. For a critical external action, retain the target identifier and reconcile the provider-visible result as well.

Verify the signature

Naasher-Signature contains a Unix timestamp and HMAC value:

t=1752163200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Compute HMAC-SHA256 over "{timestamp}.{raw_body}", compare in constant time, and reject stale timestamps. A five-minute window is a reasonable starting policy for many systems, but choose one that matches the controlled queue and clock guarantees.

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyNaasherWebhook(rawBody: string, header: string, secret: string) {
  const parts = Object.fromEntries(header.split(',').map((part) => part.split('=')));
  const timestamp = Number(parts.t);
  if (!Number.isFinite(timestamp) || Math.abs(Date.now() / 1000 - timestamp) > 300) {
    return false;
  }
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
  const given = Buffer.from(parts.v1 ?? '', 'hex');
  const want = Buffer.from(expected, 'hex');
  return given.length === want.length && timingSafeEqual(given, want);
}

Verify the raw request body

Calculate the signature before parsing or re-serializing JSON. Reordered keys or normalized whitespace change the signed bytes.

Delivery and retries

Return 2xx quickly after durable receipt, then process asynchronously. Naasher retries transient network and 5xx failures with increasing delay. Your consumer must deduplicate repeated event deliveries and must not turn a duplicate delivery into a repeated publish or customer notification.

Use the REST API to fetch current state when an event is late or missing, and keep secrets and raw customer content out of public delivery logs.