file: bytes you uploaded or the implementer generated. It is carrier-agnostic, like Stripe Files.document_upload: a submission of one or more files to a carrier as trade documents (commercial invoice, certificate of origin, licence), also known as paperless trade, ETD, or PLT.
file can be cited by many submissions, and each submission belongs to one connection and, after the label, one shipment.
1. The file object
purpose is one of customs_document, dangerous_goods_declaration, label (generated), manifest (generated), signature_image, proof_of_delivery, logo (printed on labels or invoices where carriers allow it), or other.
Upload
file (binary, required), purpose (required), and user_metadata[key]. The maximum size is 10 MB. Allowed types per purpose: customs_document takes PDF, PNG, JPG and TIFF, and logo takes PNG and SVG.
There is also a JSON alternative for agents and serverless clients that cannot do multipart easily:
GET /v1/files/{id}, GET /v1/files/{id}/contents (streams bytes), GET /v1/files?purpose=..., and DELETE /v1/files/{id}. Deletion is refused (409) while a pending document_upload references the file. accepted, partially_accepted and rejected are terminal.
2. The document_upload object
3. Submit documents
stage is derived: if shipment or tracking_number is present, it is post_shipment, and otherwise pre_shipment.
This is how the implementer derives stage and resolves the connection from the request parameters.
A post-shipment submission against a shipment the implementer created looks like this.
Errors: option_unsupported (the carrier or corridor does not accept paperless documents, so print and attach instead), document_type_unsupported, file_too_large_for_carrier (carrier limits are often lower than 10 MB), shipment_not_eligible (already delivered, or outside the upload window).
Pre-shipment flow
customs_declaration.documents[] references a document_upload, the implementer resolves its carrier references. A reference made under a different connection returns 400 parameter_invalid.
The same flow as a sequence: the document reaches the carrier first, and the purchase cites it by reference.
Generated documents
Ifcustoms_declaration.paperless_trade is true and neither order.invoice.file nor a commercial_invoice document reference is provided, implementers SHOULD generate a commercial invoice from order (number, date, charges), handling_units[].items[] (lines) and customs_declaration (parties, incoterm, certification), submit it, and expose it as shipment.documents[type=commercial_invoice] and a document_upload with system_metadata.generated = true.
The diagram shows when an invoice is generated and which shipment data feeds it.
4. Retrieve, list, update
shipment, documents.file.
5. Events
file.created, document_upload.created, document_upload.accepted, document_upload.partially_accepted, document_upload.rejected.