API reference
Shipments
Create one simulated booking, list your shipments, retrieve current state or request cancellation. POST creation requires an idempotency key. Live funding and carrier booking remain unavailable.
Set PX_BASE_URL to http://127.0.0.1:4010/v1. Intended live host: https://api.parcelxpert.com/v1. Live requests are not released. Set PX_IDEMPOTENCY_KEY to one stored unique value per write; replace all example quote and shipment IDs with returned IDs.
Create shipment
Creates one simulated booking with a PX-TEST reference and void A4 PDF. Route and parcels must exactly match the quote. International shipments require customs. Collection services require collection details. Live creation is blocked pending account billing and fenced domain adapter. Production access remains disabled. Unreleased server adapters and database controls are under certification; hosted test credentials are unavailable.
Required scope: shipments:write
Parameters
| Name | Location | Meaning |
|---|---|---|
| Idempotency-Key required | header | 8–128 ASCII letters, digits, underscore, dot, colon or hyphen. Account/environment/operation scoped; never reuse for a different request. Sandbox retains keys until reset. |
Request body
| Field | Type | Description |
|---|---|---|
quote_idrequired | string | Tenant-owned, unexpired PX quote ID. Pattern: ^qt_[a-f0-9-]{36}$ |
senderrequired | object | |
sender.namerequired | string | Contact full name. |
sender.companyoptional | string | Company name. |
sender.line1required | string | Street address. |
sender.line2optional | string | Additional address line. |
sender.cityrequired | string | Town/city. |
sender.postcoderequired | string | Postcode matching quote. |
sender.countryrequired | string | ISO 3166-1 alpha-2 uppercase country code. Pattern: ^[A-Z]{2}$ |
sender.emailrequired | string | Contact email. |
sender.phonerequired | string | International contact telephone number. |
recipientrequired | object | |
recipient.namerequired | string | Contact full name. |
recipient.companyoptional | string | Company name. |
recipient.line1required | string | Street address. |
recipient.line2optional | string | Additional address line. |
recipient.cityrequired | string | Town/city. |
recipient.postcoderequired | string | Postcode matching quote. |
recipient.countryrequired | string | ISO 3166-1 alpha-2 uppercase country code. Pattern: ^[A-Z]{2}$ |
recipient.emailrequired | string | Contact email. |
recipient.phonerequired | string | International contact telephone number. |
parcelsrequired | array | Max items: 100 |
parcels[].weightrequired | number | Weight in kilograms. |
parcels[].lengthrequired | number | Dimension in centimetres. |
parcels[].widthrequired | number | Dimension in centimetres. |
parcels[].heightrequired | number | Dimension in centimetres. |
contentsrequired | string | Description of contents. |
customsoptional | object | |
customs.itemsrequired | array | Max items: 100 |
customs.items[].descriptionrequired | string | Specific goods description; avoid generic terms. |
customs.items[].quantityrequired | integer | Minimum: 1 |
customs.items[].valuerequired | number | |
customs.items[].weightrequired | number | Unit weight in kilograms. |
customs.items[].hs_coderequired | string | 6 to 10 tariff digits. Sandbox validates shape only. Pattern: ^\d{6,10}$ |
customs.items[].country_of_originrequired | string | ISO 3166-1 alpha-2 uppercase country code. Pattern: ^[A-Z]{2}$ |
customs.currencyrequired | string | Value currency. Pattern: ^[A-Z]{3}$ |
customs.reason_for_exportrequired | string | Values: sale, gift, return, sample, personal_effects, other |
customs.termsrequired | string | Sandbox supports DAP only. Live DDP requires service eligibility and duty settlement; unavailable until reviewed. Values: DAP, DDP |
customs.eorioptional | string | Sender EORI when required. |
customs.recipient_eorioptional | string | Recipient EORI when required. |
customs.vat_idoptional | string | Sender VAT identifier. |
customs.ioss_idoptional | string | IOSS identifier when eligible. |
collectionoptional | object | |
collection.daterequired | string | Collection date in origin local calendar. |
collection.ready_timerequired | string | Origin local time HH:mm. Pattern: ^([01]\d|2[0-3]):[0-5]\d$ |
collection.close_timerequired | string | Origin local closing time HH:mm, later than ready_time. Pattern: ^([01]\d|2[0-3]):[0-5]\d$ |
merchant_referenceoptional | string | Your order/reference for search. |
shipment_referenceoptional | string | Your shipment reference. |
delivery_instructionsoptional | string | Instructions; live support varies by service. |
order_idoptional | string | Optional imported order owned by this account. |
declared_valueoptional | number | Declared contents value in quote currency. Required by the unreleased live domestic PX booking adapter; optional in the local fixture sandbox. International API creation remains disabled pending customs certification. |
Response schema
| Field | Type | Description |
|---|---|---|
idrequired | string | Stable PX shipment ID. |
referencerequired | string | PX reference; sandbox uses PX-TEST-000001. |
statusrequired | string | Values: created, booking_pending, booked, label_ready, collected, in_transit, out_for_delivery, ready_for_collection, delivered, returned, failed, exception, cancellation_pending, cancelled |
courierrequired | string | Courier name. |
servicerequired | string | Service name. |
tracking_numberrequired | string | null | |
label_availablerequired | boolean | |
label_formatsrequired | array | |
collectionrequired | object | null | |
merchant_referencerequired | string | null | |
shipment_referencerequired | string | null | |
created_atrequired | string | ISO 8601 timestamp with timezone. Responses use UTC Z. |
HTTP responses and errors
| 201 | Resource created in local sandbox. No live purchase. |
| 400 | Malformed JSON, cursor or idempotency header. |
| 401 | Missing, invalid, expired or revoked key. |
| 403 | Required scope not granted. |
| 404 | Resource unavailable in this account and environment, or label format unavailable. |
| 405 | Method not supported. |
| 409 | Idempotency conflict, request in progress, expired/mismatched quote or cancellation unavailable. |
| 413 | Body exceeds 256 KiB. |
| 422 | Schema or capability validation failure. |
| 429 | Enforced sandbox rate limit reached. |
| 500 | Unexpected PX failure. |
| 502 | Provider operation not confirmed. No blind booking retry. |
| 503 | Provider unavailable or live API not released. |
Request example
curl --request POST \
--url "$PX_BASE_URL/shipments" \
--header "Authorization: Bearer $PX_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: $PX_IDEMPOTENCY_KEY" \
--data '{
"quote_id": "qt_00000000-0000-4000-8000-000000000001",
"sender": {
"name": "Test Sender",
"line1": "1 Test Street",
"city": "Northampton",
"postcode": "NN1 1AA",
"country": "GB",
"email": "sender@example.com",
"phone": "+441234567890"
},
"recipient": {
"name": "Test Recipient",
"line1": "1 Test Street",
"city": "London",
"postcode": "SW1A 1AA",
"country": "GB",
"email": "recipient@example.com",
"phone": "+441234567890"
},
"parcels": [
{
"weight": 2,
"length": 30,
"width": 20,
"height": 15
}
],
"contents": "Cotton T-shirts",
"merchant_reference": "ORDER-1001"
}'Response example
{
"id": "shp_00000000-0000-4000-8000-000000000002",
"reference": "PX-TEST-000001",
"status": "booked",
"courier": "PX Sandbox Courier",
"service": "Test drop-off",
"tracking_number": "TEST001",
"label_available": true,
"label_formats": [
"a4"
],
"collection": null,
"merchant_reference": "ORDER-1001",
"shipment_reference": null,
"created_at": "2026-10-04T10:25:00Z"
}List shipments
Account and environment scoped; creation descending with ID tiebreaker. Cursors are filter-bound. No total count is promised. Production access remains disabled. Unreleased server adapters and database controls are under certification; hosted test credentials are unavailable.
Required scope: shipments:read
Parameters
| Name | Location | Meaning |
|---|---|---|
| limit optional | query | Page size. Default 20; maximum 100. |
| cursor optional | query | Opaque signed next_cursor. Preserve filters between pages. |
| status optional | query | Exact normalized status. |
| created_from optional | query | Inclusive creation timestamp. |
| created_to optional | query | Inclusive creation timestamp. |
| courier optional | query | Exact courier match. |
| tracking_number optional | query | Exact tracking_number match. |
| merchant_reference optional | query | Exact merchant_reference match. |
Response schema
| Field | Type | Description |
|---|---|---|
datarequired | array | |
data[].idrequired | string | Stable PX shipment ID. |
data[].referencerequired | string | PX reference; sandbox uses PX-TEST-000001. |
data[].statusrequired | string | Values: created, booking_pending, booked, label_ready, collected, in_transit, out_for_delivery, ready_for_collection, delivered, returned, failed, exception, cancellation_pending, cancelled |
data[].courierrequired | string | Courier name. |
data[].servicerequired | string | Service name. |
data[].tracking_numberrequired | string | null | |
data[].label_availablerequired | boolean | |
data[].label_formatsrequired | array | |
data[].collectionrequired | object | null | |
data[].merchant_referencerequired | string | null | |
data[].shipment_referencerequired | string | null | |
data[].created_atrequired | string | ISO 8601 timestamp with timezone. Responses use UTC Z. |
paginationrequired | object | |
pagination.limitrequired | integer | Minimum: 1 |
pagination.next_cursorrequired | string | null | |
pagination.has_morerequired | boolean |
HTTP responses and errors
| 200 | Success. |
| 400 | Malformed JSON, cursor or idempotency header. |
| 401 | Missing, invalid, expired or revoked key. |
| 403 | Required scope not granted. |
| 404 | Resource unavailable in this account and environment, or label format unavailable. |
| 405 | Method not supported. |
| 409 | Idempotency conflict, request in progress, expired/mismatched quote or cancellation unavailable. |
| 413 | Body exceeds 256 KiB. |
| 422 | Schema or capability validation failure. |
| 429 | Enforced sandbox rate limit reached. |
| 500 | Unexpected PX failure. |
| 502 | Provider operation not confirmed. No blind booking retry. |
| 503 | Provider unavailable or live API not released. |
Request example
curl --request GET \
--url "$PX_BASE_URL/shipments" \
--header "Authorization: Bearer $PX_API_KEY"Response example
{
"data": [
{
"id": "shp_00000000-0000-4000-8000-000000000002",
"reference": "PX-TEST-000001",
"status": "booked",
"courier": "PX Sandbox Courier",
"service": "Test drop-off",
"tracking_number": "TEST001",
"label_available": true,
"label_formats": [
"a4"
],
"collection": null,
"merchant_reference": "ORDER-1001",
"shipment_reference": null,
"created_at": "2026-10-04T10:25:00Z"
}
],
"pagination": {
"limit": 20,
"next_cursor": null,
"has_more": false
}
}Retrieve shipment
Returns the current normalized PX shipment. Foreign-account IDs return 404. Production access remains disabled. Unreleased server adapters and database controls are under certification; hosted test credentials are unavailable.
Required scope: shipments:read
Parameters
| Name | Location | Meaning |
|---|---|---|
| id required | path | PX resource ID, scoped to account and environment. |
Response schema
| Field | Type | Description |
|---|---|---|
idrequired | string | Stable PX shipment ID. |
referencerequired | string | PX reference; sandbox uses PX-TEST-000001. |
statusrequired | string | Values: created, booking_pending, booked, label_ready, collected, in_transit, out_for_delivery, ready_for_collection, delivered, returned, failed, exception, cancellation_pending, cancelled |
courierrequired | string | Courier name. |
servicerequired | string | Service name. |
tracking_numberrequired | string | null | |
label_availablerequired | boolean | |
label_formatsrequired | array | |
collectionrequired | object | null | |
merchant_referencerequired | string | null | |
shipment_referencerequired | string | null | |
created_atrequired | string | ISO 8601 timestamp with timezone. Responses use UTC Z. |
HTTP responses and errors
| 200 | Success. |
| 400 | Malformed JSON, cursor or idempotency header. |
| 401 | Missing, invalid, expired or revoked key. |
| 403 | Required scope not granted. |
| 404 | Resource unavailable in this account and environment, or label format unavailable. |
| 405 | Method not supported. |
| 409 | Idempotency conflict, request in progress, expired/mismatched quote or cancellation unavailable. |
| 413 | Body exceeds 256 KiB. |
| 422 | Schema or capability validation failure. |
| 429 | Enforced sandbox rate limit reached. |
| 500 | Unexpected PX failure. |
| 502 | Provider operation not confirmed. No blind booking retry. |
| 503 | Provider unavailable or live API not released. |
Request example
curl --request GET \
--url "$PX_BASE_URL/shipments/$PX_SHIPMENT_ID" \
--header "Authorization: Bearer $PX_API_KEY"Response example
{
"id": "shp_00000000-0000-4000-8000-000000000002",
"reference": "PX-TEST-000001",
"status": "booked",
"courier": "PX Sandbox Courier",
"service": "Test drop-off",
"tracking_number": "TEST001",
"label_available": true,
"label_formats": [
"a4"
],
"collection": null,
"merchant_reference": "ORDER-1001",
"shipment_reference": null,
"created_at": "2026-10-04T10:25:00Z"
}Request cancellation
Sandbox confirms cancellation only before transit. Provider failures are 502; they never become success. Live cancellation may require 202 cancellation_pending/manual processing and does not imply a Stripe refund. Live handler remains unavailable. Production access remains disabled. Unreleased server adapters and database controls are under certification; hosted test credentials are unavailable.
Required scope: shipments:write
Parameters
| Name | Location | Meaning |
|---|---|---|
| id required | path | PX resource ID, scoped to account and environment. |
| Idempotency-Key required | header | 8–128 ASCII letters, digits, underscore, dot, colon or hyphen. Account/environment/operation scoped; never reuse for a different request. Sandbox retains keys until reset. |
Request body
| Field | Type | Description |
|---|---|---|
reasonoptional | string | Optional cancellation reason. |
Response schema
| Field | Type | Description |
|---|---|---|
shipment_idrequired | string | PX shipment ID. |
referencerequired | string | PX reference. |
statusrequired | string | Only confirmed cancellation is cancelled; manual requests are pending. Refund is separate. Values: cancelled, cancellation_pending |
HTTP responses and errors
| 200 | Success. |
| 202 | Reserved live outcome: cancellation request accepted for manual handling, not confirmed. Not emitted by sandbox. |
| 400 | Malformed JSON, cursor or idempotency header. |
| 401 | Missing, invalid, expired or revoked key. |
| 403 | Required scope not granted. |
| 404 | Resource unavailable in this account and environment, or label format unavailable. |
| 405 | Method not supported. |
| 409 | Idempotency conflict, request in progress, expired/mismatched quote or cancellation unavailable. |
| 413 | Body exceeds 256 KiB. |
| 422 | Schema or capability validation failure. |
| 429 | Enforced sandbox rate limit reached. |
| 500 | Unexpected PX failure. |
| 502 | Provider operation not confirmed. No blind booking retry. |
| 503 | Provider unavailable or live API not released. |
Request example
curl --request POST \
--url "$PX_BASE_URL/shipments/$PX_SHIPMENT_ID/cancel" \
--header "Authorization: Bearer $PX_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: $PX_IDEMPOTENCY_KEY" \
--data '{
"reason": "Order cancelled"
}'Response example
{
"shipment_id": "shp_00000000-0000-4000-8000-000000000002",
"reference": "PX-TEST-000001",
"status": "cancelled"
}