1. Operations matrix
The “no destroy” principle: objects that record money or a legal handover (shipments past draft, pickups, manifests, document uploads, events) are never deleted through the API. They move to a terminal status instead. Objects that are configuration (connections, apps, webhook endpoints, files, trackers) can be deleted.
This flowchart shows how the principle decides what happens when you want an object gone.
2. List
GET /v1/{resources} follows chapter 00 §10. Each resource’s list filters:
Range operators are
gt, gte, lt and lte. user_metadata[key]=value is an exact match. system_metadata[source] and system_metadata[batch] are also filterable on every list. carrier_metadata is never filterable or searchable, because its keys are not stable.
3. Search
field:"value"for exact match,field~"val"for substring match (minimum 3 characters), andfield>value(also<,>=,<=) for numbers and dates.ANDandORcombine clauses, but they cannot be mixed in one query.-negates a clause.- Searchable fields: shipments allow
id,status,tracking.status,carrier,purchase.service.code,tracking.number,reference,order.id,order.invoice.number,ship_to.name,ship_to.email,ship_to.address.postal_code,ship_to.address.country,ship_from.address.postal_code,handling_units.items.sku,handling_units.items.import_hs_code,created,ship_date, anduser_metadata["key"]. Trackers allowstatus,status_detail,carrier,tracking_number,created,delivered_at, anduser_metadata["key"]. Pickups allowstatus,carrier,date,confirmation_number, andcreated. - The response is
{ "object": "search_result", "data": [...], "has_more": true, "next_page": "..." }. Search results are eventually consistent, so allow up to 1 minute after a write.
4. Retrieve and expand
GET /v1/{resources}/{id}?expand[]=.... A test-mode ID requested with a live key returns 404 resource_missing, with message hinting at the mode mismatch.
5. Update
POST /v1/{resources}/{id}. Partial update. null clears a field. Setting user_metadata to {} or null clears all keys, and setting user_metadata[key] to "" deletes that key.
Updating an immutable field returns 400 parameter_invalid with message naming the status that froze it.
6. Delete
DELETE /v1/{resources}/{id} returns { "id", "object", "deleted": true }. A repeated delete returns 404.
7. Bulk operations (capability batches)
batch object (bat_) with status (processing, completed, completed_with_errors), counts, and results_file (JSONL, one line per item: { index, status, object | error }). Each item gets its own idempotency key, derived as {batch_id}:{index}. Batches exist because merchants buy labels in the thousands at end of day, and shipping 1,000 POSTs through a rate limiter is a bad experience.
This sequence shows a batch from submission to its results file.
8. Export
file with purpose: "export" and emits file.created. It is optional (capability exports).