EvlPixel
Home › Fanvue API webhooks

Fanvue API webhooks

Notes from building against them: the event catalogue, what the payloads actually contain, and the delivery behaviour that will bite you if you assume otherwise.

Authentication

OAuth 2.0, authorization code with PKCE — mandatory, not optional. Access tokens last about an hour. Refresh tokens rotate and are single use: replaying one after its thirty-second grace window invalidates the entire chain and forces the creator to re-authorise.

Two workers refreshing the same connection concurrently is therefore not a lost update, it is a broken integration. Serialise it.

The event catalogue

The creator.* family supersedes the older flat events and shares one Standard-Webhooks envelope:

{
  "id": "f1a2b3c4-…",
  "type": "creator.subscription.activated",
  "timestamp": "2026-06-09T08:39:33.139Z",
  "data": { "object": "subscription", … }
}

Fields inside data are snake_case, and optional values are omitted rather than sent as null — so reading payload.data.media_uuids.length will throw rather than return zero.

Signature verification

X-Fanvue-Signature: t=<unix>,v0=<hex>

HMAC-SHA256 over {timestamp}.{rawBody}, using the raw bytes. Parsing the JSON and re-serialising it changes those bytes and the signature will not match. Reject anything older than about five minutes, or an old but genuinely signed delivery can be replayed.

Two registration paths exist with different secrets: a per-app secret for webhooks added in the Developer Area, and a fresh per-subscription secret from POST /webhooks/subscriptions — returned once, never readable again.

Delivery guarantees

PropertyBehaviour
DeliveryAt least once. Duplicates are expected
OrderingNot guaranteed
Timeout10 seconds
Retries5, at 30-second intervals
Auto-disableAfter 20 consecutive failures
BackfillNone. Events missed while disabled are gone

Persist and return 2xx immediately, then process asynchronously. Doing the work first risks a timeout, which produces a retry, which produces a duplicate. And acknowledge event types you do not recognise — a 4xx counts as a failure and walks a healthy endpoint towards auto-disable.

Idempotency, with two exceptions

The top-level id is a deterministic hash of the event's identifying inputs, so it is a valid idempotency key almost everywhere. Two topics are exceptions:

Attribution fields

Not populated uniformly, which is easy to get wrong:

That last one shapes every integration built on this API: identity resolution cannot rely on email, so whatever identifier you need later has to be sent out with the visitor and read back from tracking.metadata.

Money

All amounts are integers in the currency's minor units, with a separate ISO 4217 code that may be null. Subscription events carry a price but no currency; the correlated payment event carries both.

Or skip building it

EvlPixel already handles the webhooks, the token rotation and the attribution join.

Start tracking