Webhooks

Flow Retail can send webhooks to your system when specific events occur, allowing you to process updates in real time — for example when an order is settled, a product is updated, or stock changes.

How webhooks are delivered

  • Event triggered → Flow Retail sends an `HTTP POST` request to your registered webhook endpoint.

  • Timeout → If your endpoint does not respond within 10 seconds, we consider it a timeout.

  • Retries → On timeout or `5xx` response, Flow Retail retries the webhook up to 10 times with exponential backoff.

  • No retries on 4xx → Any `4xx` status code (including `429`) marks the webhook as failed and will not be retried.

Status codes — quick reference

Status
When to use
Will retry?

200 OK

Event processed successfully

No

202 Accepted

Event accepted for asynchronous processing

No

400 Bad Request

Invalid payload (validation error, etc.)

No

401/403

Invalid or missing authentication

No

404

Endpoint not found / wrong route

No

429 Too Many Requests

Temporary overload — not ready to receive more calls

No

5xx

Temporary server error

Yes

Timeout > 10s

No response within 10 seconds

Yes

All available webhooks

Below is the full list of webhook action values you can subscribe to.

Action
Description

PRODUCT_CREATE

A new product was created

PRODUCT_UPDATE

An existing product was updated

PRODUCT_DELETE

A product was deleted

CUSTOMER_CREATE

A new customer was created

CUSTOMER_UPDATE

An existing customer was updated

CUSTOMER_DELETE

A customer was deleted

ORDER_SETTLED

A new order was settled (fully paid)

ORDER_RECEIPT_SETTLED

A receipt was settled

ORDER_DELIVERED

An existing order was delivered in full

ORDER_HANDLING_STATE_CHANGED

An order handling state was changed

TILL_CLOSED

A till was counted and closed

TILL_OPEN

A till was opened

PRICE_CREATE

A new price was created

PRICE_UPDATE

A price was updated

PRICE_DELETE

A price was deleted

STOCK_CHANGE

Stock changed for a product in a specific warehouse

PRODUCT_MEDIA_CHANGE

Product media was created, updated, or deleted

PURCHASE_RECEIVED

A purchase order was fully received

Response examples

Flow Retail sends a webhook as an HTTP POST and waits up to 10 seconds for a response.

Your endpoint should return the appropriate HTTP status code depending on whether you successfully received and processed the event.

The table below shows how Flow Retail interprets your response:

Response
Meaning
Retries?

200 OK

Event processed successfully — remove it from the queue

No

202 Accepted

Event accepted for async processing — remove it from the queue

No

Any 4xx

Permanent error (invalid payload, auth error, etc.) — remove it from the queue

No

5xx

Temporary server error — retry later

Yes

Timeout > 10s

No response within 10 seconds — retry later

Yes

200 OK — synchronous processing

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"ok"}

202 Accepted — asynchronous processing

HTTP/1.1 202 Accepted
Content-Type: application/json

{"status":"queued"}

400 Bad Request — do not retry

HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error":"invalid payload format"}

500 Internal Server Error — retry

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error":"temporary failure"}

Example webhook payloads

All payloads are sent as application/json in the request body.

Fields may be added over time — always parse only what you need.

PRODUCT_CREATE

{
  "action": "PRODUCT_CREATE",
  "occurredAt": "2025-08-15T07:32:41Z",
  "attempt": 1,
  "tenant": {
    "id": 7,
    "uid": "7"
  },
  "product": {
    "id": 123,
    "uid": "PRD-123",
    "sku": "KF100",
    "name": "Kos Sweater",
    "active": true
  }
}

ORDER_SETTLED

{
  "action": "ORDER_SETTLED",
  "occurredAt": "2025-08-15T07:34:12Z",
  "attempt": 1,
  "tenant": {
    "id": 7,
    "uid": "7"
  },
  "store": {
    "id": 1,
    "uid": "70"
  },
  "order": {
    "id": 7123,
    "uid": "700",
    "orderNumber": "100045",
    "status": "SETTLED",
    "totals": {
      "gross": 129900,
      "net": 103920,
      "vat": 25980,
      "currency": "NOK"
    }
  }
}

STOCK_CHANGE

{
  "action": "STOCK_CHANGE",
  "occurredAt": "2025-08-15T07:36:05Z",
  "attempt": 1,
  "tenant": {
    "id": 7,
    "uid": "7"
  },
  "warehouse": {
    "id": 12,
    "uid": "WH-01"
  },
  "product": {
    "id": 123,
    "uid": "PRD-123",
    "sku": "KF100"
  },
  "quantityChange": -2,
  "quantityAfter": 8
}

Best practices for webhook receivers

  • Respond fast — Do not do heavy processing inside the webhook handler; enqueue work instead.

  • Idempotency — Make sure your processing logic can handle duplicate events.

  • Logging — Log incoming webhooks for troubleshooting.

  • Security — Verify the request is from Flow Retail (via IP allowlisting or signing).

  • Error handling — Return a 5xx if you want Flow Retail to retry.

Last updated