AcknowledgeFulfillmentOrders records the identifier you gave the work on your own side. It does **not** drain ListNeedToShip — you still owe the shipment — and it is not required before shipping.
You call thissales:orders:fulfillment:self
const url = 'https://api.zentail.com/v2/shipping/fulfillment_orders/acknowledge';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"acknowledgements":[{"fulfillmentOrderId":"example","externalOrderId":"example"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.zentail.com/v2/shipping/fulfillment_orders/acknowledge \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "acknowledgements": [ { "fulfillmentOrderId": "example", "externalOrderId": "example" } ] }'Two reasons to call it. It is how a crash between “created it on my side” and “told Zentail” becomes recoverable: the fulfillment order is still in ListNeedToShip, and the absence of your id there tells you to reconcile before creating a duplicate. And it is what puts the work into ListNeedToCancel if Zentail later needs it pulled back.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
One entry per fulfillment order you have created on your own side. Required and server-capped: an empty list, or one over the cap, fails the whole request rather than answering per entry.
object
The work you are claiming, as ListNeedToShip gave it. Acknowledging does not drain it from that queue — you still owe the shipment.
Your own identifier for the work. Unique per integration — Zentail rejects a duplicate rather than recording it twice, which is what makes a retry safe.
Examplegenerated
{ "acknowledgements": [ { "fulfillmentOrderId": "example", "externalOrderId": "example" } ]}Responses
Section titled “ Responses ”A successful response.
object
One result per acknowledgement sent. Match on fulfillment_order_id rather than on position, and read every entry: one failing does not fail the rest.
object
The acknowledgement this answers, echoed back.
True when Zentail holds your external_order_id against this fulfillment order — including when it already did, which reports success with already_acknowledged set. False is always a real failure.
Why it failed, in prose, for logs and support. Empty on success. This contract carries no error code, so the string is all there is: log it, and do not branch on its wording.
True when this external_order_id was already recorded — a replay, not a conflict. Treat as success.
Examplegenerated
{ "results": [ { "fulfillmentOrderId": "example", "success": true, "errorMessage": "example", "alreadyAcknowledged": true } ]}default
Section titled “default”An unexpected error response.
object
object
Examplegenerated
{ "code": 1, "message": "example", "details": [ { "@type": "example" } ]}