Delivery & Recovery
How webhook payloads are delivered and retried, and the endpoints to test, monitor, resend and discard them.
How GAINS Connect delivers webhook payloads, what happens when a delivery fails, and the endpoints to test, monitor and recover deliveries. What your endpoint must answer is described in Receiving Webhooks.
Delivery
When a trigger fires, every active configuration that has the trigger enabled, and whose filter a record matches, receives that record. Each configuration sends payloads of up to PayloadMaxItems records of one trigger, waiting PayloadInterval seconds after each successful payload.
Your URL must answer 2xx within 90 seconds, and must tolerate receiving the same record twice. What each answer leads to, timeouts and duplicates are described in Receiving Webhooks.
Retries
A failed payload is tried again after RetryHandling.Gap minutes, up to RetryHandling.Attempts more times: with Attempts set to 3, a payload is tried at most four times. Each try appears in webhook history, numbered from 1 in Attempt.
- Later payloads wait behind a failing one. Until it succeeds or its last try fails, nothing queued behind it is delivered.
- After the last try fails, the payload is dropped from the queue. Find it in webhook history and send it again with resend (see Monitoring and recovery).
Pausing delivery
Set Active to false to stop a configuration delivering. Records already queued stay queued and are delivered when you set it back to true. Events that occur while a configuration is inactive are not delivered to it later.
Disabling a trigger stops new records of that trigger being queued for the configuration. To discard records that are already queued, use reset (see Monitoring and recovery).
Monitoring and recovery
| Task | Endpoint |
|---|---|
| Send a sample payload to a configuration | POST /webhook/test |
| List the webhooks sent | GET /webhook/history |
| Read the payload of one webhook | GET /webhook/{WebhookId}/payload |
| Send a webhook again | POST /webhook/resend |
| See what is waiting in the queue | GET /webhook/status |
| Discard what is waiting in the queue | POST /webhook/reset, then POST /webhook/reset/confirm |
Testing a configuration
POST /webhook/test sends a sample payload of one trigger to a configuration straight away, using its URL, authorization and field naming. The sample holds made-up records, not your data.
{
"Trigger": "POSubmit",
"ConfigurationId": 3
}200means your URL answered2xx:ReasonreadsThe webhook was issued successfully.400means the test failed, with the reason: the status your URL answered, a redirect included, or why no token could be obtained.- The configuration does not need to be active, but it needs a
Url. TaskStatusUpdatecannot be tested.
Each test appears in webhook history like any other delivery.
Webhook history
GET /webhook/history lists the webhooks sent, one entry per try. History is kept for 30 days.
| Parameter | Use |
|---|---|
SearchDateStart, SearchDateEnd | The period, as YYYY-MM-DD HH:MM:SS. Each defaults to the start or end of today. |
Status | success, failed or no_response. All by default. |
Trigger | One trigger or a comma-separated list: POSubmit,TOSubmit. |
TrackingNumber | Webhooks containing this order. |
WithPayload | true to include each payload. |
Cursor, Size | Paging; see Pagination. |
Each entry carries the WebhookId (for reading its payload or resending it), the Status and Attempt, and your URL's HttpStatusCode and Response. When your URL could not answer, HttpStatusCode is a code GAINS Connect recorded; see Troubleshooting. The API Reference describes every field.
To read the payload of a single webhook, call GET /webhook/{WebhookId}/payload. It returns WebhookId and Payload, exactly as sent, or 404 for an unknown WebhookId.
Resending a webhook
POST /webhook/resend queues a webhook to be sent again. Send exactly one of:
WebhookIdto resend a whole payload, taken from webhook history.TrackingNumberto resend one order from a payload already sent. This applies to the order triggers only.
{
"TrackingNumber": 4821
}The response is 202 with Reason The webhook to be resent was successfully added to the queue.
- It goes to the configuration that sent it originally, with that configuration's current URL and authorization.
- It is sent only while the configuration is active.
TaskStatusUpdatewebhooks cannot be resent.- A resend repeats data you may already hold; see Duplicates.
A resend that cannot be done answers 400 with a Reason saying why.
Queue status
GET /webhook/status shows what is waiting to be delivered, in total and per trigger. Ages are in seconds. It needs webhook read access.
{
"QueueSummary": {
"PendingRecords": 240,
"PendingNotifications": 3,
"OldestMessageAge": 1820,
"EstimatedNextPayload": "2026-10-21 10:15:00",
"DataStart": "2026-10-21 09:44:40",
"DataEnd": "2026-10-21 10:13:05"
},
"Triggers": {
"InventoryPolicyUpdate": {
"PendingRecords": 200,
"OldestMessageAge": 610
},
"POSubmit": {
"PendingRecords": 40,
"OldestMessageAge": 1820
}
}
}When you have no configuration, or nothing is waiting, it answers 400 with a Reason saying so (No webhook tasks in the queue.).
Discarding queued payloads
Reset discards records waiting in a configuration's queue so they are never delivered, for example after a mass change you do not want sent. It takes two calls, so it cannot happen by accident, and both need webhook update access:
- Request a token with
POST /webhook/reset, passingConfigurationIdandTriggeras query parameters.Triggertakes one trigger, a comma-separated list, or an empty value (Trigger=) for every trigger. - Confirm with
POST /webhook/reset/confirmwithin 5 minutes.
POST /api/v1/webhook/reset?ConfigurationId=3&Trigger=InventoryPolicyUpdate{
"ResetToken": "5b0e4c1a-93d2-4f7e-8a61-2c9d7e3f1b48",
"Expires": "2026-10-21 10:20:00"
}{
"ResetToken": "5b0e4c1a-93d2-4f7e-8a61-2c9d7e3f1b48"
}The confirmation answers Status success and a Reason giving the number of records discarded. If nothing is queued for those triggers, the first call answers 200 with a Reason saying so instead of a token. An expired or unknown token answers 400; request a new one.
Configuration history
GET /webhook/settings/history lists earlier versions of your configurations, as they were before each change or deletion; secrets read as ******. Results are paged with Cursor and Size, the next cursor being Pagination.NextCursor.
Updated about 7 hours ago
