Signed delivery
Webhooks
Receive bounded platform events, verify the raw payload before parsing it and make processing idempotent.
Verify before processing
Jotify signs the exact raw request body with HMAC-SHA256. Reject missing, malformed, stale or mismatched signatures before deserializing business data.
import { verifyJotifyWebhook } from '@jotify/app-sdk/server';
const valid = verifyJotifyWebhook({
rawBody, signature: request.headers.get('x-jotify-signature'), secret
});
if (!valid) return new Response('Invalid signature', { status: 401 });Delivery rules
Return a 2xx response only after the event is durably accepted. Duplicate event IDs are normal and must not repeat side effects. The event history API returns only deliveries belonging to the authenticated app.
- Store event_id with a unique constraint.
- Process asynchronously after durable acceptance.
- Retry transient failures with bounded backoff.
- Disable endpoints that repeatedly fail and alert the developer.
Registration and verification
Create an exact public HTTPS endpoint, store the one-time signing secret and implement the signed challenge response. Jotify pins a public DNS result for the TLS request, rejects internal addresses and activates the endpoint only when the exact challenge is returned.
POST /api/app-platform/webhooks
POST /api/app-platform/webhooks/verifyOperations
CLI credentials can list only their own endpoints and deliveries, stage a new signing secret and queue a replay of an existing owned delivery. A rotated secret becomes active only after a successful signed ownership challenge; replays create a new delivery ID.
GET /api/app-platform/webhooks
POST /api/app-platform/webhooks/rotate-secret
POST /api/app-platform/webhooks/replayInitial event families
App installation and lifecycle events are the first supported family. Content, commerce, community, event and creator event families remain preview or planned until their privacy and authorization contracts are frozen.
- app.installed
- app.uninstalled
- app.scopes_changed
- app.version_activated

