Fix or reassign a shipment
When a shipment lands in error, re-book it with
POST /shipments/{shipment_id}/reprocess. The same endpoint covers
both common fixes: correct the data the error points to, or move the
shipment to a different carrier account. Reprocess applies your change
as a partial update and re-submits the booking.
Resolving errors is usually easiest in the Carriyo Dashboard, where an operator sees the error, corrects it, and reprocesses in a few clicks, see Resolve shipment errors. Use this API path when you want to automate it.
Scenario
Two situations leave a shipment in error, both fixable with reprocess:
- A data problem. A Carriyo or carrier validation flags a field, for example an invalid phone number on the dropoff. Correct the field and reprocess.
- A carrier problem. Carriyo's rules couldn't assign a carrier
(
no_carrier_assigned), or the assigned carrier rejected the booking. Move it to a different carrier account and reprocess.
Prerequisites
- API credentials: see Getting started.
- A shipment in a reprocess-eligible status (most commonly
error). - For a carrier change, the
carrier_idof the carrier account you want (a UUID).
Step 1, read the error
Read post_shipping_info.error_details to see what failed, from the
error webhook (see Book a shipment)
or by fetching the shipment:
curl 'https://api.carriyo.com/shipments/MPRD8K2NXVABE2' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY'
{
"shipment_id": "MPRD8K2NXVABE2",
"post_shipping_info": {
"status": "error",
"error_details": [
{
"level": "ERROR",
"trigger": "BOOKING",
"source": "CARRIYO",
"type": "VALIDATION",
"message": "The Phone number provided '212-555-0100' is invalid. Please use a valid phone number and reprocess booking again.",
"code": "phone_number_invalid",
"field": "dropoff.contact_phone"
}
]
},
"...": "(other fields elided)"
}
The field tells you what to send back corrected. (code meanings are
in Error codes.)
Step 2, reprocess with your fix
reprocess is a POST with the action in the path. Its body is a
partial update: include a top-level field to replace it, omit it to
leave it unchanged, or set it to null to clear it (custom attributes
are the exception: they merge key-by-key). An included object is
replaced as a whole, so send the complete object. The call moves the
shipment to pending and re-submits the booking. Send only what the
error needs, pick the case that matches.
Fix the data
The error above points at dropoff.contact_phone. Because an included
object is replaced wholesale, send the entire dropoff with the
corrected phone, not just the phone:
curl -X POST 'https://api.carriyo.com/shipments/MPRD8K2NXVABE2/reprocess' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"dropoff": {
"address1": "350 5th Avenue",
"city": "New York",
"state": "NY",
"country": "US",
"postcode": "10118",
"contact_name": "Alex Chen",
"contact_phone": "+12125550100"
}
}'
Reassign the carrier
If the problem is the carrier, a rejection or no_carrier_assigned,
pass carrier_account.carrier_id set to the account you want:
curl -X POST 'https://api.carriyo.com/shipments/MPRD8K2NXVABE2/reprocess' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"carrier_account": {
"carrier_id": "a72f1b90-5e3d-4c2a-9f10-2b7c6e4d8a31"
}
}'
Naming an account skips the shipping rules: Carriyo books with that
account and won't fall through to another if it can't serve the
shipment. To let the rules pick again instead, reprocess without
carrier_account.
Step 3, read the outcome
Reprocess returns the shipment in pending, the booking is
re-submitted but not yet accepted:
{
"shipment_id": "MPRD8K2NXVABE2",
"post_shipping_info": {
"status": "pending",
"key_milestones": {}
},
"...": "(other fields elided)"
}
It then resolves asynchronously, pending → booked (tracking number
and label attached) or pending → error (still failing, read
error_details and try again). Catch the outcome on the same
booked / error webhook you use for new bookings, see
Book a shipment.
Eligible statuses
Reprocess covers more than error: booked, ready_to_ship, error,
cancelled, cancelled_by_carrier, out_for_collection,
failed_collection_attempt, ready_for_return, return_in_transit,
and returned. A terminal status like delivered returns a 400. To
re-book a draft, use
Draft then confirm instead,
confirm handles draft and error.
Pitfalls
- Send the whole object you're changing. Top-level fields you
include are replaced wholesale, so a
dropoffcarrying only the phone would blank the rest of the address. Send the complete object; usenullonly to clear a field deliberately. - It's
carrier_account.carrier_id, notcarrier_account_id. On the shipment you name the account undercarrier_account.carrier_id(a UUID), even though the carrier account's own field iscarrier_account_id. A legacy quirk that's easy to get wrong. - A named carrier account has no fallback. Reprocess with a
specific
carrier_accountskips the rules; if that account can't serve the shipment it fails toerrorrather than rerouting.