Pengine Store API
Webhooks

Delivery and retries

What counts as success, when we retry, and what the logs record.

The request we send

POST /your-endpoint HTTP/1.1
Content-Type: application/json
User-Agent: Pengine-Webhooks
X-Pengine-Signature: sha256=6f2d1c8b4a09e73f5d2b8c1a0e94f7b3...
PropertyValue
MethodPOST, always.
BodyThe event JSON. See Events.
Timeout10 seconds, from connection to last byte.
RedirectsNot followed. A 301 or 302 is a failed delivery.

Your URL

Set one URL per event in your store's API settings in the Pengine app. The rules are checked when you save it and again before every delivery:

  • HTTPS only.
  • No credentials in the URL.
  • The hostname must resolve to a public address. Private ranges and loopback are refused, so localhost and 10.x receivers cannot be reached. Use a tunnel while you develop.

Changing the URL takes effect immediately. Removing it stops delivery, including for events already queued and waiting on a retry.

Success and failure

Any 2xx response is successful. Pengine retries other status codes, timeouts, redirects, TLS errors, and DNS failures.

Answer fast, work later

The ten-second timeout covers the entire response. Store the event, return 200, and process it asynchronously.

Retries

Five attempts in total, with exponential backoff starting at ten minutes.

AttemptSent
1Immediately
2~10 minutes after the first failure
3~20 minutes later
4~40 minutes later
5~80 minutes later

After the fifth failure, Pengine stops retrying the event. The schedule spans about two and a half hours. If your endpoint misses events, recover by listing recently updated resources: GET /stores/:storeId/orders?sort[updatedAt]=desc.

Test deliveries sent from the app are never retried. They are one attempt, so you see the real result.

Ordering and duplicates

Delivery order is not guaranteed. Retries and concurrent events can deliver an older event after a newer one. An event can also repeat if Pengine does not receive your 2xx response.

Deduplicate on the event id, which remains stable across retries, and fetch the resource to get its current state.

What we record

Every attempt is logged for 14 days, and you can read it in your store's API settings:

FieldWhat it holds
EventThe topic, event ID, and resource ID
AttemptWhich of the five this was
OutcomeYour status code, or the transport error if we never got one
DurationHow long you took to answer
ResponseThe first kilobyte of your response body

If your framework returns an HTML error page, the log stores its first kilobyte to help diagnose the failure.

On this page