These endpoints cover everything that happens after an order has been processed: recording the delivery, confirming it, uploading evidence (photos/documents), attaching information for an external shipment, and managing its cost. For the fulfillment/shipping preparation itself, see Fulfillment.
Response envelope
Every successful single-resource response follows { "data": {...} }. Errors are always { "error": { "code", "message", "details?" } } with namespace:snake_case codes.
It doesn't upload the file — it only registers its URL
This endpoint is NOT a two-step upload flow like order attachments (S3 presigned URL + confirmation). evidenceUrl is the already-existing URL of the evidence (for example, a photo you uploaded yourself to your own storage or via the attachments flow) — this endpoint just associates it with the order; it doesn't host the file.
Attaches to the order the complete information of a shipment: carrier, cost, tracking label, estimated dates, origin/destination, and package dimensions.
orderIdstringrequired
Order ID
trackingNumberstringrequired
Tracking number.
carrierstringrequired
Carrier code.
shipmentIdstring
Shipment ID, if one already exists to update.
waybillIdstring
Waybill ID.
carrierNamestring
Visible carrier name.
serviceNamestring
Shipping service name (e.g. 'Express', 'Ground').
providerstring
Provider that originated the shipment (e.g. carrier aggregator).
This endpoint is only the cost — it doesn't replace attach-shipment
PUT .../shipping-cost only captures or updates the amount paid for a shipment that already exists on the order (identified by shipmentId); it doesn't create the shipment nor accept attach-shipment's other fields (label, carrier, dates). Each operation emits a domain event that lambda-finance-events reflects as an Expense in @fenicia/finance-service.
Removes the cost previously assigned to a shipment on the order.
Idempotent: removed indicates whether there was a prior cost
If the shipment already had no cost assigned, the call still responds 200 with removed: false — that's not an error, it's intentional idempotency (event consumers may deliver the same removal twice). A shipmentId that doesn't exist on the order does return orders:shipment_not_found (404).
Returns presigned S3 URLs to download the order's shipping labels. Each PDF is persisted as an order attachment (the first time) or served from S3 cache on subsequent calls.
It's persisted as an order attachment in S3 and the API responds with a presigned URL (TTL ~15 min). Download the PDF directly from that URL — you don't need your API key for that second step. Repeated calls for the same order reuse the cached attachment.