Configuring Webhooks
Create, change, pause and delete webhook configurations: destination, authorization, triggers, batching, secrets and configuration history.
A webhook configuration names a destination URL, how to authenticate to it, which triggers it reports, and how it batches and retries. Create one or more with POST /webhook/settings. The body is an array, and every element becomes a new configuration:
POST /api/v1/webhook/settings
Content-Type: application/json[
{
"Name": "ERP orders",
"Active": true,
"Authorization": {
"Basic": {
"Username": "gains-webhooks",
"Password": "Vq7#pL2m-Xr9"
}
},
"Url": "https://erp.example.com/gains/webhooks",
"PayloadMaxItems": 100,
"PayloadInterval": 60,
"Triggers": {
"POSubmit": {
"Enabled": true,
"Filter": "ReceivingLocation IN ('CHI01', 'DAL02')"
},
"TOSubmit": {
"Enabled": true
},
"TaskStatusUpdate": {
"Enabled": true,
"Filter": "Status IN ('Completed', 'Failed', 'RejectedFailedProcessing')"
}
},
"RetryHandling": {
"Attempts": 3,
"Gap": 10
},
"FieldNamingConvention": "PASCAL_CASE"
}
]The response returns each new configuration with the Id you use to change it later. Secrets are masked:
{
"Status": "success",
"Reason": "New webhook(s) configured. Any updates to a webhook configuration should use the PUT method.",
"TotalConfigurations": 1,
"NewConfigurations": [
{
"Id": 3,
"Name": "ERP orders",
"Active": true,
"Authorization": {
"Basic": {
"Username": "gains-webhooks",
"Password": "******"
}
},
"Url": "https://erp.example.com/gains/webhooks",
"PayloadMaxItems": 100,
"PayloadInterval": 60,
"Triggers": {
"POSubmit": {
"Enabled": true,
"Filter": "ReceivingLocation IN ('CHI01', 'DAL02')"
},
"TOSubmit": {
"Enabled": true,
"Filter": null
},
"TaskStatusUpdate": {
"Enabled": true,
"Filter": "Status IN ('Completed', 'Failed', 'RejectedFailedProcessing')"
}
},
"RetryHandling": {
"Attempts": 3,
"Gap": 10
},
"ConfigurationMode": "v2",
"PreferencesUpdated": "2026-10-21 09:42:17",
"FieldNamingConvention": "PASCAL_CASE"
}
]
}When a request enables InventoryPolicyUpdate, ForecastWeeklyUpdate or ForecastMonthlyUpdate for the first time, Reason adds that notifications for the trigger may take up to 15 minutes to begin.
Managing configurations
| Task | Endpoint |
|---|---|
List every configuration (204 when there is none) | GET /webhook/settings |
| Add configurations | POST /webhook/settings |
| Replace one configuration | PUT /webhook/settings/{ConfigurationId} |
| Change some settings of one configuration | PATCH /webhook/settings/{ConfigurationId} |
| Delete one configuration | DELETE /webhook/settings/{ConfigurationId} |
| See earlier versions of your configurations | GET /webhook/settings/history |
POST always adds configurations; it never changes an existing one.
PUTreplaces the whole configuration. A setting you leave out takes its default, exceptFieldNamingConvention, which keeps its current value;Triggersleft out means no triggers, andAuthorizationleft out removes authorization. Send every secret again.PATCHchanges only what you send. Everything you omit keeps its stored value, secrets included, so you can change a URL or a trigger without resending credentials.TriggersandRetryHandlingare replaced as a whole when present, so send every trigger you want to keep.
Settings
| Setting | What it controls |
|---|---|
Name | Your own label, so you can tell configurations apart. |
Active | Whether payloads are delivered; see Pausing a configuration. An active configuration needs a Url and at least one enabled trigger. |
Url | The destination; see Destination URL. |
Authorization | How GAINS Connect authenticates to your URL; see Authorization. |
PayloadMaxItems | The most records in one payload. |
PayloadInterval | How long to wait after a successful payload before sending the next. |
RetryHandling | How many times, and how far apart, a failed delivery is tried again; see Retries. |
FieldNamingConvention | Whether the payloads you receive use PascalCase field names (ItemCode) or camelCase (itemCode); see Webhook Payload Samples. |
Triggers | Which events are sent, each with an optional filter; see Webhook Filters. |
The API Reference for POST /webhook/settings gives each setting's type, limits and default.
What PayloadMaxItems counts depends on the trigger: orders for the order triggers, SKU-locations for the inventory policy and forecast triggers, and task status changes for TaskStatusUpdate.
Pausing a configuration
Set Active to false with PATCH to stop a configuration delivering:
{
"Active": false
}- Records already queued stay queued and are delivered when you set
Activeback totrue, unless they have waited too long; see Delivery. - 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. Records already queued are still delivered; to discard them, see Discarding queued payloads.
Authorization
Authorization takes exactly one of four schemes, or {} for none.
| Scheme | What GAINS Connect sends | Use it when |
|---|---|---|
Header | Value as the Authorization header, exactly as given | Your endpoint accepts a fixed API key or a token that does not expire. |
Basic | HTTP Basic authentication built from Username and Password | Your endpoint accepts HTTP Basic authentication. |
OAuth2ClientCredentials | An access token it obtains from your identity provider with a client ID and secret | Your identity provider issues tokens to clients with a secret. |
OAuth2PrivateKeyJwt | An access token it obtains by signing a JWT client assertion with your private key | Your identity provider authenticates clients by certificate instead of a secret. |
Header and Basic send the same credential with every delivery, so you rotate it yourself. The OAuth 2.0 schemes send a short-lived token that GAINS Connect renews before it expires; OAuth 2.0 Webhook Destinations explains how tokens are obtained and gives examples for Microsoft Entra ID and Oracle NetSuite. The API Reference for POST /webhook/settings lists the fields of each scheme.
In a PATCH, naming the same scheme changes only the fields you send. Naming a different scheme replaces the old one, so send everything the new scheme needs; {} removes authorization.
Secrets
Secrets (Value, Password, ClientSecret, PrivateKey) are stored encrypted and never returned:
- A read shows each secret as
******. Sending******back is refused, so usePATCHand leave the secret out to keep it. - To change a secret, send only the new one with
PATCH, under the same scheme.
A secret reads ******(re-enter)
******(re-enter)When GET /webhook/settings shows a secret as ******(re-enter) instead of ******, the stored secret can no longer be used. Every delivery for that configuration then fails without reaching your URL, and webhook history records it with status code 502 and this Response:
{
"error": "credential_must_be_re_entered",
"errorDescription": "The stored credential for this webhook can no longer be decrypted and must be re-entered."
}Send the secret again with PATCH /webhook/settings/{ConfigurationId}, naming the same scheme and only the secret:
{
"Authorization": {
"Basic": {
"Password": "Vq7#pL2m-Xr9"
}
}
}A PATCH that leaves Authorization out still works while a secret needs re-entering, so you can change other settings first.
Destination URL
Use an https address that can be reached from the internet, and point Url at the final address: redirects are not followed. Put credentials in Authorization, never in the URL. What your endpoint must do is described in Receiving Webhooks.
Multiple configurations
You can have several configurations, each with its own URL, authorization, triggers, filters and batching. Use them to send the same event to more than one system, or to split one trigger's records between destinations with filters. For example, two configurations that both enable InventoryPolicyUpdate, one with the filter LocationCode IN ('CHI01', 'DAL02') and the other with LocationCode NOT IN ('CHI01', 'DAL02'), divide the policy changes between two systems.
Configurations deliver independently: a destination that is down delays only its own payloads.
Configuration history
GET /webhook/settings/history lists earlier versions of your configurations, as they were before each change or deletion, with CreatedAt and ReplacedAt saying when each version applied. Secrets read as ******. It answers 204 when there is no history.
The history is paged with Cursor and Size: pass Pagination.NextCursor from one page as Cursor to read the next. See Pagination.
Errors
The webhook endpoints (settings, history, test, resend, status and reset) answer these statuses of their own:
| Status | When |
|---|---|
400 Bad Request | A setting or filter is invalid, a test failed, or a resend, status request or reset could not be done. Reason explains which; several validation errors come back together in Reasons. |
403 Forbidden | Your credentials do not include webhook access: read access to list configurations, history and queue status, update access to change configurations, test, resend or reset. |
404 Not Found | No configuration, or no webhook, with the Id in the path. |
For 401, the other statuses and the error body, see Errors & Retries.
Related
- Webhooks: the triggers and their
DataType - OAuth 2.0 Webhook Destinations: token-based authorization
- Webhook Filters: send only the records you want
- Receiving Webhooks: what your endpoint receives and must answer
- Delivery & Recovery: retries, history and resending
Updated 8 days ago
