Writing Data
The Trackstar API enables you to write data into your end users’ connected accounts. You can create new entities POST
and update existing entities PUT
.
Request Body
Every write request requires a JSON body. The request body will differ depending on the type of write request you are making and the integeration you are writing to.
e.g. Creating orders in WMS A will have a different request body than creating orders in WMS B.
To make it easier to dynamically write into WMS, Trackstar provides a meta
endpoint that allows you to get the schema of the request body for a write request.
Meta Endpoint
The meta
endpoint returns the request body schema for a given integration and method. For example, calling GET /wms/inbound-shipments/meta?method=POST
with access_token=abc123
will return the schema for creating an inbound shipment in the WMS integration associated with the access token abc123
.
Instead of building customized write logic for every integration, /meta
allows you to:
- Dynamically generate the request body schema for a write request
- Automatically account for differences between integrations
- Autogenerate user interfaces for your end users to create and update entities
Meta Response
The top level of the meta
response is an object with three keys: schema
, definitions
, and $ref
.
Every definition has properties
, a list of elements called required
, and a type
(equal to object
).
This schema conforms to the JSON Schema Draft 07 specification. More information can be found there.
Example
The following example demonstrates how to take the response from the meta
endpoint and use it to create the request body for a write request.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"InboundShipmentLineItem": {
"properties": {
"expected_quantity": {
"title": "expected_quantity",
"type": "integer",
"description": ""
},
"expected_weight": {
"title": "expected_weight",
"type": "number",
"format": "float",
"description": "Expected weight in pounds"
},
"received_quantity": {
"title": "received_quantity",
"type": "integer",
"description": ""
},
"sku": {
"title": "sku",
"type": "string",
"description": ""
},
"unit_price": {
"title": "unit_price",
"type": "number",
"format": "float",
"description": "Price of the product (USD)."
}
},
"type": "object",
"required": [
"expected_quantity",
"expected_weight",
"sku",
"unit_price"
],
"additionalProperties": false
},
"ShipToAddress": {
"properties": {
"address1": {
"title": "address1",
"type": "string",
"description": ""
},
"address2": {
"title": "address2",
"type": "string",
"description": ""
},
"city": {
"title": "city",
"type": "string",
"description": ""
},
"country": {
"title": "country",
"type": "string",
"description": ""
},
"first_name": {
"title": "first_name",
"type": "string",
"description": ""
},
"last_name": {
"title": "last_name",
"type": "string",
"description": ""
},
"postal_code": {
"title": "postal_code",
"type": "string",
"description": ""
},
"state": {
"title": "state",
"type": "string",
"description": ""
}
},
"type": "object",
"required": [
"address1",
"city",
"country",
"first_name",
"last_name",
"postal_code",
"state"
],
"additionalProperties": false
},
"InboundShipmentSchema": {
"properties": {
"supplier": {
"title": "supplier",
"type": "string",
"description": "The supplier from which the shipment is being sent."
},
"warehouse_id": {
"title": "warehouse_id",
"type": "string",
"description": "ID of the warehouse that will be receiving the shipment."
},
"expected_arrival_date": {
"title": "expected_arrival_date",
"type": "string",
"description": "Date the shipment is expected to reach the warehouse. Returned in YYYY-MM-DDTHH:MM:SSZ format.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"status": {
"title": "status",
"type": "string",
"description": "The status of the inbound shipment.",
"enum": [
"open",
"received",
"cancelled"
],
"enumNames": []
},
"ship_to_address": {
"type": "object",
"$ref": "#/definitions/ShipToAddress"
},
"line_items": {
"title": "line_items",
"type": "array",
"description": "List of line items included in the shipment.",
"items": {
"type": "object",
"$ref": "#/definitions/InboundShipmentLineItem"
}
}
},
"type": "object",
"required": [
"warehouse_id",
"expected_arrival_date",
"status",
"ship_to_address",
"line_items"
],
"additionalProperties": false
}
},
"$ref": "#/definitions/InboundShipmentSchema"
}
Write Request Flow
- Call
GET wms/<object_type>/meta?method=[POST|PUT]
to get the schema of the request body. - Generate a user interface (e.g. a form) based on the schema.
- On submit, serialize the form data into a JSON object.
- Call
POST wms/<object_type>
orPUT wms/<object_type>
with the JSON object as the request body.
Example UI Creation
The example React code below demonstrates how to use the meta endpoint to generate a form for creating an inbound-shipment.
// See "Sample Meta Response" for the schema
const generateFormFields = (sub_schema) => {
const properties = sub_schema.properties;
return Object.keys(properties).map((key) => {
const property = properties[key];
const { description, type, enum: enumValues, pattern, items } = property;
const required = sub_schema.required.includes(key);
const keyStr = required ? key.concat("*") : key;
if (type === 'object') {
const ref = property["$ref"].replace("#/definitions/", "");
const definition = definitions[ref];
return (
<div>
<label> {keyStr}: </label>
{generateFormFields(definition)}
</div>
);
}
if (type === 'array') {
const ref = items["$ref"].replace("#/definitions/", "");
const definition = definitions[ref];
const subForm = generateFormFields(definition);
return (
<form id="sub">
<label>{keyStr}: </label>
<div key={"item1"}>
<label>{keyStr} 1: </label>
{subForm}
</div>
<div key={"item2"}>
<label>{keyStr} 2: </label>
{subForm}
</div>
</form>
);
}
if (enumValues) {
return (
<div key={key}>
<label htmlFor={key}>{keyStr}: </label>
<select
id={key}
name={key}
>
{enumValues.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
<label> ({description})</label>
</div>
);
}
return (
<div key={key}>
<label htmlFor={key}>{keyStr}: </label>
<input
type={type}
id={key}
name={key}
required={required}
pattern={pattern ? pattern : ".+"}
/>
<label> {description ? "(".concat(description).concat(")") : ""}</label>
</div>
);
});
};