API reference
Shipments
Buy labels, download them, track parcels, void labels and make return labels.
Endpoints
- GET /returns/{id}
- GET /shipments
- POST /shipments
- GET /shipments/{id}
- POST /shipments/{id}/archive
- POST /shipments/{id}/cancel
- GET /shipments/{id}/comments
- POST /shipments/{id}/comments
- DELETE /shipments/{id}/comments/{comment_id}
- GET /shipments/{id}/customs-invoice
- GET /shipments/{id}/label
- POST /shipments/{id}/return
- GET /shipments/{id}/timeline
- GET /shipments/{id}/tracking
- GET /shipments/counts
- GET /shipments/ids
Get a return label
GET /v1/returns/{id}
A return created with POST /v1/shipments/{id}/return.
Path parameters
id• Required string
Response in data
created_at• Required timestampWhen it was created (ISO 8601, UTC).
id• Required uuidoriginal_shipment_id• Required uuidreturn_shipment_id• Required uuidreturn_type• Required stringupdated_at• Required timestampWhen it last changed (ISO 8601, UTC).
notesstringFree-text notes.
reasonstring
curl "https://api.parcelhub.ca/v1/returns/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"created_at": "2026-10-31T15:04:05Z",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"notes": "string",
"original_shipment_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"reason": "string",
"return_shipment_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"return_type": "string",
"updated_at": "2026-10-31T15:04:05Z"
},
"request_id": "01JBX7Q2…"
}List shipments
GET /v1/shipments
Purchased shipments, newest first. Filter by status, dates, source or a search (order number, tracking number, recipient name, company or city). Page with limit and offset.
Query parameters
statusstringOnly shipments with this status.
limitintegerMost results to return.
offsetintegerResults to skip, for paging.
fromdateCreated on or after this day (
YYYY-MM-DD, UTC).todateCreated on or before this day (
YYYY-MM-DD, UTC).is_returnbooleantruefor return shipments only,falseto leave them out.archivedbooleantruefor the Archived list. Archived shipments are left out otherwise.sourcestringOnly shipments from this source:
manual,csv,xlsx,apior a store platform such asshopify.searchstringMatches order number, tracking number, or the recipient's name, company or city.
Response in data
items• Required array of objectsEach item · 18
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyid• Required uuidis_return• Required booleanorder_number• Required stringservice• Required stringsource• Required stringWhere the shipment came from. Leave out (it becomes
manual) or name your integration, e.g.api.status• Required stringto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
created_by_namestringreturn_ofuuidsource_namestringA name for that source, e.g. your app's name.
tracking_numberstringThe carrier's tracking number.
totalinteger
curl "https://api.parcelhub.ca/v1/shipments" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"items": [
{
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_name": "string",
"currency": "CAD",
"final_rate_cents": 1299,
"from_address": null,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"order_number": "PH-104233",
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"source": "manual",
"source_name": "string",
"status": "string",
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784"
}
],
"total": 1
},
"request_id": "01JBX7Q2…"
}Buy a label
POST /v1/shipments
Buys a label for one of the rates from POST /v1/rates and charges the wallet. Send the same addresses and packages you quoted, the chosen carrier, service_code and service_name, and the quote_id. Shipments that cross a border need customs_declaration_id. Send an Idempotency-Key header (any unique string per purchase): retrying with the same key returns the first shipment instead of buying a second label. Returns 409 (error.message is insufficient_funds) when the wallet does not cover the price: top up and retry.
Confirm with the account owner before calling it.
Headers
Idempotency-KeystringAny unique string per purchase. A retry with the same key returns the first result instead of buying again.
Request body
carrier• Required stringThe
carrierof the chosen rate, exactly asPOST /v1/ratesreturned it.from• Required objectShip-from address.
Fields · 11
city• Required stringCity.
country• Required stringTwo-letter country code, e.g.
CA,US.name• Required stringpostal_code• Required stringPostal or ZIP code.
state• Required stringProvince or state code, e.g.
ON,BC,NY.street• Required stringStreet address.
companystringCompany name.
emailstringEmail address.
is_residentialbooleanTrue for a home address. Some carriers charge more for residential delivery.
line2stringApartment, suite or unit.
phonestringPhone number. Carriers need one for the recipient on most international and express services.
packages• Required array of objectsOne entry per box.
Each item · 10
dimension_unit• Required stringinorcm.height• Required numberHeight, in
dimension_unit.items• Required array of objectsWhat is in this box (optional for domestic shipments).
Each item · 8
currency• Required stringThree-letter currency code, e.g.
CAD.description• Required stringWhat the item is.
quantity• Required integerHow many.
unit_value_cents• Required integerValue of one unit, in cents.
customs_descriptionstringDescription for customs, if different.
hs_codestringHarmonized System code.
origin_countrystringTwo-letter code of the country where the item was made.
skustringYour product code.
length• Required numberLength, in
dimension_unit.weight• Required numberWeight of the box with its contents, in
weight_unit.weight_unit• Required stringlborkg.width• Required numberWidth, in
dimension_unit.box_iduuidA standard box from
GET /v1/package-boxes, if one was used.namestringpreset_iduuidA saved box from
GET /v1/package-presets, if one was used.
service_code• Required stringThe
service_codeof the chosen rate.service_name• Required stringThe
service_nameof the chosen rate.to• Required objectShip-to address.
Fields · 11
city• Required stringCity.
country• Required stringTwo-letter country code, e.g.
CA,US.name• Required stringpostal_code• Required stringPostal or ZIP code.
state• Required stringProvince or state code, e.g.
ON,BC,NY.street• Required stringStreet address.
companystringCompany name.
emailstringEmail address.
is_residentialbooleanTrue for a home address. Some carriers charge more for residential delivery.
line2stringApartment, suite or unit.
phonestringPhone number. Carriers need one for the recipient on most international and express services.
customs_declaration_iduuidA customs declaration from
POST /v1/customs/declarations. Needed for shipments that cross a border.delivery_instructionsstringInstructions for the driver.
discount_codestringA discount code to apply.
email_notificationsbooleanEmail tracking updates to the recipient.
label_sizestringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.quote_iduuidThe
quote_idfrom thePOST /v1/ratesresponse the chosen rate came from.reference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
ship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.sourcestringWhere the shipment came from. Leave out (it becomes
manual) or name your integration, e.g.api.source_namestringA name for that source, e.g. your app's name.
Response in data
archived• Required booleantrueto archive (the default),falseto bring it back.base_rate_cents• Required integerLabel price before discount and tax, in cents.
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.discount_cents• Required integerDiscount applied, in cents.
duties_cents• Required integerDestination duties and taxes prepaid with this label (DDP), when offered.
email_notifications• Required booleanEmail tracking updates to the recipient.
final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyhas_customs_invoice• Required booleanid• Required uuidis_return• Required booleanlabel_size• Required stringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.order_number• Required stringpackages• Required anyOne entry per box.
refund_pending• Required booleanrefund_withheld• Required booleanrefunded_cents• Required integerservice• Required stringstatus• Required stringtax_cents• Required integerSales tax, in cents.
tax_rate_bps• Required integerto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
updated_at• Required timestampWhen it last changed (ISO 8601, UTC).
batchobjectFields · 3
batch_number• Required stringid• Required uuidname• Required string
cancelled_attimestampcreated_by_emailstringcreated_by_namestringdelivery_instructionsstringInstructions for the driver.
paid_attimestampreference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
refund_held_untiltimestampreturn_ofuuidship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.tax_jurisdictionstringtracking_numberstringThe carrier's tracking number.
wallet_transaction_iduuid
curl -X POST "https://api.parcelhub.ca/v1/shipments" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"carrier": "ups",
"delivery_instructions": "string",
"discount_code": "string",
"email_notifications": true,
"from": {
"city": "Toronto",
"company": "Maple Goods Inc.",
"country": "CA",
"email": "[email protected]",
"is_residential": false,
"line2": "Suite 400",
"name": "Alex Martin",
"phone": "+1 416 555 0100",
"postal_code": "M5V 2T6",
"state": "ON",
"street": "123 King St W"
},
"label_size": "thermal",
"packages": [
{
"dimension_unit": "cm",
"height": 10,
"items": [
{}
],
"length": 30,
"name": "Alex Martin",
"weight": 2.5,
"weight_unit": "kg",
"width": 20
}
],
"reference_number": "string",
"service_code": "service_code",
"service_name": "UPS Standard",
"ship_date": "2026-11-03",
"signature_option": "none",
"source": "manual",
"source_name": "string",
"to": {
"city": "Toronto",
"company": "Maple Goods Inc.",
"country": "CA",
"email": "[email protected]",
"is_residential": false,
"line2": "Suite 400",
"name": "Alex Martin",
"phone": "+1 416 555 0100",
"postal_code": "M5V 2T6",
"state": "ON",
"street": "123 King St W"
}
}'{
"ok": true,
"data": {
"archived": true,
"base_rate_cents": 1299,
"batch": {
"batch_number": "string",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"name": "Alex Martin"
},
"cancelled_at": "2026-10-31T15:04:05Z",
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_email": "[email protected]",
"created_by_name": "string",
"currency": "CAD",
"delivery_instructions": "string",
"discount_cents": 1299,
"duties_cents": 1299,
"email_notifications": true,
"final_rate_cents": 1299,
"from_address": null,
"has_customs_invoice": false,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"label_size": "thermal",
"order_number": "PH-104233",
"packages": null,
"paid_at": "2026-10-31T15:04:05Z",
"reference_number": "string",
"refund_held_until": "2026-10-31T15:04:05Z",
"refund_pending": true,
"refund_withheld": true,
"refunded_cents": 1299,
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"ship_date": "2026-11-03",
"signature_option": "none",
"status": "string",
"tax_cents": 1299,
"tax_jurisdiction": "string",
"tax_rate_bps": 1,
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784",
"updated_at": "2026-10-31T15:04:05Z",
"wallet_transaction_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
},
"request_id": "01JBX7Q2…"
}Get a shipment
GET /v1/shipments/{id}
One shipment in full: addresses, packages, carrier and service, charges, tracking number and status.
Path parameters
id• Required string
Response in data
archived• Required booleantrueto archive (the default),falseto bring it back.base_rate_cents• Required integerLabel price before discount and tax, in cents.
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.discount_cents• Required integerDiscount applied, in cents.
duties_cents• Required integerDestination duties and taxes prepaid with this label (DDP), when offered.
email_notifications• Required booleanEmail tracking updates to the recipient.
final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyhas_customs_invoice• Required booleanid• Required uuidis_return• Required booleanlabel_size• Required stringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.order_number• Required stringpackages• Required anyOne entry per box.
refund_pending• Required booleanrefund_withheld• Required booleanrefunded_cents• Required integerservice• Required stringstatus• Required stringtax_cents• Required integerSales tax, in cents.
tax_rate_bps• Required integerto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
updated_at• Required timestampWhen it last changed (ISO 8601, UTC).
batchobjectFields · 3
batch_number• Required stringid• Required uuidname• Required string
cancelled_attimestampcreated_by_emailstringcreated_by_namestringdelivery_instructionsstringInstructions for the driver.
paid_attimestampreference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
refund_held_untiltimestampreturn_ofuuidship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.tax_jurisdictionstringtracking_numberstringThe carrier's tracking number.
wallet_transaction_iduuid
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"archived": true,
"base_rate_cents": 1299,
"batch": {
"batch_number": "string",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"name": "Alex Martin"
},
"cancelled_at": "2026-10-31T15:04:05Z",
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_email": "[email protected]",
"created_by_name": "string",
"currency": "CAD",
"delivery_instructions": "string",
"discount_cents": 1299,
"duties_cents": 1299,
"email_notifications": true,
"final_rate_cents": 1299,
"from_address": null,
"has_customs_invoice": false,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"label_size": "thermal",
"order_number": "PH-104233",
"packages": null,
"paid_at": "2026-10-31T15:04:05Z",
"reference_number": "string",
"refund_held_until": "2026-10-31T15:04:05Z",
"refund_pending": true,
"refund_withheld": true,
"refunded_cents": 1299,
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"ship_date": "2026-11-03",
"signature_option": "none",
"status": "string",
"tax_cents": 1299,
"tax_jurisdiction": "string",
"tax_rate_bps": 1,
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784",
"updated_at": "2026-10-31T15:04:05Z",
"wallet_transaction_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
},
"request_id": "01JBX7Q2…"
}Archive a shipment
POST /v1/shipments/{id}/archive
Moves a shipment to the Archived list, or back with archived: false. Nothing changes with the carrier.
Path parameters
id• Required string
Request body
archivedbooleantrueto archive (the default),falseto bring it back.
Response in data
archived• Required booleantrueto archive (the default),falseto bring it back.base_rate_cents• Required integerLabel price before discount and tax, in cents.
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.discount_cents• Required integerDiscount applied, in cents.
duties_cents• Required integerDestination duties and taxes prepaid with this label (DDP), when offered.
email_notifications• Required booleanEmail tracking updates to the recipient.
final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyhas_customs_invoice• Required booleanid• Required uuidis_return• Required booleanlabel_size• Required stringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.order_number• Required stringpackages• Required anyOne entry per box.
refund_pending• Required booleanrefund_withheld• Required booleanrefunded_cents• Required integerservice• Required stringstatus• Required stringtax_cents• Required integerSales tax, in cents.
tax_rate_bps• Required integerto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
updated_at• Required timestampWhen it last changed (ISO 8601, UTC).
batchobjectFields · 3
batch_number• Required stringid• Required uuidname• Required string
cancelled_attimestampcreated_by_emailstringcreated_by_namestringdelivery_instructionsstringInstructions for the driver.
paid_attimestampreference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
refund_held_untiltimestampreturn_ofuuidship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.tax_jurisdictionstringtracking_numberstringThe carrier's tracking number.
wallet_transaction_iduuid
curl -X POST "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/archive" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"archived": true
}'{
"ok": true,
"data": {
"archived": true,
"base_rate_cents": 1299,
"batch": {
"batch_number": "string",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"name": "Alex Martin"
},
"cancelled_at": "2026-10-31T15:04:05Z",
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_email": "[email protected]",
"created_by_name": "string",
"currency": "CAD",
"delivery_instructions": "string",
"discount_cents": 1299,
"duties_cents": 1299,
"email_notifications": true,
"final_rate_cents": 1299,
"from_address": null,
"has_customs_invoice": false,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"label_size": "thermal",
"order_number": "PH-104233",
"packages": null,
"paid_at": "2026-10-31T15:04:05Z",
"reference_number": "string",
"refund_held_until": "2026-10-31T15:04:05Z",
"refund_pending": true,
"refund_withheld": true,
"refunded_cents": 1299,
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"ship_date": "2026-11-03",
"signature_option": "none",
"status": "string",
"tax_cents": 1299,
"tax_jurisdiction": "string",
"tax_rate_bps": 1,
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784",
"updated_at": "2026-10-31T15:04:05Z",
"wallet_transaction_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
},
"request_id": "01JBX7Q2…"
}Void a label
POST /v1/shipments/{id}/cancel
Voids an unused label with the carrier and refunds it to the wallet. Some carriers refund only after they confirm the label was not used. Cannot be undone.
Path parameters
id• Required string
Request body
reasonstringWhy the label is being voided.
Response in data
archived• Required booleantrueto archive (the default),falseto bring it back.base_rate_cents• Required integerLabel price before discount and tax, in cents.
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.discount_cents• Required integerDiscount applied, in cents.
duties_cents• Required integerDestination duties and taxes prepaid with this label (DDP), when offered.
email_notifications• Required booleanEmail tracking updates to the recipient.
final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyhas_customs_invoice• Required booleanid• Required uuidis_return• Required booleanlabel_size• Required stringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.order_number• Required stringpackages• Required anyOne entry per box.
refund_pending• Required booleanrefund_withheld• Required booleanrefunded_cents• Required integerservice• Required stringstatus• Required stringtax_cents• Required integerSales tax, in cents.
tax_rate_bps• Required integerto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
updated_at• Required timestampWhen it last changed (ISO 8601, UTC).
batchobjectFields · 3
batch_number• Required stringid• Required uuidname• Required string
cancelled_attimestampcreated_by_emailstringcreated_by_namestringdelivery_instructionsstringInstructions for the driver.
paid_attimestampreference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
refund_held_untiltimestampreturn_ofuuidship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.tax_jurisdictionstringtracking_numberstringThe carrier's tracking number.
wallet_transaction_iduuid
curl -X POST "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/cancel" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "string"
}'{
"ok": true,
"data": {
"archived": true,
"base_rate_cents": 1299,
"batch": {
"batch_number": "string",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"name": "Alex Martin"
},
"cancelled_at": "2026-10-31T15:04:05Z",
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_email": "[email protected]",
"created_by_name": "string",
"currency": "CAD",
"delivery_instructions": "string",
"discount_cents": 1299,
"duties_cents": 1299,
"email_notifications": true,
"final_rate_cents": 1299,
"from_address": null,
"has_customs_invoice": false,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"label_size": "thermal",
"order_number": "PH-104233",
"packages": null,
"paid_at": "2026-10-31T15:04:05Z",
"reference_number": "string",
"refund_held_until": "2026-10-31T15:04:05Z",
"refund_pending": true,
"refund_withheld": true,
"refunded_cents": 1299,
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"ship_date": "2026-11-03",
"signature_option": "none",
"status": "string",
"tax_cents": 1299,
"tax_jurisdiction": "string",
"tax_rate_bps": 1,
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784",
"updated_at": "2026-10-31T15:04:05Z",
"wallet_transaction_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
},
"request_id": "01JBX7Q2…"
}List comments
GET /v1/shipments/{id}/comments
Notes on a shipment, from the account and from ParcelHub support.
Path parameters
id• Required string
Response in data
items• Required array of objectsEach item · 9
author_kind• Required stringauthor_name• Required stringbody• Required stringcan_delete• Required booleancreated_at• Required timestampWhen it was created (ISO 8601, UTC).
id• Required uuidis_internal• Required booleanmetadata• Required anysourcestringWhere the shipment came from. Leave out (it becomes
manual) or name your integration, e.g.api.
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/comments" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"items": [
{
"author_kind": "string",
"author_name": "string",
"body": "string",
"can_delete": true,
"created_at": "2026-10-31T15:04:05Z",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_internal": false,
"metadata": null,
"source": "manual"
}
]
},
"request_id": "01JBX7Q2…"
}Add a comment
POST /v1/shipments/{id}/comments
Adds a note to a shipment. ParcelHub support can see it.
Path parameters
id• Required string
Request body
body• Required stringThe note.
Response in data
author_kind• Required stringauthor_name• Required stringbody• Required stringcan_delete• Required booleancreated_at• Required timestampWhen it was created (ISO 8601, UTC).
id• Required uuidis_internal• Required booleanmetadata• Required anysourcestringWhere the shipment came from. Leave out (it becomes
manual) or name your integration, e.g.api.
curl -X POST "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/comments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "string"
}'{
"ok": true,
"data": {
"author_kind": "string",
"author_name": "string",
"body": "string",
"can_delete": true,
"created_at": "2026-10-31T15:04:05Z",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_internal": false,
"metadata": null,
"source": "manual"
},
"request_id": "01JBX7Q2…"
}Delete a comment
DELETE /v1/shipments/{id}/comments/{comment_id}
Deletes a note the account wrote.
Path parameters
id• Required stringcomment_id• Required string
Response in data
See the example on the right.
curl -X DELETE "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/comments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": null,
"request_id": "01JBX7Q2…"
}Download the commercial invoice
GET /v1/shipments/{id}/customs-invoice
A download link for the commercial invoice the carrier made for a cross-border label, valid for about 15 minutes.
Path parameters
id• Required string
Response in data
filename• Required stringurl• Required string
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/customs-invoice" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"filename": "string",
"url": "https://…"
},
"request_id": "01JBX7Q2…"
}Download the label
GET /v1/shipments/{id}/label
A download link for the label PDF, valid for about 15 minutes. For a shipment with several boxes, box returns one box's label.
Path parameters
id• Required string
Query parameters
boxintegerBox number (from 1) to get only that box's label.
Response in data
url• Required stringtracking_numberstringThe carrier's tracking number.
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/label" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"tracking_number": "1Z999AA10123456784",
"url": "https://…"
},
"request_id": "01JBX7Q2…"
}Buy a return label
POST /v1/shipments/{id}/return
Buys a return label for an existing shipment and charges the wallet. By default it goes from the original recipient back to the sender with the same packages; any field you send replaces the original. Send an Idempotency-Key header, as when buying a label.
Confirm with the account owner before calling it.
Path parameters
id• Required string
Headers
Idempotency-KeystringAny unique string per purchase. A retry with the same key returns the first result instead of buying again.
Request body
carrierstringCarrier code, as returned with each rate.
delivery_instructionsstringInstructions for the driver.
discount_codestringA discount code to apply.
email_notificationsbooleanEmail tracking updates to the recipient.
fromobjectShip-from address.
Fields · 11
city• Required stringCity.
country• Required stringTwo-letter country code, e.g.
CA,US.name• Required stringpostal_code• Required stringPostal or ZIP code.
state• Required stringProvince or state code, e.g.
ON,BC,NY.street• Required stringStreet address.
companystringCompany name.
emailstringEmail address.
is_residentialbooleanTrue for a home address. Some carriers charge more for residential delivery.
line2stringApartment, suite or unit.
phonestringPhone number. Carriers need one for the recipient on most international and express services.
label_sizestringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.notesstringNotes for the return.
packagesarray of objectsOne entry per box.
Each item · 10
dimension_unit• Required stringinorcm.height• Required numberHeight, in
dimension_unit.items• Required array of objectsWhat is in this box (optional for domestic shipments).
Each item · 8
currency• Required stringThree-letter currency code, e.g.
CAD.description• Required stringWhat the item is.
quantity• Required integerHow many.
unit_value_cents• Required integerValue of one unit, in cents.
customs_descriptionstringDescription for customs, if different.
hs_codestringHarmonized System code.
origin_countrystringTwo-letter code of the country where the item was made.
skustringYour product code.
length• Required numberLength, in
dimension_unit.weight• Required numberWeight of the box with its contents, in
weight_unit.weight_unit• Required stringlborkg.width• Required numberWidth, in
dimension_unit.box_iduuidA standard box from
GET /v1/package-boxes, if one was used.namestringpreset_iduuidA saved box from
GET /v1/package-presets, if one was used.
reasonstringdamaged,wrong_item,not_as_described,refused,no_longer_neededorother.reference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
return_typestringprint_label(default).service_codestringService code, as returned with each rate. Treat it as opaque and send it back unchanged when you buy: it can carry routing details for that exact rate.
service_namestringService name to show to people.
signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.toobjectShip-to address.
Fields · 11
city• Required stringCity.
country• Required stringTwo-letter country code, e.g.
CA,US.name• Required stringpostal_code• Required stringPostal or ZIP code.
state• Required stringProvince or state code, e.g.
ON,BC,NY.street• Required stringStreet address.
companystringCompany name.
emailstringEmail address.
is_residentialbooleanTrue for a home address. Some carriers charge more for residential delivery.
line2stringApartment, suite or unit.
phonestringPhone number. Carriers need one for the recipient on most international and express services.
Response in data
return• Required objectFields · 8
created_at• Required timestampWhen it was created (ISO 8601, UTC).
id• Required uuidoriginal_shipment_id• Required uuidreturn_shipment_id• Required uuidreturn_type• Required stringupdated_at• Required timestampWhen it last changed (ISO 8601, UTC).
notesstringFree-text notes.
reasonstring
shipment• Required objectFields · 41
archived• Required booleantrueto archive (the default),falseto bring it back.base_rate_cents• Required integerLabel price before discount and tax, in cents.
carrier• Required stringCarrier code, as returned with each rate.
carrier_display_name• Required stringCarrier name to show to people.
created_at• Required timestampWhen it was created (ISO 8601, UTC).
currency• Required stringThree-letter currency code, e.g.
CAD.discount_cents• Required integerDiscount applied, in cents.
duties_cents• Required integerDestination duties and taxes prepaid with this label (DDP), when offered.
email_notifications• Required booleanEmail tracking updates to the recipient.
final_rate_cents• Required integerWhat was charged: price − discount + tax + prepaid duties, in cents.
from_address• Required anyhas_customs_invoice• Required booleanid• Required uuidis_return• Required booleanlabel_size• Required stringthermal(4×6 in) orstandard(8.5×11 in). Defaults to the account's shipping preference.order_number• Required stringpackages• Required anyOne entry per box.
refund_pending• Required booleanrefund_withheld• Required booleanrefunded_cents• Required integerservice• Required stringstatus• Required stringtax_cents• Required integerSales tax, in cents.
tax_rate_bps• Required integerto_address• Required anytracking_available• Required booleanFalse for a service without tracking.
updated_at• Required timestampWhen it last changed (ISO 8601, UTC).
batchobjectFields · 3
batch_number• Required stringid• Required uuidname• Required string
cancelled_attimestampcreated_by_emailstringcreated_by_namestringdelivery_instructionsstringInstructions for the driver.
paid_attimestampreference_numberstringYour reference, e.g. an order number. Printed on the label where the carrier allows.
refund_held_untiltimestampreturn_ofuuidship_datedateDay the parcel will be handed to the carrier (
YYYY-MM-DD). Leave out for today; up to 7 days ahead.signature_optionstringSignature on delivery:
none,requiredoradult. Carriers charge extra for a signature.tax_jurisdictionstringtracking_numberstringThe carrier's tracking number.
wallet_transaction_iduuid
curl -X POST "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/return" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"carrier": "ups",
"delivery_instructions": "string",
"discount_code": "string",
"email_notifications": true,
"from": {
"city": "Toronto",
"company": "Maple Goods Inc.",
"country": "CA",
"email": "[email protected]",
"is_residential": false,
"line2": "Suite 400",
"name": "Alex Martin",
"phone": "+1 416 555 0100",
"postal_code": "M5V 2T6",
"state": "ON",
"street": "123 King St W"
},
"label_size": "thermal",
"notes": "string",
"packages": [
{
"dimension_unit": "cm",
"height": 10,
"items": [
{}
],
"length": 30,
"name": "Alex Martin",
"weight": 2.5,
"weight_unit": "kg",
"width": 20
}
],
"reason": "damaged",
"reference_number": "string",
"return_type": "print_label",
"service_code": "string",
"service_name": "UPS Standard",
"signature_option": "none",
"to": {
"city": "Toronto",
"company": "Maple Goods Inc.",
"country": "CA",
"email": "[email protected]",
"is_residential": false,
"line2": "Suite 400",
"name": "Alex Martin",
"phone": "+1 416 555 0100",
"postal_code": "M5V 2T6",
"state": "ON",
"street": "123 King St W"
}
}'{
"ok": true,
"data": {
"return": {
"created_at": "2026-10-31T15:04:05Z",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"notes": "string",
"original_shipment_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"reason": "string",
"return_shipment_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"return_type": "string",
"updated_at": "2026-10-31T15:04:05Z"
},
"shipment": {
"archived": true,
"base_rate_cents": 1299,
"batch": {
"batch_number": "string",
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"name": "Alex Martin"
},
"cancelled_at": "2026-10-31T15:04:05Z",
"carrier": "ups",
"carrier_display_name": "UPS",
"created_at": "2026-10-31T15:04:05Z",
"created_by_email": "[email protected]",
"created_by_name": "string",
"currency": "CAD",
"delivery_instructions": "string",
"discount_cents": 1299,
"duties_cents": 1299,
"email_notifications": true,
"final_rate_cents": 1299,
"from_address": null,
"has_customs_invoice": false,
"id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"is_return": false,
"label_size": "thermal",
"order_number": "PH-104233",
"packages": null,
"paid_at": "2026-10-31T15:04:05Z",
"reference_number": "string",
"refund_held_until": "2026-10-31T15:04:05Z",
"refund_pending": true,
"refund_withheld": true,
"refunded_cents": 1299,
"return_of": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f",
"service": "string",
"ship_date": "2026-11-03",
"signature_option": "none",
"status": "string",
"tax_cents": 1299,
"tax_jurisdiction": "string",
"tax_rate_bps": 1,
"to_address": null,
"tracking_available": true,
"tracking_number": "1Z999AA10123456784",
"updated_at": "2026-10-31T15:04:05Z",
"wallet_transaction_id": "3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
}
},
"request_id": "01JBX7Q2…"
}Timeline
GET /v1/shipments/{id}/timeline
Everything that happened to the shipment on ParcelHub: purchase, label, pickup, tracking milestones, refunds and charges.
Path parameters
id• Required string
Response in data
items• Required array of objectsEach item · 4
created_at• Required timestampWhen it was created (ISO 8601, UTC).
event_type• Required stringmessage• Required stringseverity• Required string
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/timeline" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"items": [
{
"created_at": "2026-10-31T15:04:05Z",
"event_type": "string",
"message": "string",
"severity": "string"
}
]
},
"request_id": "01JBX7Q2…"
}Tracking
GET /v1/shipments/{id}/tracking
Tracking events from the carrier, newest first, with the current status.
Path parameters
id• Required string
Response in data
items• Required array of objectsEach item · 5
event_code• Required stringevent_description• Required stringoccurred_at• Required timestampsource• Required stringWhere the shipment came from. Leave out (it becomes
manual) or name your integration, e.g.api.locationstring
curl "https://api.parcelhub.ca/v1/shipments/3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f/tracking" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"items": [
{
"event_code": "string",
"event_description": "string",
"location": "string",
"occurred_at": "2026-10-31T15:04:05Z",
"source": "manual"
}
]
},
"request_id": "01JBX7Q2…"
}Shipment counts
GET /v1/shipments/counts
How many shipments are in each list (in transit, delivered, exceptions, drafts…).
Response in data
all• Required integerarchived• Required integertrueto archive (the default),falseto bring it back.delivered• Required integerdrafts• Required integerexception• Required integerin_transit• Required integerready• Required integervoided• Required integer
curl "https://api.parcelhub.ca/v1/shipments/counts" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"all": 1,
"archived": 1,
"delivered": 1,
"drafts": 1,
"exception": 1,
"in_transit": 1,
"ready": 1,
"voided": 1
},
"request_id": "01JBX7Q2…"
}List shipment ids
GET /v1/shipments/ids
Only the ids of the shipments a GET /v1/shipments query would return, in the same order. Takes the same filters.
Query parameters
statusstringOnly shipments with this status.
limitintegerMost results to return.
offsetintegerResults to skip, for paging.
fromdateCreated on or after this day (
YYYY-MM-DD, UTC).todateCreated on or before this day (
YYYY-MM-DD, UTC).is_returnbooleantruefor return shipments only,falseto leave them out.archivedbooleantruefor the Archived list. Archived shipments are left out otherwise.sourcestringOnly shipments from this source:
manual,csv,xlsx,apior a store platform such asshopify.searchstringMatches order number, tracking number, or the recipient's name, company or city.
Response in data
ids• Required array of uuidstotal• Required integer
curl "https://api.parcelhub.ca/v1/shipments/ids" \
-H "Authorization: Bearer $TOKEN"{
"ok": true,
"data": {
"ids": [
"3f2b8c1e-5d6a-4b7c-9e0f-1a2b3c4d5e6f"
],
"total": 1
},
"request_id": "01JBX7Q2…"
}