Custom Schema
Load and read data that fits none of the standard subjects: what GAINS sets up, how records are checked, and the errors.
What a custom schema is
A custom schema lets you load data into GAINS, and read it back, when it fits none of the standard subjects. Each schema has its own route: you submit records to POST /custom/{ApiRoute} and read them with GET /custom/{ApiRoute}. Attributes of a custom schema can also be returned as extended data on standard outbound subjects.
What GAINS sets up
Your GAINS representative configures each custom schema in your environment and gives you:
| Item | Example | Meaning |
|---|---|---|
| Route | warehouse-zones | The {ApiRoute} part of the endpoint path. |
| Attributes | ZoneCode, LocationCode, Capacity, Refrigerated, Notes | The field names your records use, spelled exactly as given. |
| Type of each attribute | string, text, numeric, boolean | How the value is checked (see How records are checked). |
| Required attributes | ZoneCode, LocationCode | Attributes every record must carry. |
| Task type | WarehouseZones | The TaskType the loads of this schema show on their tasks. |
You cannot create or change a schema through the API. Ask your GAINS representative to add an attribute or a new route.
Loading data
Submit an array of records to POST /custom/{ApiRoute}, each record holding the schema's attributes:
POST /api/v1/custom/warehouse-zones HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqTl9F...
Content-Type: application/json[
{
"ZoneCode": "CHI01-A3",
"LocationCode": "CHI01",
"Capacity": "1250.5",
"Refrigerated": "true",
"Notes": "Cold storage aisle, north wall"
},
{
"ZoneCode": "CHI01-B1",
"LocationCode": "CHI01",
"Capacity": "800",
"Refrigerated": "false",
"Notes": "Bulk pallets"
}
]The submit behaves like every other inbound endpoint: the record limit, the 202 / 207 / 422 responses with a TaskId for the accepted records, and 429 when GAINS Connect is busy are described in Loading Data.
{
"Status": "Queued",
"TaskId": "5b9e2c71-0a4d-4f36-8e1b-7c3d9a2f6e15"
}GAINS loads the records at its next scheduled load for custom data. The task shows the task type set up for the schema, for example WarehouseZones. To list these tasks with GET /tasks, filter on TaskType=InboundCustomSchema, which covers every custom schema. See Integration Tasks.
No idempotency key on custom loadsThis endpoint ignores
Idempotency-Key, so a resent request is loaded again. After a timeout, look for the first attempt's task withGET /tasksbefore you submit it again.
How records are checked
Each record is checked against the schema on its own. A record that fails is listed under RejectedRecords in the 207 or 422 response; the others are accepted.
| Check | Rule |
|---|---|
| Required attributes | Each must be present. |
| Unknown attributes | An attribute the schema does not define rejects the record. Names are case-sensitive: zonecode is not ZoneCode. |
string | A JSON string of at most 500 characters, or fewer if GAINS stores the attribute in a shorter field. |
text | A JSON string of any length. |
numeric | A JSON string holding a number: "1250.5", "-3". |
boolean | The JSON string "true" or "false", in any letter case. |
Send every value as a JSON string, numbers and booleans included: "Capacity": 1250.5 is rejected, "Capacity": "1250.5" is accepted. Leave out an optional attribute you have no value for instead of sending null, which fails the type check.
An unknown attribute differs from the standard endpoints, where an unknown field fails the whole request with 400: here only that record is rejected, and the others are still accepted. A rejected custom-schema record comes back with its attributes wrapped in a Data object, and its reasons carry no RecordKey, so match it to your own data by its attributes:
{
"Status": "Received",
"TaskId": "5b9e2c71-0a4d-4f36-8e1b-7c3d9a2f6e15",
"RejectedRecords": [
{
"Record": {
"Data": {
"ZoneCode": "CHI01-B1",
"LocationCode": "CHI01",
"Colour": "Blue"
}
},
"Reasons": [
{
"Reason": "Unexpected attribute: Colour"
}
]
}
]
}Reading and resending rejected records is described in Rejected Records.
Reading data
GET /custom/{ApiRoute} returns the records GAINS holds for the schema, so a load appears only once its task is Completed. Results are paged with Size and Cursor, as described in Pagination.
GET /api/v1/custom/warehouse-zones?Size=2 HTTP/1.1
Host: acme.gainsystems.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqTl9F...{
"Data": [
{
"Data": {
"ZoneCode": "CHI01-A3",
"LocationCode": "CHI01",
"Capacity": 1250.5,
"Refrigerated": true,
"Notes": "Cold storage aisle, north wall"
}
},
{
"Data": {
"ZoneCode": "CHI01-B1",
"LocationCode": "CHI01",
"Capacity": 800,
"Refrigerated": false,
"Notes": "Bulk pallets"
}
}
],
"Paging": {
"NextCursor": "eyJpZENvZGUiOiIxMDIifQ==",
"CurrentDataCount": 2
}
}Unlike the standard outbound subjects, the response carries Data and Paging only, with no DataType. Records come back under the same attribute names you submit them with, each inside its own Data object. Values come back in the type GAINS stores them in, so a numeric attribute you sent as "1250.5" can be returned as the number 1250.5.
Errors
| Status | Reason begins with | What to do |
|---|---|---|
404 | The route specified does not exist. | Check the route name with your GAINS representative. Applies to POST and GET. |
424 | The underlying schema has not yet been initialized. | The schema's data store has not been created yet. Retry later; contact your GAINS representative if it persists. Applies to GET. |
Other errors are common to every endpoint; see Errors & Retries.
Related
- Loading Data: submit responses and the record limit.
- Integration Tasks: following a load to
Completed. - Rejected Records
- Load Throughput & Retries
- Pagination
- Extended Data: returning custom-schema attributes with standard subjects.
Updated 8 days ago
