Asynchronous operations
Choose between the default synchronous response and optional asynchronous label purchasing.
An asynchronous operation accepts work and returns a resource that you can retrieve. You do not keep the connection open for the label (guía).
This pattern is currently optional for label purchases. The same endpoint supports both modes.
This page explains how to choose and operate each mode. See Labels for the complete endpoint contract, all fields, and errors.
Choose the correct mode
| Mode | How to request it | Initial response | Use it when |
|---|---|---|---|
| Synchronous | Omit async or send false |
201 Created with the label |
You buy few labels and want the result in one request |
| Asynchronous | Send async: true |
202 Accepted with an attempt |
You process volume or must release the connection quickly |
Synchronous mode is the default. An existing integration does not need to change.
Start an asynchronous purchase
curl -i -X POST https://api.sendit.mx/v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/label \
-H "X-API-Key: sk_test_..." \
-H "Idempotency-Key: 1f0e6f0e-59a4-4a6f-9d2e-9b1a7b2c3d4e" \
-H "Content-Type: application/json" \
-d '{ "rateId": "DHL_standard_a1b2c3", "async": true }'
The 202 response includes Location, Retry-After: 2, and statusUrl. Retry-After is a suggestion, not a completion guarantee. This excerpt shows the fields needed to start polling; the Labels page has the complete resource.
{
"success": true,
"data": {
"id": "lat_550e8400-e29b-41d4-a716-446655440000",
"object": "label_purchase_attempt",
"shipmentId": "clxq1w2e3r4t5y6u7i8o9p0a",
"status": "pending",
"livemode": false,
"async": true,
"statusUrl": "/v1/label-purchase-attempts/lat_550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2026-08-01T10:00:00.000Z",
"updatedAt": "2026-08-01T10:00:00.000Z",
"completedAt": null
}
}
Retrieve the result
Send GET to statusUrl with a key that has labels:read:
curl https://api.sendit.mx/v1/label-purchase-attempts/lat_550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: sk_test_..."
status |
What it means | What you do |
|---|---|---|
pending |
The purchase was accepted | Wait before the next request |
processing |
The purchase is in progress | Continue polling with gradual backoff |
succeeded |
The label is ready | Use label and stop polling |
failed |
The purchase failed and the attempt ended | Read error; fix the cause before a new purchase |
action_required |
The outcome is not conclusive | Do not buy another label for this shipment; keep the attempt and contact support |
The endpoint does not reveal whether an ID belongs to another organization or mode. Those cases and a missing ID return the same 404.
Receive completion by webhook
Subscribe to label.purchase.completed to avoid continuous polling. The event covers succeeded, failed, and action_required.
Webhook delivery is at least once. Deduplicate with the event id, then retrieve the attempt before updating your final state.
Retry without duplicating the purchase
Send an Idempotency-Key and store it with your operation. An exact repeat returns the same active attempt.
If you change the rateId, format, external reference, or async value, the API returns 409 SHIPMENT_LABEL_IN_PROGRESS. Retrieve the existing attempt.
Insufficient funds return 402 INSUFFICIENT_BALANCE before the API accepts work. No pending attempt remains.
See the complete contract in Labels and retry protection in Idempotency.