Rejected Records

Why records are rejected, where each rejection is reported, and how to resend only what failed.

A record you send to an inbound endpoint can be rejected at two points: by GAINS Connect when you submit it, or by GAINS while it loads the task. This page explains where each kind of rejection is reported, how to read it, and what to resend.

Where rejections are reported

WhenReported inWhat happened to the other records
At submit, the record fails the endpoint's checksThe submit response: 207 when other records were accepted, 422 when none wereAccepted records are in the task and will be loaded
While loading, GAINS refuses the recordBatch.RejectedRecords of the task, once it is Completed or RejectedFailedProcessingRecords GAINS loaded are in GAINS

Both use the same RejectedRecords structure. A record rejected at submit is not part of the task.

🚧

Keep the submit response

Submit-time rejections are returned only once, in the 207 or 422 response. Save RejectedRecords from that response: it cannot be read back later from the task.

Rejections at submit

GAINS Connect checks each record against the endpoint's rules, such as required fields, maximum lengths, date formats, value ranges and extended data. It checks every record, and accepts or rejects each one on its own. On endpoints whose records carry nested data, such as orders with LineItems, the top-level record is the unit: a problem on one line rejects that whole order with its other lines.

  • If some records pass, GAINS Connect creates a task for them and answers 207, with the task's Status and TaskId and the rejected records.
  • If no record passes, no task is created. GAINS Connect answers 422, with Status set to RejectedFailedProcessing and the rejected records.
{
  "Status": "Queued",
  "TaskId": "c2791b62-508f-4aaa-b011-3764ff4625ee",
  "RejectedRecords": [
    {
      "Record": {
        "LocationCode": "DET03",
        "Name": "Detroit Branch",
        "Type": null,
        "ParentDefaultCode": "CHI01",
        "Address1": null,
        "Address2": null,
        "City": "Detroit",
        "State": "MI",
        "Country": "US",
        "PostalCode": "48226-3307-00012",
        "Latitude": null,
        "Longitude": null,
        "StartDate": null,
        "EndDate": null,
        "Size": null,
        "CurrencyCode": "USD",
        "ExtendedData": null
      },
      "Reasons": [
        {
          "Reason": "PostalCode must be between 0 and 15 characters. (path: PostalCode)",
          "RecordKey": {
            "LocationCode": "DET03"
          }
        },
        {
          "Reason": "Type is required. (path: Type)",
          "RecordKey": {
            "LocationCode": "DET03"
          }
        }
      ]
    }
  ]
}

A request that cannot be read at all, such as malformed JSON, answers 400 with a single Reason, and nothing is accepted. See Inbound Endpoints & Integration Tasks for every submit response.

Rejections while loading

GAINS can refuse a record that passed the submit checks, for example because it refers to data GAINS does not hold. These rejections are reported on the task. Read them with GET /tasks/{TaskId}, or receive them with the TaskStatusUpdate webhook (see Webhooks).

Batch.RejectedRecords is filled once the task is final:

  • Completed: at least one record was loaded. Batch.Rejected gives the number refused, and Batch.RejectedRecords lists them.
  • RejectedFailedProcessing: GAINS refused every record in the task.
{
  "TaskId": "c2791b62-508f-4aaa-b011-3764ff4625ee",
  "TaskType": "InboundLocation",
  "Status": "Completed",
  "StatusMessage": "Processing completed. Total objects = 2. Accepted = 1. Accepted (with exclusions) = 0. Rejected = 1.",
  "Batch": {
    "TotalRecords": 2,
    "Accepted": 1,
    "AcceptedWithExclusions": 0,
    "Rejected": 1,
    "RejectedRecords": [
      {
        "Record": {
          "LocationCode": "MKE02",
          "Name": "Milwaukee Branch",
          "Type": "Branch",
          "ParentDefaultCode": "CHI01",
          "Address1": null,
          "Address2": null,
          "City": "Milwaukee",
          "State": "WI",
          "Country": "US",
          "PostalCode": "53202",
          "Latitude": null,
          "Longitude": null,
          "StartDate": null,
          "EndDate": null,
          "Size": null,
          "CurrencyCode": "USD",
          "ExtendedData": {}
        },
        "Reasons": [
          {
            "Reason": "Parent location CHI01 is not a valid location."
          }
        ]
      }
    ]
  },
  "StatusUpdatedOn": "2026-05-22 02:04:51",
  "CreatedOn": "2026-05-21 16:12:08",
  "CreatedBy": "[email protected]",
  "UpdatedBy": null,
  "Comments": null,
  "UpdatedOn": null
}

A task that ends Failed stopped on an unexpected error rather than refusing records, so it has no RejectedRecords to act on. Send the batch again, and contact your GAINS representative if it fails again.

Structure of a rejected record

Each entry of RejectedRecords has two members:

FieldDescription
RecordThe rejected record, as an object.
ReasonsOne entry per problem found with the record, each with a Reason.

Each entry of Reasons has:

FieldDescription
ReasonWhat is wrong. At submit, the message ends with (path: …), naming the field concerned in the form it has in your request, for example (path: LineItems[2].RequestedQuantity) for a field on the third line of an order.
RecordKeySubmit only. The key fields of the record, for example LocationCode, or ItemCode and LocationCode, so that you can match the rejection to your own data. When the problem is on a nested line, the line's keys are included.

A record can have several reasons.

Correcting and resending

  1. Match each rejected record to your own data with RecordKey (at submit) or the key fields of Record.
  2. Correct the problem each Reason describes.
  3. Send only the corrected records, in a new request. After a 207 the accepted records are already in a task, so resending the whole batch would load them twice.
  4. Use a new Idempotency-Key for the new request. See Idempotency.

Related guides


Did this page help you?