Sale webhook events (beta)

The new sale.* event family delivers full sale payloads inline. Understand what's available, how they differ from the legacy sales.* events, and how to get access.

🚧

Closed beta

The sale.* event family is currently in closed beta. The event schemas are published and stable, but webhook delivery is gated. To subscribe, email [email protected].

📘

API-ingested sales only

Both the sales.* and sale.* event families only fire for sales created through the Sales Management API (POST /salesManagement/orgs/{orgId}/sales). Sales recorded natively on the Flipdish POS, kiosk, web app, or third-party marketplaces (UberEats, JustEats, etc.) do not currently trigger these events. This matches the existing read-path scope described in the analytics guide.

Overview

Flipdish exposes two families of sale-related webhook events. Both are scoped to API-ingested sales; they differ in what they carry and what they're designed for.

FamilyEventsPayloadStatus
sales.* (legacy)sales.created.v1, sales.cancelled.v1, sales.pos.status.updated.v1, sales.delivery.status.updated.v1Identifiers only — orgId, propertyId, salesChannelId, saleIdGenerally available
sale.* (new)sale.created.v1, sale.updated.v1, sale.status.updated.v1Full sale payload inlineClosed beta

The sales.* events (legacy, generally available)

These events fire for every sale lifecycle transition and carry just enough context to identify the sale and look it up:

EventWhen it firesKey fields beyond IDs
sales.created.v1A new sale is recorded
sales.cancelled.v1A sale is voidedcancellationReason, cancellationNotes, cancelledBy
sales.pos.status.updated.v1POS / kitchen state changestatus (SALE_PREPARED_BY_KITCHEN, SALE_PICKUP_TIME_CHANGED, SALE_DELIVERY_TIME_CHANGED, SALE_CANCELLED)
sales.delivery.status.updated.v1Delivery state changestatus (SALE_DISPATCHED, SALE_ON_THE_WAY, SALE_DELIVERED)

Because the payload carries identifiers only, your handler must call the Sales Management APIGET /salesManagement/orgs/{orgId}/salesChannels/{salesChannelId}/sales/{saleId} — to fetch the line items, charges, discounts, and payments.

Use these events when you need broad availability today, or when you already have a read-path built against the Sales Management API.


The sale.* events (new, closed beta)

The sale.* family was designed to eliminate the follow-up API call: the full sale object is embedded in the event payload itself.

Events

sale.created.v1

Fires when a sale is first recorded. The detail.properties.sale field carries the complete PublicSale object at the moment of creation: items, modifiers, charges, discounts, payments, customer, delivery/dine-in details, and menu reference.

{
  "source": "rms",
  "detail-type": "sale.created.v1",
  "detail": {
    "properties": {
      "orgId": "org123",
      "brandId": "br123",
      "propertyId": "p123",
      "salesChannelId": "sc123",
      "salesChannelType": "UberEats",
      "saleId": "3N356",
      "externalId": "sale-external-123",
      "sale": {
        "salesChannelId": "sc123",
        "source": "App",
        "dispatchType": "Delivery",
        "menuId": "123e4567-e89b-12d3-a456-426614174000",
        "menuRevisionId": "123",
        "items": [ ... ],
        "charges": [ ... ],
        "discounts": [ ... ],
        "payments": [ ... ]
      }
    },
    "metadata": { ... }
  }
}

sale.updated.v1

Fires when a sale's content changes materially — items added or removed, charges or discounts modified. The embedded sale reflects the post-update state. There is no equivalent event in the sales.* family: previously you had to poll or reconcile to detect updates.

sale.status.updated.v1

A unified status event that covers both POS kitchen states and delivery states in a single discriminated union. It replaces the two separate sales.pos.status.updated.v1 and sales.delivery.status.updated.v1 events.

Status values: SALE_CANCELLED, SALE_PREPARED_BY_KITCHEN, SALE_DISPATCHED, SALE_ON_THE_WAY, SALE_DELIVERED.


Key differences at a glance

sales.* (legacy)sale.* (new)
ScopeAPI-ingested sales onlyAPI-ingested sales only
PayloadIdentifiers onlyFull PublicSale object inline
Follow-up API call neededYes, to hydrate items/charges/paymentsNo
Sale update eventNonesale.updated.v1
Status eventsTwo separate eventsOne unified sale.status.updated.v1
Includes brandIdNoYes
AvailabilityGenerally availableClosed beta

When to use which family

Use sales.* if you're building against the Sales Management API read path already, or need to go live before the sale.* beta opens.

Use sale.* if you want a simpler handler that processes the full sale from the event payload without a round-trip, or if you need sale.updated.v1 to track mid-lifecycle changes.

The sales.* events will be deprecated when sale.* reaches general availability. They will remain available until all subscribers have migrated, but new integrations should prefer sale.*.


Getting access to sale.* events

The sale.* events are in closed beta. Webhook delivery is gated and not available through the self-serve Portal subscription UI.

To subscribe:

  1. Build and test against your sandbox org using the sales.* events, which are freely available.
  2. Email [email protected] with your orgId, the events you want (sale.created.v1, sale.updated.v1, sale.status.updated.v1), and a brief description of your use case.
  3. The integrations team will provision access and confirm your subscription endpoint.

Related