Data Formats & Conventions

Field naming, accepted JSON values, date and time formats, and empty values, shared by every GAINS Connect endpoint.

This page describes the conventions every GAINS Connect endpoint shares: how fields are named, which JSON values are accepted for each type, and how dates and times are written. Read it before you build your first request, and come back to it when a request is refused with 400.

Requests and responses are JSON

Send every request that has a body with Content-Type: application/json. A missing or different Content-Type is refused with 415. Responses are JSON too.

The body must be one JSON document. Load endpoints take a JSON array of records; see Sending a batch for the limit. See Inbound Endpoints & Integration Tasks for the responses a load returns.

POST /api/v1/skus HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqTl9F...
Content-Type: application/json
[
  {
    "ItemCode": "ASM-7701",
    "Description": "Hydraulic pump assembly",
    "Department": "HYD",
    "Group": "PUMPS",
    "StockingUnitOfMeasure": "EA",
    "ShelfLife": 730,
    "StandardCost": 412.5,
    "ItemCreateDate": "2026-05-22"
  }
]

Field names

Field names are PascalCase, in requests and responses alike: ItemCode, StandardCost, TaskId. Query parameters follow the same rule: Cursor, Size, DateStart.

Names are matched exactly, including case. itemCode or ITEMCODE is not ItemCode. Some names keep an abbreviation in capitals, such as POType, FOBCost or BTOKitItemCode, so copy each name from the API Reference rather than deriving it.

A few names do not follow the PascalCase rule:

WhereNames
ExtendedDataThe keys are the labels configured for your environment. See Extended Data - Inbound and Extended Data - Outbound.
POST /custom/{ApiRoute}The fields defined for that custom route.
Webhook deliveriesPascalCase by default; a destination can be set up to receive camelCase. See Webhooks.

Unknown fields are refused

A field the endpoint does not define is not ignored. GAINS Connect refuses the whole request with 400 and accepts no record from it:

{
  "Reason": "The field 'itemCode' is not recognized. Please ensure you are using the correct field names and try again."
}

Values and types

Send each value with the JSON type the API Reference gives for the field. A number or true/false value can also be sent in quotes where it fits the field, such as "730" or "true". Arrays, objects, and text in a number or true/false field are refused with 400.

🚧

Decimals in whole-number fields

A whole-number field takes a whole number only. A decimal such as 1.9, or 5.0, is refused with 400, and the Reason names the value and the field. Check the field's type in the API Reference and round the value yourself before you send it.

To leave an optional field empty, send null or leave the field out; GAINS Connect treats the two the same way. In a text field, "null" is the four letters null.

A value of the wrong type stops GAINS Connect from reading the request, so the whole request is refused and nothing is accepted. The Reason names the record's position in the array and the field:

{
  "Reason": "'two years' is not a valid value for field '[0].ShelfLife (location: line: 7, column: 18)'"
}

Lengths, ranges and formats

The API Reference gives each field's limits: maxLength and minLength for text, a format such as date, and allowed values or ranges where they apply. These are checked record by record, after the request has been read. A record that breaks one is rejected on its own and the others are still accepted, with 207 or 422 as described in Rejected Records.

{
  "Reason": "Name must be between 0 and 100 characters. (path: Name)",
  "RecordKey": {
    "LocationCode": "DET03"
  }
}

GAINS Connect does not trim text. Leading and trailing spaces are part of the value and count toward its length.

ProblemResult
Malformed JSON, an unknown field, a value of the wrong type400, the whole request is refused.
An empty array, or more than 1000 records422, the whole request is refused.
A missing required field, a value too long, out of range or in the wrong date formatThe record is rejected; the others are accepted.

Dates and times

Dates and times have no time zone and no offset. Times are local to your GAINS environment; ask your GAINS representative which time zone it uses.

ValueFormatExample
DateYYYY-MM-DD2026-05-22
Date and timeYYYY-MM-DD HH:MM:SS, 24-hour, with a space and no T2026-05-22 14:30:00

Dates you send

Depending on the endpoint, a field expects a date or a date and time. Each field's description in the API Reference gives its format. Use a four-digit year and two-digit month and day: 2026-5-22 and 2026-02-30 are both rejected.

A date in the wrong format rejects its record, with a reason that names the expected pattern:

{
  "Reason": "StartDate is not a valid date. Expected pattern: yyyy-MM-dd (path: StartDate)",
  "RecordKey": {
    "LocationCode": "DET03"
  }
}

Dates in query parameters

Date filters on read endpoints also follow the format each parameter's description gives; most take a date and time, even where the parameter is named after a date. Encode the space in the URL as %20:

GET /api/v1/tasks?DateStart=2026-05-22%2000:00:00 HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqTl9F...

A value in another format answers 400 with The date string isn't a valid date.

Dates you receive

Responses and webhooks return a date or a date and time, depending on the endpoint and field; the API Reference gives each field's format.

Empty values in responses

A field with no value is returned as null in responses and webhook deliveries, not left out. The exception is ExtendedData, left out where no extended data is configured for that level.

Related


Did this page help you?