Open app
Moonborn — Developers

Webhook events

The full catalog of webhook event types Moonborn emits. Sixteen real events covering persona lifecycle, generation, billing, marketplace, moderation, and system test pings.

Every Moonborn webhook delivery carries an event of one of the following types. The full list lives in source as WEBHOOK_EVENT_TYPES; this page is the human-readable view.

Persona lifecycle (6)

TypeWhen
persona.createdA new persona finished the generation pipeline.
persona.updatedA persona's mutable metadata changed (slug, visibility, etc.).
persona.deletedPersona soft-deleted (enters 30-day grace).
persona.archivedPersona archived (read-only; lineage preserved).
persona.regeneratedPipeline re-ran from a chosen step.
persona.audit_failedAudit verdict dropped below threshold, OR drift detection alerted on a chat reply.

persona.audit_failed is overloaded — data.reason carries either audit_below_threshold, provocation_test_failed, or voice_drift. Inspect the reason field; the schema is otherwise the same.

Generation pipeline (3)

TypeWhen
generation.run.startedPipeline run kicked off.
generation.run.completedPipeline run finished successfully.
generation.run.failedPipeline run failed terminally (after retries).

These fire on every persona generation, refine, fork. Subscribe to them only if you're tracking pipeline observability — for normal persona lifecycle, the persona.* events are usually enough.

Subscription / billing (3)

TypeWhen
subscription.upgradedPlan moved up a tier (e.g. Pro → Team).
subscription.downgradedPlan moved down a tier.
subscription.cancelledSubscription cancelled (effective end of period).

Marketplace (2)

TypeWhen
marketplace.persona.publishedListing passed moderation; visible publicly.
marketplace.persona.purchasedPaid listing bought (Enterprise commerce).

Moderation (1)

TypeWhen
moderation.flaggedAny moderation stage produced a non-pass verdict (input intent, output content, impersonation, PII).

System (1)

TypeWhen
webhook.endpoint.test_pingFired by POST /v1/webhooks/{id}/ping for connectivity tests.

Wildcard

Subscribe with events: ['*'] to receive every event type. Useful for audit-log archival or generic event streaming; not recommended for production handlers (you'll do if/else over 16+ types).

Envelope shape

Every event ships in the same envelope:

{
  "id": "evt_01H...",
  "type": "persona.audit_failed",
  "occurredAt": "2026-05-16T12:00:00Z",
  "orgId": "org_...",
  "workspaceId": "ws_...",
  "data": { /* type-specific */ }
}

id is unique + idempotent — use it as your dedupe key on retries.

Delivery semantics

  • HMAC-SHA256 signed (X-Moonborn-Signature header).
  • Five retries with exponential backoff (1m → 2m → 5m → 30m → 2h).
  • Dead-letter after five failures; replayable from the dashboard or POST /v1/webhooks/{id}/deliveries/{id}/replay.

See the Webhooks integration for setup + the Webhook signature verification guide for production receivers.

Honest scope

Sixteen event types. No more. We do not emit:

  • Per-message chat events (too high-volume; use SSE streaming on the chat endpoint instead).
  • Per-step pipeline events (use SSE on POST /v1/personas?stream=true).
  • User-action events (no member.invited-style events today).

If you need a type that isn't here, the audit log is the broader record. Webhooks emit the edge-triggered subset that's worth pushing.