Outbound Overview: Pull or Push
Every outbound endpoint, which subjects also arrive by webhook, and when to read an endpoint, use a webhook, or combine both.
GAINS Connect gives you two ways to take data out of GAINS: you read it from an endpoint when you choose (pull), or GAINS sends it to your URL by webhook when something happens (push). This page lists every outbound endpoint, says which subjects you can also receive by webhook, and helps you decide which to use. It also covers demand history, order requisitions and master data, which have no guide of their own.
Pull or push
| Read an endpoint (pull) | Webhook (push) | |
|---|---|---|
| What you receive | Everything GAINS currently holds that matches your filters | Orders as they are submitted; policies and forecasts that changed |
| When | Whenever you call | Shortly after the event, in batches |
| Subjects | Every subject on this page | Replenishment orders, inventory policies, weekly and monthly forecasts |
| Narrowing what you receive | Query parameters on each request | A filter on each trigger |
| If you miss something | Read it again | Retries, then resend from webhook history |
When to read an endpoint
- You need the full current state, for example a first load, or a nightly copy of every inventory policy.
- You want to reconcile what you hold against what GAINS holds.
- The subject has no webhook: demand history, requisitions, service levels, the aggregate forecast, bills of material, supercessions, master data and lead-time prediction.
An endpoint does not track changes. None of them can return only the records that changed since a given time, and none remembers what you have already read: each call returns everything that matches your filters. The date filters that exist select on business dates, not on when a record changed.
When to use a webhook
- You want to act on events as they happen: a submitted order, a changed policy or forecast.
- You want only what changed. The policy and forecast triggers send a SKU-location only when GAINS detects that it has changed.
- You want to route data. A trigger filter, for example
ReceivingLocation IN ('CHI01', 'DAL02'), sends each destination only the records it needs.
See Webhooks for setting up destinations, filters, retries and resending.
Using both
Where a subject has a webhook, use both channels together:
- Load once from the endpoint. Read every page of the subject to start from the full current state.
- Keep up to date from the webhook. Process each delivery as it arrives. Deliveries can repeat, so make processing a record twice harmless: key orders on
TrackingNumber, and policies and forecasts onItemCodeandLocationCode. - Reconcile on a schedule. Read the endpoint again, for example daily, and compare. This catches anything a delivery missed, such as a payload dropped after its last retry. For orders, you can also re-read a single order with
TrackingNumber.
Outbound endpoints
Every endpoint below returns DataType, Data and Paging, and takes Size and Cursor; see Pagination. A webhook delivery carries the same DataType and Data, without Paging. Filters that take a list accept up to 10 comma-separated values, and different filters combine with AND.
Replenishment orders and requisitions
| Endpoint | Returns | DataType | Webhook trigger | Extended data |
|---|---|---|---|---|
GET /replenishment/purchase-orders | Submitted purchase orders, with their lines | purchase_order | POSubmit | Yes |
GET /replenishment/transfer-orders | Submitted transfer orders, with their lines | transfer_order | TOSubmit | Yes |
GET /replenishment/work-orders | Submitted work orders, with their lines | work_order | WOSubmit | Yes |
GET /replenishment/production-orders | Submitted production orders, with their lines | production_order | ProductionOrderSubmit | Yes |
GET /replenishment/requisitions | Order recommendations, one line per record | requisition | None | Yes |
See Replenishment Orders for the order endpoints, and Order requisitions below.
Demand planning
| Endpoint | Returns | DataType | Webhook trigger | Extended data |
|---|---|---|---|---|
GET /demand-planning/forecast/weekly | Weekly forecast buckets per SKU-location | forecast | ForecastWeeklyUpdate | Yes |
GET /demand-planning/forecast/monthly | Monthly forecast buckets per SKU-location | forecast | ForecastMonthlyUpdate | Yes |
GET /demand-planning/forecast/monthly-aggregate | Monthly aggregate forecast per SKU-location | forecast | None | Yes |
GET /demand-planning/demand-history | Demand transaction lines | demand_history | None | Yes |
See Forecasts, and Demand history below.
Inventory optimization
| Endpoint | Returns | DataType | Webhook trigger | Extended data |
|---|---|---|---|---|
GET /inventory/policies | The inventory policy of each SKU-location | inventory_policy | InventoryPolicyUpdate | Yes |
GET /inventory/service-level | Policies with their costs and the service levels GAINS evaluated | inventory_service_level | None | Yes |
GET /inventory/bills-of-material | The components of each kit, per kit location | bill_of_material | None | No |
GET /inventory/supercessions | Each superseding item-location with the items it replaces | supercessions | None | No |
See Inventory Policies for policies and service levels, and Master data below for bills of material and supercessions.
Locations, vendors and customers
| Endpoint | Returns | DataType | Webhook trigger | Extended data |
|---|---|---|---|---|
GET /locations | Your locations | location | None | Yes |
GET /vendors | Your vendors, with lead times and ordering terms | vendor | None | No |
GET /customers | Your customers and their ship-to addresses | customer | None | No |
Lead-time prediction
These endpoints are available only when lead-time prediction is enabled for your GAINS instance. Every request names a model run with ModelRunDate.
| Endpoint | Returns | DataType | Main filters |
|---|---|---|---|
GET /ltp/predictions | The predicted lead time of each SKU-location | prediction | ModelRunDate; ItemCode and LocationCode, together |
GET /ltp/predictions/features | What contributed to one SKU-location's prediction | predictions_features | ModelRunDate, ItemCode, LocationCode, all required |
GET /ltp/models/training | Model metrics on the training data | training | ModelRunDate |
GET /ltp/models/holdout | Model metrics on the holdout data | holdout | ModelRunDate |
GET /ltp/features/predictions | Training feature values | training_predictions | ModelRunDate, Source |
GET /ltp/features/probability | Training probability feature values | training_probability | ModelRunDate, Source |
GET /ltp/features/evaluations | Holdout evaluation feature values | holdout_evaluation_features | ModelRunDate, Source |
None of them has a webhook or extended data.
Your own custom data
GET /custom/{ApiRoute} reads back the records loaded through POST /custom/{ApiRoute}, for a route your GAINS representative has set up.
Demand history
GET /demand-planning/demand-history returns the demand transactions GAINS holds: one record per order line, with its customer, dates, quantity and price, and the item details GAINS has for it. Use it to copy the sales history GAINS forecasts from into a reporting or analytics system.
This request reads the September demand shipped from CHI01:
GET /api/v1/demand-planning/demand-history?LocationCode=CHI01&RequestDateStart=2026-09-01%2000:00:00&RequestDateEnd=2026-10-01%2000:00:00{
"DataType": "demand_history",
"Data": [
{
"ItemCode": "ASM-7701",
"ItemDescription": "Hub assembly, front",
"ItemType": null,
"IdealShipLocationCode": "CHI01",
"ActualShipLocationCode": "CHI01",
"Department": "10",
"Group": "220",
"InventoryClass": "A",
"UnitOfMeasure": "EA",
"OrderNumber": "SO-2026-118734",
"LineNumber": "1",
"CustomerCode": "C10045",
"CustomerShipToCode": "C10045-02",
"ExclusionFlag": false,
"RequestDate": "2026-09-14 00:00:00",
"PromiseDate": "2026-09-16 00:00:00",
"ShipDate": "2026-09-16 00:00:00",
"RequestQuantity": 24,
"OrderPrice": 89.5,
"LineComment": null,
"Status": "03",
"DemandType": 0
}
],
"Paging": {
"NextCursor": null,
"CurrentDataCount": 1
}
}Demand history filters
| Parameter | Matches |
|---|---|
ItemCode | The item of the line |
LocationCode | The location the line was actually shipped from, ActualShipLocationCode |
ItemLocationFilterType | include (default) or exclude: whether ItemCode and LocationCode select or leave out |
CustomerCode, CustomerShipToCode | The customer and ship-to of the line |
RequestDateStart | Lines requested on or after this time |
RequestDateEnd | Lines requested before this time |
- Dates include a time, as in the example above; see Dates in query parameters.
RequestDateEndis exclusive. To read September, end at2026-10-01 00:00:00.excludeleaves out every match of either list.ItemLocationFilterType=exclude&ItemCode=ASM-7701&LocationCode=DAL02leaves out itemASM-7701everywhere, and every item shipped fromDAL02.
You can also filter on extended data attributes that your GAINS representative has made available as filters.
Reading demand history regularly
Size counts order lines. The date filters select on the date a line was requested, not on when GAINS received it, so a line loaded late for an earlier date appears in a window you may already have read. To keep a copy current, re-read a recent window, for example the last 60 days, and replace what you hold for it.
Order requisitions
A requisition is a single order recommendation in GAINS: one item to be ordered from one shipping location into one receiving location, with its quantity, dates and cost. Buyers review requisitions and submit them as orders. A submitted order groups lines under a TrackingNumber and is read from the order endpoints; GET /replenishment/requisitions returns the recommendations line by line.
This request reads the purchase requisitions for CHI01:
GET /api/v1/replenishment/requisitions?OrderType=purchase_order&ReceivingLocation=CHI01{
"DataType": "requisition",
"Data": [
{
"OrderType": "purchase_order",
"ItemCode": "ASM-7701",
"ItemDescription": "Hub assembly, front",
"ShippingLocation": "ACME",
"ReceivingLocation": "CHI01",
"ReceiveDate": "2026-11-23",
"ReleaseDate": "2026-10-26",
"DeliveryDate": "2026-11-21",
"ApprovalCode": "U",
"Quantity": 480,
"Cost": 62.1,
"LineComment": null,
"OrderNumber": null,
"BuyerCode": "JSMITH",
"PreOrderCarryCost": 112.4,
"DaysOverLeadTime": 0.0,
"Weight": 6.2,
"Volume": 0.05,
"ConversionFactor": 12.0,
"BundleCode": 3,
"Department": "10",
"Group": "220"
}
],
"Paging": {
"NextCursor": null,
"CurrentDataCount": 1
}
}Requisition filters
| Parameter | Matches |
|---|---|
OrderType | One order type: purchase_order, transfer_order or work_order |
ItemCode | The item |
ApprovalCode | The approval code. Defaults to U, P and Q |
BundleCode | The bundle, as a whole number |
ShippingLocation | The vendor or location the line ships from |
ReceivingLocation | The location that receives the line |
OrderTypetakes one value, spelled asOrderTypeis returned. Without it, every type is returned.- The default approval codes differ from the order endpoints. Without
ApprovalCode, requisitions with codesU,PandQare returned, and approved (A) lines are not. Name every code you want, for exampleApprovalCode=A,U.
Submitted or not
The endpoint filters on approval code only. It does not look at whether a line has been submitted, and a requisition carries no TrackingNumber, so you cannot tell from the response whether a line is already part of an order. To process submitted orders, use the order endpoints or their webhooks instead.
Size counts requisition lines. Requisitions have no webhook.
Master data
The master data endpoints return the records as GAINS holds them at the time of the call, ordered by their codes.
| Endpoint | One record is | Filters |
|---|---|---|
GET /locations | A location, with its type, address, dates and currency | LocationCode, and extended data filters |
GET /vendors | A vendor for one receiving location (ReceiveLocationCode), with its address, contact, terms and lead times. A vendor that supplies several locations appears once for each | VendorCode |
GET /customers | A customer ship-to (CustomerCode and ShipToCode), with its address and the location it is ideally shipped from | CustomerCode |
GET /inventory/bills-of-material | A kit item, with its KitLocations and their Components | KitItemCode, KitLocationCode, ItemLocationFilterType |
GET /inventory/supercessions | A superseding item-location (NewItem), with the OldItems it replaces | NewItemCode, NewLocationCode, ItemLocationFilterType, EffectiveDateStart, EffectiveDateEnd |
- Bills of material include every component GAINS holds, whatever its
EffectiveFromandEffectiveTodates. Check those dates to find the components in effect. - Supercession dates both filter on the effective date of the relationship:
EffectiveDateStartis inclusive,EffectiveDateEndexclusive; see Dates in query parameters.
Errors
| Status | Cause |
|---|---|
400 Bad Request | A filter or paging parameter is invalid, for example a filter with more than 10 values, or Size not between 1 and 1000 |
401 Unauthorized | The request carries no valid credentials |
403 Forbidden | Your credentials do not grant access to this group of endpoints |
426 Upgrade Required | Production orders only: your GAINS X version is too old for this endpoint |
Access is granted per group: replenishment (orders and requisitions), demand planning (forecasts and demand history), inventory optimization (policies, service levels, bills of material and supercessions), master data (locations, vendors and customers), lead-time prediction, and custom data. Ask your GAINS representative to change what your client can read. See Errors Handling & Exceptions for the error response body.
Related
Updated about 9 hours ago
