Webhooks¶
Subscribe a URL to receive HMAC-signed event deliveries when things happen on your account. Manage subscriptions with the manage:webhooks scope via /api/v1/webhooks.
curl -X POST https://rmhstudios.com/api/v1/webhooks \
-H "Authorization: Bearer $RMH_KEY" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/hook","events":["post.created","follow.created"]}'
# → 201 { "id": "wh_…", "secret": "whsec_…", ... } (secret shown once)
Subscribe to ["*"] to receive every event.
Events¶
Event |
Fires when |
|---|---|
|
You created a post (via the API or in-app). |
|
One of your posts was deleted. |
|
You followed another user. |
|
You unfollowed a user. |
|
You liked a post. |
|
You commented on a post. |
|
You bookmarked a post. |
Delivery¶
Each event is delivered as a POST with a JSON body:
{
"id": "<deliveryId>",
"event": "post.created",
"created": "2026-06-30T10:00:00.000Z",
"data": { "postId": "ck_…" }
}
and these headers:
Header |
Meaning |
|---|---|
|
The event name. |
|
Unique delivery id. |
|
Unix seconds when the request was signed. |
|
|
A delivery succeeds on any 2xx. Failures retry with exponential backoff (up to 6 attempts); an endpoint that keeps failing is auto-disabled. Inspect recent attempts with GET /api/v1/webhooks/{id}.
Deliveries are at-least-once: a timeout on our side after your handler committed will be retried. Use the id field to de-duplicate.
Verifying signatures¶
The signature is HMAC-SHA256 of ${timestamp}.${rawBody} keyed by your endpoint secret, hex-encoded:
import { createHmac, timingSafeEqual } from 'crypto';
function verify(secret, header, rawBody, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')));
const t = Number(parts.t);
if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // replay guard
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const a = Buffer.from(expected),
b = Buffer.from(parts.v1);
return a.length === b.length && timingSafeEqual(a, b);
}
Warning
Verify the signature and the timestamp tolerance before trusting a payload, and compute the HMAC over the raw request body — not over a re-serialised parsed object, whose byte-for-byte output will differ and fail to match.