Skip to main content
Webhooks push events to your server as they happen in Fluid — an order is placed, a cart changes, a member is created — so you never have to poll for updates. You register an HTTPS endpoint once, and Fluid delivers a JSON payload to it every time a matching event fires. This guide covers registering a webhook, managing it, verifying and handling deliveries, and inspecting the most recent delivered event for a resource.

Base URL and authentication

Webhook management lives on the company surface. Call it against https://api.fluid.app and send a company Bearer token on every request as Authorization: Bearer <your_token>. Unlike the versioned storefront and checkout surfaces, the webhook paths are unversioned: subscriptions sit under /api/company/webhooks and the payload schemas under /api/webhooks/schemas.
Every operation in this guide requires a company Bearer token. In production your delivery url must be HTTPS, and Fluid does not deliver to internal or private (non-public) hosts, so your endpoint must be publicly reachable.

Register a webhook

Create a subscription with POST /api/company/webhooks. A subscription needs three things: the resource to watch, the event on that resource, and the url Fluid delivers to. You can also set active, the http_method Fluid uses to deliver, and an auth_token — a shared secret you use to verify deliveries.
A successful create returns 201 with the new subscription under a webhook key; a body that fails validation returns 422. The response echoes the webhook’s integer id, the fields you set, and an event_identifier — the identifier Fluid uses for this event’s payload schema.
Discover what you can subscribe to before you register. GET /api/company/webhooks/resources lists the resources and the events available on each.

List, inspect, update, and delete

List your subscriptions with GET /api/company/webhooks, and fetch one by its numeric id with GET /api/company/webhooks/{id}:
Update a subscription with PUT /api/company/webhooks/{id}. The update body accepts url, active, auth_token, and http_method; it does not accept resource or event. To retarget a subscription at a different resource or event, delete it and create a new one.
Delete a subscription with DELETE /api/company/webhooks/{id}. A successful delete returns 200 and echoes the deleted webhook’s id:

The delivery envelope

Every delivery is a JSON envelope with a small, stable outer shape. The event data rides inside payload.
integer
The delivery’s identifier — a number, not a prefixed string.
string
A generated token for this specific delivery.
string
The event identifier, matching what you registered.
string
An ISO 8601 timestamp for when the event occurred.
object
The event data, keyed by the resource’s name, plus metadata about the event.
Inside payload, the event data is keyed by the resource’s own name — an order delivery carries an order object, a cart delivery a cart object, a member delivery a member object. There is no generic data wrapper. Alongside the resource, payload carries metadata about the event: event_name, schema_version, schema_hash, company_id, resource_name, resource, and event.
Read the resource data from the key named for the resource in lowercase — payload.order, payload.cart, or payload.member. The separate resource_name metadata field is an internal type identifier and may be namespaced, so don’t use it to index the payload.

Verify a delivery

Set auth_token to a long, random secret when you register a webhook. Fluid uses it to sign every delivery. Each delivery carries these headers:
  • X-Fluid-Signature — a hex HMAC-SHA256 of the request, keyed with your auth_token.
  • X-Fluid-Timestamp — the Unix time in seconds when Fluid signed the request.
  • X-Fluid-Token and AUTH_TOKEN — your raw auth_token.
  • X-Fluid-Shop — your shop identifier.
Verify the signature: recompute a hex HMAC-SHA256, keyed with your auth_token, over the string <X-Fluid-Timestamp>.<raw_request_body>, then constant-time compare it to X-Fluid-Signature. Sign over the raw request body exactly as received; if you re-serialize the parsed JSON the bytes can change and the signature will not match.
If you don’t verify the signature, the simpler alternative is to compare the X-Fluid-Token (or AUTH_TOKEN) header against your stored secret with a constant-time comparison. The signature is more robust because it also binds the timestamp and the exact body. Use at least 32 random characters for the secret, and rotate it periodically — send a new auth_token to the update endpoint, then update the value your handler verifies against.

Handle and respond

Acknowledge every delivery quickly with a 2xx status. Parse the envelope, enqueue the work, and return 200 right away rather than doing slow processing inline:
Make your handler idempotent: key on the envelope’s integer id so that reprocessing the same event is a safe no-op.

Inspect the most recent delivery

To confirm what Fluid last sent for a resource, call GET /api/company/webhooks/resources/{resource_name}. It returns the most recent delivered event for that resource as the same envelope you receive at your endpoint:
Pass a resource that your company has actually registered. An unregistered or unknown resource_name returns 404 with a { "message": ..., "status": ... } body, not an empty response.

Introspect payload schemas

Each event publishes a JSON schema for its payload. List the schemas with GET /api/webhooks/schemas, optionally narrowing to one event with the event_identifier query parameter, and fetch a single schema with GET /api/webhooks/schemas/{event_identifier}:
Use these schemas to generate types or validate payloads when you build a handler. Webhooks push events to you. Two adjacent surfaces are documented in the API reference: callback registrations (/api/callback/registrations), which let Fluid call you synchronously for tax or shipping decisions, and company events (/api/company/events), the company calendar surfaced to members. Both use the same company Bearer token.

Next steps

  • Browse the Create a webhook endpoint reference for full request and response schemas.
  • Register a subscription, then use the inspect endpoint to confirm your first delivery.