Plug & Play API
This spec describes a contract that carriers implement, not a Carriyo-hosted service.
The Plug & Play (PnP) integration model lets a carrier go live with Carriyo without Carriyo writing a bespoke connector. The carrier exposes a small set of HTTP endpoints that follow this specification; Carriyo points its routing engine at the carrier's base URL and calls those endpoints whenever a shipment, manifest, label, or tracking lookup is needed.
Direction of every operation
| Operation | Hosted by | Called by | Direction |
|---|---|---|---|
create-shipment, cancel, request-label, batch-tracking, schedule-collection, manifest |
Carrier | Carriyo | Carriyo → carrier |
status-update-webhook |
Carriyo | Carrier | Carrier → Carriyo (the only reversed flow) |
Every operation tagged Shipments or Manifest is something the carrier implements. Carriyo authenticates itself when it calls those endpoints using the credentials the carrier issued during onboarding.
The single Status update webhook operation is hosted by Carriyo. The carrier calls it whenever a shipment status changes. Authentication for that call goes the other way: Carriyo issues an API key during onboarding, and the carrier includes it in the request.
What's required vs optional
| Operation | Required for Plug & Play? |
|---|---|
create-shipment |
Required |
cancel |
Required |
request-label |
Required (or include labels inline in the create-shipment response) |
batch-tracking |
Required (acts as the fallback when status webhooks are missed) |
status-update-webhook push |
Strongly recommended; real-time tracking depends on it |
schedule-collection |
Optional; implement only if the carrier supports scheduled pickups |
manifest |
Optional; implement only if the carrier supports manifesting |
Authentication
A carrier picks one of the two security schemes when registering with Carriyo:
- API key (
x-api-keyheader): the simplest option. The carrier issues a static key, and Carriyo sends it on every request. - OAuth 2.0 client credentials: Carriyo obtains an access token from the carrier's token endpoint and uses it as a bearer token. Tokens are cached until expiry.
For the status update webhook (the reversed direction), Carriyo issues an API key during carrier onboarding. The carrier must include it as x-api-key on every callback to Carriyo.
Retry, idempotency, and ordering
Carriyo retries failed calls with exponential backoff:
create-shipment: Carriyo may retry the same request after a network failure or 5xx response. Make this endpoint idempotent on the merchant's shipment reference (references.partner_shipment_reference): if a shipment with that reference already exists, return the sametracking_numberinstead of creating a duplicate.cancel: same idempotency expectation. Cancelling an already-cancelled shipment should return200 OK, not400.request-label,batch-tracking: safe to retry; treat as read-only.schedule-collection,manifest: Carriyo retries on 5xx; design for repeat calls with the same payload.
For the status update webhook, the carrier should:
- Treat a
200or204response as confirmed receipt. - On
4xx, do not retry the event; it indicates a malformed payload. - On
5xxor network error, retry with backoff; Carriyo dedupes by(carrier, tracking_number, event_timestamp, status_code). - Include the exact
event_timestampfrom the carrier system, not the time of the callback.
Testing
The servers block uses a templated URL: replace carrier_host with the host you're testing against. While developing your implementation you can point Carriyo at a sandbox URL.
Onboarding
To register a Plug & Play carrier, contact Carriyo Support (support@carriyo.com). The onboarding flow covers: confirming which endpoints you've implemented, exchanging credentials in both directions (your auth for Carriyo → carrier calls, plus Carriyo's API key for your status callbacks), and running an integration test on the demo environment.
Manifest
Optional carrier-hosted endpoint Carriyo calls to generate a manifest (hand off a batch of shipments at a scheduled pickup). Skip this endpoint if your carrier does not support manifesting.
1 operation · 0 objects
/shipments/manifestCreate manifest
You implement this endpoint (optional). Carriyo calls it to generate a manifest for a batch of shipments sharing a pickup location and date.
This is an optional endpoint for the carrier. If manifesting is not supported by the carrier, then the implementation of this endpoint can be skipped.
Carriyo employs the manifest endpoint to facilitate generation of manifests for designated shipments. The shipments included in the manifest will share a common pickup location and a scheduled pickup date.
In the request, Carriyo includes essential manifest details, encompassing:
Shipment tracking numbers
Scheduled date and time slot
Pickup Location
In response to this request, the carrier will provide a unique pickup identifier for the manifest.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: manifest-requestrequiredResponses
Need the full machine-readable spec? Download the OpenAPI document →
Shipments
Shipment-related endpoints the carrier hosts and Carriyo calls: create, cancel, fetch label, batch tracking, schedule collection. Carriyo authenticates with the credentials issued during onboarding.
5 operations · 0 objects
/shipmentsCreate shipment
You implement this endpoint. Carriyo calls it to book a new shipment with your carrier service.
Carriyo will use the create shipment endpoint to book a new shipment with the carrier, by providing all the essential information such as:
Merchant's Order and Shipment reference
Pickup details - name, contact information and address
Dropoff details - name, contact information and address
Item details
Parcel details
Any custom information needed by the carrier, such as account number, service type etc
The carrier will respond with a unique tracking number and optionally provide the PDF and ZPL labels in the response, either encoded as hexadecimal or as download URLs.
While both binary and URL options are supported, we recommend sending the labels directly in the response as binary hexadecimal data for optimal integration.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: create-shipment-requestrequired- References for a shipment, provided by the merchant. The
partner_order_referenceis mandatory but not required to be unique. It is usually the customer facing order number. Thepartner_shipment_referencemust be unique for every shipment. It is mandatory, but is copied frompartner_order_referenceif it is not provided. If a single order has multiple shipments, then they will share thepartner_order_referencebut have uniquepartner_shipment_reference. - The delivery options chosen for the shipment, including the delivery type and schedule. Provide the
scheduled_fromandscheduled_toto choose the scheduled date along with start and end time. Example: "collection": { "scheduled_from": "2022-01-01'T'10:00:00.000Z", "scheduled_to": "2022-01-01'T'12:00:00.000Z" }
Responses
The body matches any one of the following schemas:
create-shipment-response
Need the full machine-readable spec? Download the OpenAPI document →
/shipments/historyShipment tracking
You implement this endpoint. Carriyo calls it to retrieve the full history of status events for a batch of shipments, typically as a fallback when real-time status webhooks have been missed.
Ensuring that Carriyo maintains the most up-to-date shipment status is of paramount importance, benefiting both the merchant and their end customers.
Carriyo uses the batch tracking endpoint to retrieve the full history of status events for the specified shipments. The endpoint serves as a fallback for real-time status updates, particularly for shipments suspected of falling out of sync with the carrier's data.
To maximise efficiency, Carriyo will pass a list of tracking numbers to track multiple shipments (up to 20) in a single API call.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: batch-tracking-requestrequiredResponses
Need the full machine-readable spec? Download the OpenAPI document →
/shipments/{tracking-number}/schedule-collectionSchedule collection
You implement this endpoint (optional). Carriyo calls it to schedule a pickup for a shipment.
This operation is optional. If your carrier service doesn't support collection scheduling, you can skip implementing it.
Carriyo employs the schedule collection endpoint to facilitate carrier pick-up arrangements for a designated shipment.
In the request, Carriyo includes essential collection details, encompassing:
Shipment tracking number
Scheduled date and time slot
In response to this request, the carrier will provide unique pickup identifier.
The carrier will respond with a unique pickup id.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| tracking-number | string | Yes | — |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: scheduled-collection-requestrequiredResponses
Need the full machine-readable spec? Download the OpenAPI document →
/shipments/{tracking-number}/labelFetch label
You implement this endpoint. Carriyo calls it to fetch the shipping label by tracking number, for when labels were not returned inline in the create-shipment response.
Carriyo utilises this endpoint to obtain a shipment label by providing the tracking number. This is useful when the carrier fails to supply the label information alongside the create shipment response.
The response is expected to contain supported labels, which may be in PDF and/or ZPL format. These labels can be provided either as hexadecimal-encoded data or as URLs to download the label.
While both binary and URL options are supported, we recommend sending the labels directly in the response as binary hexadecimal data for optimal integration.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| tracking-number | string | Yes | — |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
Responses
Need the full machine-readable spec? Download the OpenAPI document →
/shipments/{tracking-number}/cancelShipment cancellation
You implement this endpoint. Carriyo calls it to cancel a previously-booked shipment.
Carriyo will use the cancel endpoint to cancel a specific shipment that has not yet been shipped.
Carriyo will use the carrier's unique tracking number to cancel the shipment.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| tracking-number | string | Yes | — |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
Responses
Need the full machine-readable spec? Download the OpenAPI document →
Status Update Webhook
Hosted by Carriyo. The carrier calls this endpoint to push real-time shipment status updates. The carrier authenticates with the API key Carriyo issues during onboarding. This is the only operation in this spec where the carrier is the client.
1 operation · 0 objects
/{carrier}/update-statusStatus update webhook
Carriyo hosts this endpoint. Your system calls it whenever a shipment status changes.
The Carriyo webhook endpoint acts as the primary link for carriers to transmit real-time status updates to Carriyo.
The carrier's system will call the endpoint for each status update as and when they happen. It is important for the carrier to include the exact date and time of the event for Carriyo to uniquely identify each update.
This feature guarantees that Carriyo and its users consistently receive current and precise details regarding the shipment's progress and location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| carrier | string | Yes | — |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| x-api-key | YOUR-API-KEY | Yes | API key the **carrier** issues to Carriyo during onboarding, sent on every Carriyo → carrier request. For the `status-update-webhook` operation (carrier → Carriyo direction), the same scheme is used but the key is issued by Carriyo to the carrier, as clarified in the operation description. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: callback-requestrequiredResponses
Need the full machine-readable spec? Download the OpenAPI document →