Carrier quickstart
Accept a shipment and register its proof of delivery
Complete sandbox setup, then use the official cURL, TypeScript or Go carrier runner. Use TypeScript SDK 0.4.0 or Go SDK 0.4.4. Hosted upload completion must be deployed in your environment before running; SDK installation alone does not establish API availability.
You need a carrier-scoped company key, an assigned synthetic pending offer, a valid synthetic PDF no larger than 10 MiB, and scenario coordinates. Set the credentials described in setup, plus OWAY_OFFER_ID, OWAY_POD_FILE, OWAY_LOCATION_FILE, a new private OWAY_STATE_FILE, and OWAY_STEP=prepare.
Prepare and upload
The runner performs these steps using the same offer identifier throughout:
- Retrieve the assigned offer. If it is PENDING, accept it. An empty offer list means you need an assigned scenario; do not accept an arbitrary offer.
- Confirm pickup with
pickup_time. Require the carrier shipment response to reach PICKED_UP. The nested order status uses the public order vocabulary; do not infer a commercial transition from an observational milestone alone. - Send a location update with latitude, longitude and timestamp from the test scenario.
- Request a storage URL with
document_type: PROOF_OF_DELIVERY,content_type: application/pdf, andfile_name. Persistdocument_idand the exact metadata before uploading. - PUT the PDF bytes to
upload_url, sending the returnedcontent_type. Do not send Oway credentials to that storage URL. Upload beforeexpires_at. - PUT the original metadata to
/v1/carrier/shipments/{identifier}/uploads/{documentId}/confirm. This registers the uploaded POD for review. The response suppliesdocument_id,download_url,expires_atandreview_status.
Completion supports PDF, PNG and JPEG PODs, with a 10 MiB byte limit and a 50-million-pixel image limit. It does not complete SIGNATURE uploads. The examples use PDF. Filenames must not contain path separators or control characters. A missing upload returns 409 upload_missing; mismatched content is rejected. Uploading bytes alone is not completion.
The document ID is stable. Download URLs expire. A repeated completion with the same ID and metadata returns the same document; changing completion metadata conflicts. To submit a corrected POD after completion, register a new document.
Review, then deliver
The uploaded POD enters PENDING review. An authorized reviewer must approve it with a verified recipient signature. Review is required before you can confirm delivery with this document. Set OWAY_STEP=deliver and rerun after review.
The runner retrieves the POD and current shipment state first. Review may already have triggered delivery; an already DELIVERED shipment must not be delivered again. Otherwise it submits delivery_time and proof_of_delivery_document_id and requires DELIVERED in the returned state.
Do not send proof_of_delivery_url alongside the document ID. Do not use a presigned PUT URL, a constructed storage URL or an expiring download URL as the legacy POD URL. A document ID without the required approval and signature verification returns 409 pod_review_required without confirming delivery.
Retrieve a fresh POD link with GET /v1/carrier/shipments/{identifier}/documents/{documentId}. The endpoint enforces shipment ownership and excludes denied, archived and superseded documents. When using shipment lists for reconciliation, include completed shipments instead of relying on the default active-only filter.
Recover from partial progress
Keep the state file after any failure. For uncertain upload completion, rerun with OWAY_STEP=confirm-upload; it uses the saved identity and metadata. If the storage PUT failed, retain that state file, choose a new state-file path and rerun prepare for the same offer. The runner reads the existing state and skips pickup when already PICKED_UP.
For an uncertain acceptance or delivery, read the shipment before retrying a mutation. Do not treat 409 as permission to repeat the whole journey. Correct a denied POD by registering a new file; keep the previously reviewed document unchanged. For a fresh complete run, request a new synthetic offer.
Use the existing webhook quickstart to verify a signed test event, then subscribe only to catalog-supported lifecycle events. Keep the GET reconciliation path even when receiving webhooks.
Updated about 3 hours ago