FansquareAPI reference
Open the app

Receiving webhooks

Webhooks

Fansquare sends a signed POST request to your server when a sale happens, a fan is reassigned or the app asks your AI to step in or out.

Webhooks push events to your servers as they happen, instead of polling the API. Each delivery is an HTTPS POST with a JSON body, signed with a secret only you and Fansquare know.

Webhooks speed your integration up, they do not replace the API. A delivery can arrive late, twice or out of order. Keep reconciling against the list endpoints, which remain the source of truth.

Events

EventSent when
order.createdA new order is recorded for a creator of the agency
order.refundedA recorded order is refunded on MYM
assignment.updatedA fan is assigned to an employee, or unassigned
conversation.ai_control_requestedSomeone in the app asks to relaunch or stop your AI on a conversation
pingYou ask for a test delivery

New event types can be added without a new API version. An endpoint only receives the types it subscribed to, plus the ping test deliveries you request: ping is not a type you subscribe to.

Register an endpoint

Create an endpoint in the app, in Settings › Developer API › Webhooks, or with POST /v1/webhooks. You choose:

  • the URL, in HTTPS, on a public host;

  • the event types it receives;

  • the creators it covers: all of them, or a selection. With a key limited to some creators, an endpoint covers the creators of the key at most.

Only the URL itself is checked at creation, its hostname is not resolved. A hostname that resolves to a private address is accepted, then every delivery to it fails.

The response holds the signing secret of the endpoint, fsq_whsec_ followed by 32 characters. It is shown once: store it with your other secrets. You can rotate it at any time.

An agency can register up to 10 endpoints. An endpoint is pinned to an API version at its creation, the Fansquare-Version of the creating request (the current version when you create it in the app): its payloads keep that shape.

A new endpoint, or one that you re-enable or that subscribes to more event types or creators, can take up to a minute to receive every event: an event in that minute may not reach it.

The delivery

Every delivery carries the same envelope. data depends on the event type.

JSON
{
  "id": "0199c7a2-5d4e-7b3a-9f1e-2c8d6b4a1e07",
  "type": "assignment.updated",
  "created_at": "2026-10-12T21:14:00.000Z",
  "api_version": "2026-07-06",
  "data": {
    "account_id": "a8c4e2f0-3b5d-4c7e-9f1a-2b4c6d8e0f13",
    "fan_id": "5d0e6a2c-7f1b-4c3e-8a9d-0b2c4e6f8a1d",
    "assigned_user_id": "3b9f1d7a-2c4e-4a6b-8d0f-1e3a5c7e9b2d"
  }
}
FieldMeaning
idEvent id. The same for every endpoint, retry and replay of this event: deduplicate on it.
typeEvent type.
created_atWhen the fact occurred, not when the delivery was sent. Each event page says which instant it is.
api_versionRelease date of the version the payload is rendered in.
dataThe event itself.

The request also carries these headers.

HeaderValue
Fansquare-Signaturev1= and the HMAC-SHA256 of the delivery, see Verify signatures
Fansquare-Signature-TimestampUnix time in seconds at which this attempt was signed
Fansquare-Event-TypeThe type of the body
Fansquare-Event-IdThe id of the body
Fansquare-Delivery-IdId of this delivery to this endpoint
User-AgentOffmy-Webhooks/1.0

Respond quickly

Answer with any 2xx status within 10 seconds. Anything else counts as a failure: another status, a timeout, a connection error, or a redirect (redirects are not followed).

Acknowledge first, work later: store the event, answer 200, then process it in the background.

Retries

A failed delivery is retried three times, 10 seconds, 1 minute and 5 minutes after the previous attempt: four attempts in all. Each attempt is signed again, with a fresh timestamp.

Since a delivery can arrive more than once, make your handler idempotent: keep the event ids you processed and skip those you already know. Deliveries are not ordered: compare created_at if order matters to you.

Failures and replay

After the last attempt, the delivery is recorded as a failure, kept 30 days. List them with GET /v1/webhooks/{endpoint_id}/failures or in the app, then replay them once your server is fixed. A replay sends the original event again, with the same id.

After 10 failed deliveries in a row (each one after its four attempts), Fansquare disables the endpoint to stop hammering a broken server: its status becomes disabled, with disabled_reason set to auto_breaker. Failures recorded in the same batch count as one, and any successful delivery resets the count. Fix your server, then re-enable the endpoint with PATCH /v1/webhooks/{endpoint_id} and "status": "active".

While an endpoint is disabled, by you or after failures:

  • deliveries still pending go to its failures, with the error endpoint_disabled, ready to replay;

  • events that occur are not sent to it and not recorded: reconcile them with the list endpoints;

  • a replay is accepted, but goes straight back to the failures until you re-enable it.

Test your endpoint

POST /v1/webhooks/{endpoint_id}/ping sends a ping event to that endpoint, through the same pipeline as real events: same signature, same headers. Use it to check your signature verification before going live. GET /v1/webhooks/{endpoint_id}/stats gives the number of delivered and failed deliveries per event type over a window, the last 7 days by default. Counters are kept 90 days.