Deleting Data

How deletes work, and how you approve or reject a SKU-location delete before anything is removed.

This page explains how to remove data from GAINS through the API, and how you approve or reject a SKU-location delete before anything is removed. A delete creates an integration task like a load does; how tasks work is described in Integration Tasks.

How a delete works

Each delete endpoint takes an array of record keys, not whole records. GAINS removes the matching records at its next scheduled load for that kind of data.

Which subjects have a delete endpoint, and the task type each delete creates, are listed in Inbound Subjects. The fields of each key are in the API Reference; where a key differs from what identifies the record on the load, the subject's page explains why, for example Vendors. Send each key exactly as you loaded the record.

What one delete removes

Most deletes remove exactly the record their key identifies. Some remove more, by design or because of the fields you leave out:

DeleteRemoves
Price breaksEvery price break of the SKU-location
Imported forecastsEvery forecast period of the SKU-location
Demand eventsThe event and every SKU-location it affects
Demand transactionsWithout LineNumber, every line of the order for that ship-from location and request date. Leaving out ItemCode or CustomerShipToCode widens it the same way
Usage transactionsWithout WorkLineNumber or ItemCode, every line of the work order at that location and release date

Leaving out an optional field does not widen every delete:

  • Vendors: without ReceiveLocationCode, only the vendor record loaded without a receiving location is removed, not the vendor at every location. Send one key for each receiving location you want to remove.
  • Supply transactions: without SplitNumber, only the unsplit line is removed. Send the split number of each split line.

Deleting an item or a location removes only that record and its extended data. Its SKU-locations, transactions, price breaks and forecasts stay in GAINS; delete them first if you no longer want them.

Sending a delete

POST /api/v1/supply-transactions/delete HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqTl9F...
Content-Type: application/json
Idempotency-Key: 3a7e9c14-5b2d-4f81-9e6a-0c4d8b1f2a73
[
  {
    "OrderNumber": "PO-58213",
    "LineNumber": "1"
  },
  {
    "OrderNumber": "PO-58213",
    "LineNumber": "2",
    "SplitNumber": "2"
  }
]
{
  "Status": "Queued",
  "TaskId": "8d4f1a2e-6c3b-4e7a-9f05-2b1c7d9e4a60"
}

A delete follows the same rules as a load:

  • The 1000-record limit and the 202, 207 and 422 responses of Loading Data apply, counted in keys. Each key is checked on its own.
  • The same key twice in one request refuses the whole request with 400.
  • Deleting needs delete access; without it the request answers 403.
  • Idempotency-Key is supported, as on loads; see Idempotency.
  • If GAINS cannot take the delete, the request answers 500, 503 or 504 and creates no task. Retry later with a new Idempotency-Key; see Decide whether to retry.

Follow the task as for a load. Once it is final, Batch.Accepted and Batch.Rejected count the keys GAINS deleted and refused, and Batch.RejectedRecords says why each refused key was refused.

SKU-location delete review

Deleting a SKU-location removes planning history that cannot be restored. POST /skus-locations/delete therefore deletes nothing on receipt: GAINS Connect holds the request until you approve or reject it.

How the review works

  1. You send the SKU-locations to delete. The task starts in PendingReview. Nothing has been deleted or sent to GAINS.
  2. A reviewer approves or rejects the request with PUT /tasks/{TaskId}.
  3. Approved: the task moves to Queued or Received and the deletion is loaded at the next scheduled load, like any other delete.
  4. Rejected: the task moves to RejectedNotApproved. Nothing is deleted.

While the task is PendingReview, you can withdraw it yourself (see Withdrawing a request).

{
  "Status": "PendingReview",
  "TaskId": "f17c3a9b-2e48-4d6a-8b1f-5c0e9a7d3b24"
}

Who reviews

The review is recorded through PUT /tasks/{TaskId}. The reviewer is taken from the credentials that make the call, so the body carries only the decision and an optional comment.

Reviewer access is enforced for OAuth (Bearer) clients only: a client without it receives 403. With Basic authentication, any GAINS X user can approve, including the user who submitted the delete. To keep submitting and approving apart, ask your GAINS representative for a separate OAuth client with reviewer access, and have reviewers use only that client.

{
  "Status": "approved",
  "Comments": "Discontinued at DAL02 per planning review 2026-05-21"
}
{
  "Reason": "The task has been marked as approved.",
  "Status": "Queued"
}

The decision is final: a second decision on the same task is refused with 400. Submit the delete again to get a new review.

Following the review

GET /tasks/{TaskId} shows the decision once it is made: UpdatedBy is the reviewer, UpdatedOn the time, and Comments the reviewer's note.

To be told instead of polling, enable the TaskStatusUpdate webhook trigger with a filter such as TaskType = 'DeleteSkuLocation'. See Webhook Filters.

Withdrawing a request

POST /tasks/{TaskId}/cancel withdraws a request that is still PendingReview, Received or Queued. The held SKU-locations are discarded and no review is needed. It answers as described in Cancelling a task.

Requests nobody reviews

A request still PendingReview when its task expires is removed with it, like every task; see How long tasks are kept. Nothing is deleted. If you still need the deletion, send the request again.

GAINS version

The SKU-location delete and the review need a recent GAINS X. On an older version they answer 426; the API Reference page of each endpoint states the version it needs. See When your version is too old (426).

Related


Did this page help you?