Inbound Endpoints & Integration Tasks
How inbound loads work: submit records, follow the integration task to completion, cancel, delete and review.
Inbound endpoints are how you send master and transactional data to GAINS. This page explains what happens to a batch after you send it: the responses a submit can return, the integration task that tracks the batch while GAINS loads it, and how to follow, cancel or delete what you sent.
How an inbound submit works
- You
POSTa batch of records to an inbound endpoint, for examplePOST /locations. - GAINS Connect checks each record against the endpoint's rules: required fields, lengths, formats and value ranges. Each record is accepted or rejected on its own.
- If at least one record is accepted, GAINS Connect creates an integration task for the accepted records and answers at once with its
TaskId. Records rejected at this point are listed in the same response and are not part of the task. - GAINS loads the task's records at its next scheduled load for that kind of data. The task moves to
Processing, then to a final status that gives the record counts and lists any record GAINS refused while loading it.
A 202 or 207 response therefore means the records were accepted for loading, not that they are already in GAINS. Follow the task to know when they are.
Sending a batch
Every inbound endpoint takes a JSON array of records. A request may hold at most 1000 records. The limit counts the top-level records only: on endpoints whose records carry nested data, such as orders with LineItems, a request can hold 1000 orders, each with its own lines.
POST /api/v1/locations HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
Idempotency-Key: 6f1c2b8e-3d4a-4f5b-9c7e-0a1b2c3d4e5f[
{
"LocationCode": "CHI01",
"Name": "Chicago Distribution Center",
"Type": "DC",
"City": "Chicago",
"State": "IL",
"Country": "US",
"PostalCode": "60607",
"CurrencyCode": "USD"
},
{
"LocationCode": "MKE02",
"Name": "Milwaukee Branch",
"Type": "Branch",
"ParentDefaultCode": "CHI01",
"City": "Milwaukee",
"State": "WI",
"Country": "US",
"PostalCode": "53202",
"CurrencyCode": "USD"
}
]When every record is accepted, GAINS Connect answers 202 with the task:
{
"Status": "Queued",
"TaskId": "c2791b62-508f-4aaa-b011-3764ff4625ee"
}Status is Queued when the next GAINS load for this data is scheduled, and Received when it is not yet scheduled. A SKU-location delete answers PendingReview instead (see SKU-location delete review).
Keep the TaskId: it is how you follow the batch from here on.
Submit responses
| Status | Meaning | What to do |
|---|---|---|
202 Accepted | Every record was accepted. The body holds Status and TaskId. | Follow the task. |
207 Multi-Status | Some records were accepted and a task was created for them. The body also lists the rejected records under RejectedRecords. | Follow the task, and correct and resend only the rejected records. |
422 Unprocessable Content | Nothing was accepted and no task was created. | Correct the request and send it again. |
429 Too Many Requests | GAINS Connect is still taking in earlier batches and did not accept this one. Nothing was saved. | Wait for the number of seconds in the Retry-After header, then send the same batch again. |
400 Bad Request | The request could not be read: malformed JSON, a field name the endpoint does not know, a value of the wrong JSON type, or a reused Idempotency-Key. Nothing was saved. | Correct the request. |
401 / 403 | The credentials are missing or rejected, or lack access to this endpoint. | See Authentication. |
A 207 is a partial successTreat
207as "accepted, with exceptions", not as a failure. The accepted records are already in a task and will be loaded, so resending the whole batch would submit them twice.
A 207 carries the task's Status and TaskId and, under RejectedRecords, each rejected record with its reasons; see Rejections at submit.
A 422 comes in one of two forms. When every record failed its checks, the body has the same RejectedRecords list, with Status set to RejectedFailedProcessing and no TaskId. When the request itself is refused, for example because the array is empty or holds more than 1000 records, the body is a single Reason:
{
"Reason": "The data provided exceeds the maximum constraint. Please submit a maximum of 1000 records."
}How to read and act on RejectedRecords is described in Rejected Records.
Integration tasks
An integration task tracks one accepted batch from the moment GAINS Connect accepts it until GAINS has finished loading it. Each task has a TaskType naming the kind of data it carries, for example InboundLocation or DeleteSku (see Task types).
Task statuses
Status | Meaning | Final |
|---|---|---|
Received | Accepted. No GAINS load for this data is scheduled yet. | No |
Queued | Accepted and waiting for the next scheduled GAINS load. StatusMessage gives the expected processing time. | No |
PendingReview | A SKU-location delete held until you approve or reject it. Nothing has been deleted. | No |
Processing | GAINS is loading the records. | No |
Completed | Loading finished and at least one record was loaded. Batch gives the counts and lists any record GAINS refused. | Yes |
RejectedFailedProcessing | Loading finished but GAINS refused every record. Batch.RejectedRecords says why. | Yes |
RejectedNotApproved | You rejected a SKU-location delete under review. Nothing was deleted. | Yes |
Cancelled | You or GAINS cancelled the task before it was processed. Nothing was loaded. | Yes |
Failed | The load stopped on an unexpected error. Send the batch again, and contact your GAINS representative if it fails again. | Yes |
Reading a task
Call GET /tasks/{TaskId} with the TaskId from the submit response:
{
"TaskId": "c2791b62-508f-4aaa-b011-3764ff4625ee",
"TaskType": "InboundLocation",
"Status": "Queued",
"StatusMessage": "Expected processing time is 2026-05-22 02:00:00.",
"Batch": {
"TotalRecords": 2,
"Accepted": null,
"AcceptedWithExclusions": null,
"Rejected": null,
"RejectedRecords": []
},
"StatusUpdatedOn": "2026-05-21 16:12:08",
"CreatedOn": "2026-05-21 16:12:08",
"CreatedBy": "[email protected]",
"UpdatedBy": null,
"Comments": null,
"UpdatedOn": null
}| Field | Description |
|---|---|
TaskId | The task's identifier, as returned by the submit. |
TaskType | The kind of data the task carries. |
Status | The current status (see Task statuses). |
StatusMessage | A readable explanation of the status, such as the expected processing time while Queued. |
Batch.TotalRecords | The number of records in the task. Records rejected at submit are not counted. |
Batch.Accepted, Batch.AcceptedWithExclusions, Batch.Rejected | The load counts. null until the task is Completed or RejectedFailedProcessing. |
Batch.RejectedRecords | The records GAINS refused while loading them, each with its Reasons. Empty until the task is final; see Rejections while loading. |
StatusUpdatedOn | When the task entered its current status. |
CreatedOn, CreatedBy | When the task was created, and the user or client that submitted it. |
UpdatedBy, UpdatedOn | Who approved or declined a reviewed task, and when. |
Comments | The note recorded with a review decision, if any. |
Times are GAINS server time, in the form YYYY-MM-DD HH:MM:SS.
Following a task
You can follow tasks in two ways:
- Polling. Call
GET /tasks/{TaskId}untilStatusis final. A task does not move until the GAINS load runs, so while it isQueued, use the expected processing time inStatusMessageto decide when to check again. - Webhook. Enable the
TaskStatusUpdatetrigger. Each time a task's status changes you receive a delivery whoseDatalist holds the task, in the same form as above; one delivery can carry several tasks. Add a filter such asStatus IN ('Completed', 'RejectedFailedProcessing', 'RejectedNotApproved', 'Cancelled', 'Failed')to receive final statuses only. See Webhooks.
Tasks are kept for 30 days after they are created.
Listing tasks
GET /tasks returns tasks oldest first, in pages, under Data, as described in Pagination.
| Parameter | Description |
|---|---|
Status | One status, or several separated by commas: Completed,RejectedFailedProcessing. |
TaskType | One task type, for example InboundSku. |
DateStart, DateEnd | Tasks created on or after, and on or before, this time. Send a date and time: 2026-05-21 00:00:00. |
Size, Cursor | Paging, as above. |
GET /api/v1/tasks?Status=RejectedFailedProcessing,Failed&DateStart=2026-05-21%2000:00:00 HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...Cancelling a task
POST /tasks/{TaskId}/cancel withdraws a task that GAINS has not started loading: one in Received, Queued or PendingReview. Once a task is Processing it can no longer be cancelled, and the request answers 400.
{
"CancelledOn": "2026-05-21 16:20:44",
"Status": "Cancelled"
}Deleting records
Most kinds of master and transactional data can also be deleted, through an endpoint ending in /delete, for example POST /skus/delete. The Task types table lists which subjects have one. A delete takes the keys of the records, answers like a load and creates a task you follow the same way. Endpoints, keys and rules are in Deleting Data & SKU-Location Review.
POST /skus-locations/delete deletes nothing until you approve it: its task starts in PendingReview. See SKU-location delete review.
Task types
TaskType identifies the endpoint a task came from. Use these values in the TaskType filter of GET /tasks.
POST /supply-transactions/link-order is the one inbound endpoint that creates no task: it takes a single object rather than an array and answers 202 with no body.
Retrying safely
After a 207, resend only the corrected RejectedRecords. After a 429 or a timeout, resend the same batch with the same Idempotency-Key. See Decide whether to retry and Load Throughput & Retries.
Related guides
- Inbound Data Model: what each inbound endpoint expects.
- Rejected Records: reading and correcting rejected records.
- Load Throughput & Retries: batch sizing,
429and retrying. - Deleting Data & SKU-Location Review: delete endpoints and the SKU-location review.
- Extended Data - Inbound: sending your own attributes with inbound records.
- Custom Schema: loading data that fits no standard endpoint.
- Errors Handling & Exceptions: error responses common to every endpoint.
Updated 5 days ago
