Integrate with Ingrid
Ingrid typically builds integrations tailored to specific carriers but we also make it possible for carriers to integrate with us.
From checkout to tracking, the following documentation provides you with everything needed for a complete integration with Ingrid.
Diagram
Endpoints
1. Fetch access token
POST /oauth/token
Request body:
{
"client_id": "client_id_value",
"client_secret": "client_secret_value"
}
NOTE: ideally there should be only one set of credentials granted for Ingrid that would work for every merchant that books with us
Response body:
{
"access_token": "access_token_value",
"scope": "general", // should always be set to general
"token_type": "Bearer", // should always be set to Bearer
"expires_in": 3600 // in seconds
}
2. Fetch shipping options
POST /shipping-options
This request is made when the customer buys something at the merchant's e-commerce portal and then presented with the delivery options during the checkout step
Headers:
- Authorization: Bearer access_token_value
- x-trace-id: P202307262336326SP2SFY4FH839WDG (id for tracing purposes)
- x-api-version: v1.0 (version of the API, new minor versions are backward-compatible and can only introduce new fields, major versions can completely change the structure of the requests or remove some fields from it which results in breaking backward compatibility)
Request body:
{
"shipping_method": "velove-std", // id of the product within Ingrid. Not important for carriers that have only one product
"parties": {
// Address of the merchant's warehouse
"from": {
"address": {
"name": "Test Merchant",
"care_of": "",
"address_lines": [
"Test warehouse street 15"
],
"city": "Kalmar",
"postal_code": "39357",
"country": "SE"
}
},
// Address that customer types in when checking available delivery options
// Usually is empty outside of postal code and country
"search": {
// Maximum amount of pickup points in the response
"location_limit": 25,
// Can be used to exclude some pickup points from the response
"location_types": ["locker", "postoffice", "manned", "store"],
// Maximum radius in kilometers, only relevant for pickup points
"location_radius": 15.42,
"address": {
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
// Customer's home address if provided
"customer": {
"phone": "+48000000000",
"email": "customer@ingrid.com",
"address": {
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
"shipper": {
"id": "id of the merchant" // id that uniquely identifies the merchant on the carrier's end
}
},
"pickup_time": { // expected time range when parcel is going to picked up from the merchant's warehouse by the carrier
"start": "2023-07-30T23:30:00Z",
"end": "2023-07-30T23:30:00Z"
},
"references": {
"cart_id": "ID of the checkout cart"
}
}
Response body (success, http code 200)
{
// Multiple timeslots are supported in case if the carrier allows the customer to select preferred delivery time slot
"delivery_times": [
{
"start": "2023-07-31T17:30:00Z",
"end": "2023-07-31T18:30:00Z"
},
{
"start": "2023-07-31T20:30:00Z",
"end": "2023-07-31T21:30:00Z"
}
],
// Relevant only for products that support delivery to pickup points (post office, locker etc)
"delivery_locations": [
{
// Unique identifier of the pickup point needed for booking
"id": "9101",
"address": {
"name": "Rīgas T/C Akropole pakomāts",
"care_of": "",
"address_lines": [
"Maskavas iela 257"
],
"city": "Rīga",
"postal_code": "LV-9101",
"country": "LV",
// Mandatory, needed to present pickup point on the map
"coordinates": {
"lat": 56.9238129,
"lng": 24.1752396
}
},
// locker|postoffice|manned|store
"location_type": "locker",
"opening_hours": [
{
"day": 1, // Sunday = 0, Monday = 1, Tuesday = 2 ...
"start": "T08:00+02:00",
"end": "T11:00+02:00"
},
{
"day": 1,
"start": "T12:00+02:00",
"end": "T23:59+02:00"
},
{
"day": 2,
"start": "T08:00+02:00",
"end": "T23:59+02:00"
},
]
}
]
}
Response body (bad request, http code >=400)
{
"errors": [
{
"message": "provided postal code is not covered"
}
]
}
3. Pre-booking
POST /prebooking
This request is sent when the customer completes checkout session from within merchant's e-commerce portal
Headers:
- Authorization: Bearer access_token_value
- x-trace-id: P202307262336326SP2SFY4FH839WDG (id for tracing purposes)
- x-api-version: v1.0 (version of the API, new minor versions are backward-compatible and can only introduce new fields, major versions can completely change the structure of the requests or remove some fields from it which results in breaking backward compatibility)
Request body:
{
"shipping_method": "velove-std", // id of the product within Ingrid. Not important for carriers that have only one product
"parties": {
"from": {
"address": {
"name": "Test Merchant",
"care_of": "",
"address_lines": [
"Test warehouse street 15"
],
"city": "Kalmar",
"postal_code": "39357",
"country": "SE"
}
},
"to": {
"id": "", // id of the pickup point in case if delivery is done to pre-selected pickup point, empty otherwise
"address": { // Usually the same as the customer.address unless it is a delivery to some pre-selected pickup point
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
"customer": {
"phone": "+48000000000",
"email": "customer@ingrid.com",
"address": {
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
"shipper": {
"id": "id of the merchant" // id that uniquely identifies the merchant on the carrier's end
}
},
"delivery_time": { // expected time range when parcel is going to be delivered to the end receiver. Usually this time range is selected from the checkout widget by the receiver themselves
"start": "2023-07-31T23:30:00Z",
"end": "2023-07-31T23:30:00Z"
},
"references": {
"tos_id": "01H6AAXCB6S6K679DPEC38TPMR", // ID of the TOS order in Ingrid, can be used for pre-booking purposes, TOS orders are created when checkout session is completed
"external_id": "Order 001" // ID of the order/shipment provided by the merchant
}
}
Response body (success, http code 200)
{
}
Response body (bad request, http code >=400)
{
"errors": [
{
"message": "delivery time must not be in the past"
}
]
}
4. Book shipment
This request is sent when shipment is booked at the merchant's warehouse by their WMS
POST /booking
Headers:
- Authorization: Bearer access_token_value
- x-trace-id: P202307262336326SP2SFY4FH839WDG (id for tracing purposes)
- x-api-version: v1.0 (version of the API, new minor versions are backward-compatible and can only introduce new fields, major versions can completely change the structure of the requests or remove some fields from it which results in breaking backward compatibility)
Request body:
{
"shipping_method": "velove-std", // id of the product within Ingrid. Not important for carriers that have only one product
"parties": {
"from": {
"address": {
"name": "Test Merchant",
"care_of": "",
"address_lines": [
"Test warehouse street 15"
],
"city": "Kalmar",
"postal_code": "39357",
"country": "SE"
}
},
"to": {
"id": "", // id of the pickup point in case if delivery is done to pre-selected pickup point, empty otherwise
"address": { // Usually the same as the customer.address unless it is a return shipment or delivery to some pre-selected pickup point
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
"customer": {
"phone": "+48000000000",
"email": "customer@ingrid.com",
"address": {
"name": "Test Testson",
"care_of": "",
"address_lines": [
"Test street 1"
],
"city": "Kalmar",
"postal_code": "39356",
"country": "SE"
}
},
"shipper": {
"id": "id of the merchant" // id that uniquely identifies the merchant on the carrier's end
}
},
"delivery_time": { // expected time range when parcel is going to be delivered to the end receiver. Usually this time range is selected from the checkout widget by the receiver themselves
"start": "2023-07-31T23:30:00Z",
"end": "2023-07-31T23:30:00Z"
},
"delivery_instructions": "", // Additional instructions for the courier
"print_config": {
"label_format": "pdf", // pdf|zpl - it is enough to support only one of these formats
"label_size": "normal" // normal|small
},
"references": {
"tos_id": "01H6AAXCB6S6K679DPEC38TPMR", // ID of the TOS order in Ingrid, can be used for pre-booking purposes, TOS orders are created when checkout session is completed
"external_id": "Order 001" // ID of the order/shipment provided by the merchant
},
"packages": [
{
"references": {
"package_id": "delivery 1 uuid"
},
"weight": 15000, // in grams
"dimensions": {
"height": 150, // in millimeters
"length": 200, // in millimeters
"width": 300 // in millimeters
}
}
],
"addons": [
"take_signature",
"id_check",
"age_check_16",
"age_check_18",
"age_check_21"
],
// outbound|return
"direction_type": "outbound"
}
Response body (success, http code 200)
{
"packages": [
{
"barcode": "tracking number",
"label_data": "bGFiZWwgZGF0YQ=="
}
]
}
Response body (bad request, http code >=400)
{
"errors": [
{
"message": "label format ZPL is not supported"
},
{
"message": "delivery time must not be in the past"
}
]
}
5. Cancel shipment
This request is sent when the merchant wants to cancel shipment via their WMS or Ingrid's TA
DELETE /booking/packages/:barcode
Headers:
- Authorization: Bearer access_token_value
- x-trace-id: P202307262336326SP2SFY4FH839WDG (id for tracing purposes)
- x-api-version: v1.0 (version of the API, new minor versions are backward-compatible and can only introduce new fields, major versions can completely change the structure of the requests or remove some fields from it which results in breaking backward compatibility)
Request body: -
Response body (success, http code 200)
{
}
Response body (bad request, http code >=400)
{
"errors": [
{
"message": "package was not found"
}
]
}
6. Tracking
Tracking is implemented via webhook exposed by Ingrid
POST https://api.ingrid.com/v1/integrations/:carrier/update.status?site_id=:site_id
where
- :carrier - is a name of the carrier within Ingrid. Example: velove
- :site_id - is the id of the site within Ingrid. Example: 5f5c1bd1-c365-4555-8771-739213e19b49
Headers:
- Authorization: HMAC-SHA256 signature
where
- signature - base64-encoded sha256 signature calculated by HMAC + SHA256 algorithm from the request JSON body and some secret key known both to Ingrid and the carrier
Request body:
{
"barcode": "tracking number",
"shipping_method": "velove-std", // id of the product within Ingrid
"shipper_id": "id of the merchant", // id that uniquely identifies the merchant on the carrier's end
"event_status": "submitted", // free text, any status will be accepted. At Ingrid we will do our best to map those statuses to our internal statuses
"event_time": "2023-07-31T23:30:00Z",
"estimated_arrival_time": { // Optional, can be ommited
"start": "2023-07-31T23:30:00Z",
"end": "2023-07-31T23:30:00Z"
}
}
Response body (success, http code 200)
{
}
Response body (bad request, http code >=400)
{
"errors": [
{
"message": "invalid or missing authorization header"
}
]
}