{"openapi":"3.1.0","info":{"title":"ShipScan API","version":"1.0.0","description":"Canonical customer API: consignment ingestion + label generation. Auth: `x-api-key: <api-key>` header (`Authorization: Bearer <api-key>` also accepted). Errors: `{ error: { code, message, details? }, request_id }`. Breaking changes never land on /api/v1 — additive fields only."},"servers":[{"url":"{baseUrl}","variables":{"baseUrl":{"default":"https://app.shipscan.io"}}}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"ShipScan API key (Settings → Integrations → API keys). The key alone identifies the organisation. `Authorization: Bearer <key>` is also accepted for older integrations."}},"schemas":{},"parameters":{}},"paths":{"/api/v1/consignments":{"post":{"summary":"Ingest a consignment (find-or-create by reference)","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reference_number":{"type":"string","minLength":1},"carrier":{"type":"string","minLength":1},"ship_from":{"type":"string","minLength":1},"ship_to":{"type":"object","properties":{"line1":{"type":"string","minLength":1},"line2":{"type":"string"},"city":{"type":"string","minLength":1},"county":{"type":"string"},"postcode":{"type":"string","minLength":1},"country_code":{"type":"string","minLength":2,"maxLength":2,"default":"GB"},"name":{"type":"string","minLength":1},"contact":{"type":"string","minLength":1},"phone":{"type":"string","minLength":1}},"required":["line1","city","postcode"]},"parcels":{"type":"array","items":{"type":"object","properties":{"tracking_number":{"type":"string","minLength":1},"parcel_id":{"type":"string"},"weight_kg":{"type":"number","exclusiveMinimum":0},"length_cm":{"type":"number","exclusiveMinimum":0},"width_cm":{"type":"number","exclusiveMinimum":0},"height_cm":{"type":"number","exclusiveMinimum":0},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1},"quantity":{"type":"integer","exclusiveMinimum":0,"default":1},"sku":{"type":"string"},"value_minor_units":{"type":"integer","minimum":0},"value_currency":{"type":"string","minLength":3,"maxLength":3},"weight_kg":{"type":"number","exclusiveMinimum":0},"hs_code":{"type":"string"},"origin_country":{"type":"string","minLength":2,"maxLength":2}},"required":["description"]}}},"required":["tracking_number"]},"minItems":1},"notes":{"type":"string"},"value_minor_units":{"type":"integer","minimum":0},"value_currency":{"type":"string","minLength":3,"maxLength":3}},"required":["reference_number","carrier","ship_from","ship_to","parcels"]}}}},"responses":{"200":{"description":"Consignment recorded (existing reference is reused)","content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"parcel_count":{"type":"integer"},"status":{"type":"string","enum":["pending_loading"]}},"required":["consignment_id","parcel_count","status"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}},"get":{"summary":"List consignments (newest first)","description":"Filters: `reference` (exact, case-insensitive), `status`, `limit` (default 25, max 100).","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"name":"reference","in":"query"},{"schema":{"type":"string","enum":["pending_loading","partially_loaded","fully_loaded","fulfilled","cancelled"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Consignments with carrier binding, status and parcels","content":{"application/json":{"schema":{"type":"object","properties":{"consignments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reference_number":{"type":"string"},"order_reference":{"type":["string","null"]},"carrier":{"type":"string"},"carrier_account_id":{"type":["string","null"],"format":"uuid"},"warehouse":{"type":["string","null"]},"status":{"type":"string"},"tracking_status":{"type":["string","null"]},"label_failed_at":{"type":["string","null"]},"fulfilled_at":{"type":["string","null"]},"fulfilment_source":{"type":["string","null"],"enum":["trailer_close","manual","api","account_auto","carrier_tracking"]},"parcel_count":{"type":"integer"},"parcels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tracking_number":{"type":["string","null"]},"status":{"type":"string"}},"required":["id","tracking_number","status"]}},"created_at":{"type":"string"}},"required":["id","reference_number","order_reference","carrier","carrier_account_id","warehouse","status","tracking_status","label_failed_at","fulfilled_at","fulfilment_source","parcel_count","parcels","created_at"]}}},"required":["consignments"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/consignments/{id}/tracking":{"get":{"summary":"Get a consignment's tracking","description":"Its loading state (`status`, `fulfilled_at`) and delivery state (`tracking_status`, `delivered_at`), each carrier tracking number with its public tracking link, and every carrier event newest first. An event's `status` is the normalised status; null means the event is history only (e.g. proof of delivery recorded) and never moves `tracking_status`. `details` carries carrier-specific facts such as who signed for it. Tracking is read here; carriers that ShipScan polls send no outbound webhooks. A cancelled consignment is still returned, with `status` cancelled.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The consignment's tracking","content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"reference_number":{"type":"string"},"order_reference":{"type":["string","null"]},"status":{"type":"string"},"fulfilled_at":{"type":["string","null"]},"tracking_status":{"type":["string","null"],"enum":["info_received","picked_up","in_transit","out_for_delivery","delivered","failed_delivery","returned","exception"]},"delivered_at":{"type":["string","null"]},"carrier":{"type":"object","properties":{"code":{"type":["string","null"]},"account":{"type":["string","null"]}},"required":["code","account"]},"tracking_numbers":{"type":"array","items":{"type":"object","properties":{"carrier_tracking_number":{"type":"string"},"tracking_url":{"type":["string","null"]},"parcel_references":{"type":"array","items":{"type":"string"}}},"required":["carrier_tracking_number","tracking_url","parcel_references"]}},"events":{"type":"array","items":{"type":"object","properties":{"occurred_at":{"type":"string"},"status":{"type":["string","null"],"enum":["info_received","picked_up","in_transit","out_for_delivery","delivered","failed_delivery","returned","exception"]},"carrier_status":{"type":"string"},"description":{"type":["string","null"]},"location":{"type":["string","null"]},"details":{"type":["object","null"],"additionalProperties":{}}},"required":["occurred_at","status","carrier_status","description","location","details"]}}},"required":["consignment_id","reference_number","order_reference","status","fulfilled_at","tracking_status","delivered_at","carrier","tracking_numbers","events"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"404":{"description":"No consignment with that id in your organisation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/labels":{"post":{"summary":"Generate a label — one-request or two-step mode","description":"One-request mode: inline `shipment` + `carrier` blocks create the consignment AND generate one label per parcel in a single call (`carrier.name` matches an account display name; unmatched → shipment recorded, `labels: []`, `reason: NO_ADAPTER`). Two-step mode: `parcel_id` or `consignment_reference` + `parcel_tracking_number`. Send an `Idempotency-Key` header — retries replay, never double-book. Allow ~60s (synchronous carrier round-trip).","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"shipment":{"type":"object","properties":{"reference":{"type":"string","minLength":1},"ship_from":{"type":"string","minLength":1},"ship_to":{"type":"object","properties":{"line1":{"type":"string","minLength":1},"line2":{"type":"string"},"city":{"type":"string","minLength":1},"county":{"type":"string"},"postcode":{"type":"string","minLength":1},"country_code":{"type":"string","minLength":2,"maxLength":2,"default":"GB"},"name":{"type":"string","minLength":1},"contact":{"type":"string","minLength":1},"phone":{"type":"string","minLength":1}},"required":["line1","city","postcode"]},"parcels":{"type":"array","items":{"type":"object","properties":{"reference":{"type":"string","minLength":1},"tracking_number":{"type":"string","minLength":1},"weight_kg":{"type":"number","exclusiveMinimum":0},"length_cm":{"type":"number","exclusiveMinimum":0},"width_cm":{"type":"number","exclusiveMinimum":0},"height_cm":{"type":"number","exclusiveMinimum":0},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1},"quantity":{"type":"integer","exclusiveMinimum":0,"default":1},"sku":{"type":"string"},"value_minor_units":{"type":"integer","minimum":0},"value_currency":{"type":"string","minLength":3,"maxLength":3},"weight_kg":{"type":"number","exclusiveMinimum":0},"hs_code":{"type":"string"},"origin_country":{"type":"string","minLength":2,"maxLength":2}},"required":["description"]}}}},"minItems":1},"notes":{"type":"string"},"value_minor_units":{"type":"integer","minimum":0},"value_currency":{"type":"string","minLength":3,"maxLength":3}},"required":["reference","ship_from","ship_to","parcels"]},"carrier":{"type":"object","properties":{"name":{"type":"string","minLength":1},"account_id":{"type":"string","format":"uuid"},"service":{"type":"string","minLength":1},"options":{"type":"object","additionalProperties":{}}}},"parcel_id":{"type":"string","format":"uuid"},"consignment_reference":{"type":"string","minLength":1},"parcel_tracking_number":{"type":"string","minLength":1},"carrier_account_id":{"type":"string","format":"uuid"},"service_code":{"type":"string","minLength":1},"format":{"type":"string","enum":["pdf","zpl","png"],"default":"pdf"}}}}}},"responses":{"200":{"description":"One-request mode: `{ shipment, labels[], reason? }`. Two-step mode: a single label object.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"shipment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"]},"document":{"type":["object","null"],"properties":{"url":{"type":"string","description":"Time-limited signed URL to ONE printable document containing every parcel label as a page"},"format":{"type":"string","enum":["pdf","zpl","png"]}},"required":["url","format"]},"parcels":{"type":"array","items":{"type":"object","properties":{"reference":{"type":"string","description":"The caller's parcel reference/barcode, exactly as submitted"},"carrier_tracking_number":{"type":["string","null"],"description":"Carrier-assigned tracking number"},"label_id":{"type":["string","null"],"format":"uuid","description":"Per-parcel label id, for POST /api/v1/labels/{id}/void"}},"required":["reference","carrier_tracking_number","label_id"]}},"reason":{"type":"string","enum":["NO_ADAPTER"]},"reason_message":{"type":"string","description":"Human-readable diagnosis for NO_ADAPTER"}},"required":["shipment","document","parcels"]},{"type":"object","properties":{"label_id":{"type":"string","format":"uuid"},"label_url":{"type":"string"},"tracking_number":{"type":"string"},"carrier_service_code":{"type":"string"},"format":{"type":"string","enum":["pdf","zpl","png"]},"rate_amount":{"type":["number","null"]},"rate_currency":{"type":"string"},"status":{"type":"string","enum":["created","failed"]},"error_message":{"type":["string","null"]}},"required":["label_id","label_url","tracking_number","carrier_service_code","format","rate_amount","rate_currency","status","error_message"]}]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"409":{"description":"Idempotency conflict: BODY_HASH_MISMATCH (same key, different body) or IN_FLIGHT","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/consignments/{id}/cancel":{"post":{"summary":"Cancel a consignment (voids labels at their carriers)","description":"Voids every created label AT ITS CARRIER (best-effort per label; failures reported), then flips the consignment to `cancelled`. Fulfilled consignments refuse with 409 — the goods have left; raise an exception instead (undo an asserted fulfilment first if it was a mistake). Idempotent on already-cancelled.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["cancelled"]},"labels_voided":{"type":"integer"},"label_void_failures":{"type":"array","items":{"type":"object","properties":{"label_id":{"type":"string"},"error":{"type":"string"}},"required":["label_id","error"]}}},"required":["consignment_id","status","labels_voided","label_void_failures"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"409":{"description":"Already fulfilled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/consignments/{id}/fulfil":{"post":{"summary":"Mark a consignment fulfilled (loaded and left the building)","description":"Your system says this consignment has left. Recorded with source `api` — asserted, not proven by a ShipScan scan (a consignment scanned onto a closed trailer is fulfilled automatically, with source `trailer_close`). Idempotent: an already-fulfilled consignment answers `already_fulfilled`. 409 with code `CONSIGNMENT_CANCELLED`, `NO_LIVE_LABEL` or `LOADING_IN_PROGRESS` (details.trailer) when it cannot be fulfilled. The body is optional.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":500}},"additionalProperties":false}}}},"responses":{"200":{"description":"Fulfilled, or already fulfilled","content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"reference_number":{"type":["string","null"]},"outcome":{"type":"string","enum":["fulfilled","already_fulfilled"]}},"required":["consignment_id","reference_number","outcome"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"409":{"description":"Cannot be fulfilled (cancelled / no live label / loading in progress)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/consignments/fulfil":{"post":{"summary":"Mark up to 500 consignments fulfilled, by id or reference","description":"Send exactly one of `ids` or `references`. Always 200 with an outcome per consignment — `fulfilled`, `already_fulfilled`, `skipped` (with `reason`) or `not_found` — plus `missing_references` and a one-line `summary`. Never a silent partial success.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":500},"references":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":500},"note":{"type":"string","maxLength":500}},"additionalProperties":false}}}},"responses":{"200":{"description":"Per-consignment outcomes","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"reference_number":{"type":["string","null"]},"outcome":{"type":"string","enum":["fulfilled","already_fulfilled","skipped","not_found"]},"reason":{"type":["string","null"],"enum":["cancelled","no_label","loading_in_progress","not_fully_loaded"]},"detail":{"type":["string","null"]}},"required":["consignment_id","reference_number","outcome","reason","detail"]}},"missing_references":{"type":"array","items":{"type":"string"}},"summary":{"type":"string"}},"required":["results","missing_references","summary"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/consignments/{id}/fulfil/undo":{"post":{"summary":"Undo an asserted fulfilment","description":"Takes back a fulfilment recorded by hand, through the API, or by the carrier account's fulfil-on-label setting. A fulfilment proven by a trailer close (reopen the trailer instead) or reported by carrier tracking answers 409 `NOT_UNDOABLE`; one that is not fulfilled, 409 `NOT_FULFILLED`. The body is optional.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":500}},"additionalProperties":false}}}},"responses":{"200":{"description":"Undone","content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"reference_number":{"type":["string","null"]},"outcome":{"type":"string","enum":["undone"]}},"required":["consignment_id","reference_number","outcome"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"409":{"description":"Not fulfilled, or not undoable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}},"/api/v1/labels/bulk":{"post":{"summary":"Generate labels for every parcel on a consignment","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"consignment_id":{"type":"string","format":"uuid"},"carrier_account_id":{"type":"string","format":"uuid"},"service_code":{"type":"string","minLength":1},"format":{"type":"string","enum":["pdf","zpl","png"],"default":"pdf"}},"required":["consignment_id"]}}}},"responses":{"200":{"description":"One label per parcel","content":{"application/json":{"schema":{"type":"object","properties":{"labels":{"type":"array","items":{"type":"object","properties":{"label_id":{"type":"string","format":"uuid"},"label_url":{"type":"string"},"tracking_number":{"type":"string"},"carrier_service_code":{"type":"string"},"format":{"type":"string","enum":["pdf","zpl","png"]},"rate_amount":{"type":["number","null"]},"rate_currency":{"type":"string"},"status":{"type":"string","enum":["created","failed"]},"error_message":{"type":["string","null"]}},"required":["label_id","label_url","tracking_number","carrier_service_code","format","rate_amount","rate_currency","status","error_message"]}}},"required":["labels"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}},"422":{"description":"Validation failed, or an operator-fixable gap (CUSTOMS_REQUIRED, ADDRESS_INVALID, …)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"request_id":{"type":"string"}},"required":["error","request_id"]}}}}}}}},"webhooks":{}}