Order attachments let you associate files with an order: invoices, CFDI (XML/PDF), shipping labels, delivery evidence, and more. Files are stored in S3 and accessed via short-lived presigned URLs — they never travel as base64 inside the API's JSON.
Response envelope
Every successful single-resource response follows { "data": {...} }. Errors are always { "error": { "code", "message", "details?" } }.
invoice, ticket, cfdi-xml, cfdi-pdf, shipping-guide, customs, receipt, other
evidence
packing-photo, packing-video, condition-photo
Don't confuse it with the old catalog
Values like cfdi, shipping_guide, or custom don't exist — the real catalog uses cfdi-xml/cfdi-pdf, shipping-guide (hyphenated), and other, respectively.
Don't confuse it with the singular /attachment route
GET /orders/{orderId}/attachment (singular, no ID) is a legacy route registered on the router but it always responds 501 — it's a disabled stub left over from a migration, not a functional endpoint. Always use the plural route with {attachmentId} documented here.
This endpoint responds with 200 and { "data": { "success": true, "message": "..." } } — it is not a bodyless 204. Check data.success instead of relying solely on the status code.
The declared contentType doesn't match what's expected for the type.
attachments:invalid_attachment_type
400
The type is not in the real catalog (see table above).
attachments:validation_failed
400
The body doesn't satisfy the expected schema.
attachments:attachment_limit_exceeded
400
The maximum number of attachments per order was reached for that category.
attachments:file_not_found
400
The file was not found in S3 when confirming the attachment (did you skip the upload step?).
attachments:unauthorized
403
The API key doesn't have the required permission.
attachments:order_not_found
404
No order with that ID exists in your tenant.
attachments:attachment_not_found
404
No attachment with that ID exists on that order.
attachments:delete_failed
500
Failed to delete the file in S3 or the attachment record.
Tip
Size and count limits are per category (document vs. evidence), not a single global limit — review the limits table above before uploading large evidence files.