Create your first shipment
This guide walks through, in order, every request needed to create a shipping order: from getting the token to checking the shipping label and the tracking.
An order needs three IDs that you get in earlier steps:
| ID | What it is | Step |
|---|---|---|
branchAddressId | The pickup address, where the package is collected. | 3 |
branchsClientId | The recipient client. The order is delivered to the client's registered address. | 4 |
courierServiceId | The courier and service chosen when quoting. | 5 |
The examples use https://api.volao.app and test values. Replace <access_token> and the IDs with your own.
Get a token
curl -X POST https://api.volao.app/api/auth/client/login \
-H "Content-Type: application/json" \
-d '{ "client_id": "client_demo", "client_secret": "secret_demo" }'
Keep token.access_token and send it in every following request, in the Authorization: Bearer <access_token> header. It lasts 15 minutes; see Authentication.
Find the destination municipality
The location catalogs are public and don't require a token.
-
List the departments and take the
departmentIdyou need:Departmentscurl https://api.volao.app/api/open/departments -
Get its municipalities:
Department's municipalitiescurl -X POST https://api.volao.app/api/open/municipality \-H "Content-Type: application/json" \-d '{ "departmentId": "0199a1b2-3333-7e5f-8a6b-1c2d3e4f0004" }'Response{"response_code": 200,"response_status": "Success","response_message": "Municipios procesados correctamente","data": [{ "municipalityId": "0199a1b2-4444-7e5f-8a6b-1c2d3e4f0005", "municipalityCode": "0101", "municipalityName": "AHUACHAPÁN" }]}
:::info Two ways to identify a municipality
Each municipality has a municipalityId (UUID) and a municipalityCode (4-digit code). The pickup address uses the code; the client and the quote use the UUID. Each step says which one to send.
:::
Choose the pickup address
List your merchant's pickup addresses (-1 returns all of them):
curl "https://api.volao.app/api/branchs/branchsAddresses?branchAddressId=-1" \
-H "Authorization: Bearer <access_token>"
Take the branchAddressId of the address you want to use. The one with "defaultAddress": 1 is the default.
If you don't have one yet, create it. The typeBranchAddressId comes from GET /api/open/typeBranchAddress (home, store, warehouse…) and municipalityCodigo is the municipality code:
curl -X POST https://api.volao.app/api/branchs/branchsAddresses \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"branchAddressName": "Bodega Prueba",
"collectionAddress": "Calle Ficticia #123, Colonia Prueba, San Salvador",
"contactName": "Cliente Prueba",
"phoneNumber": "70000000",
"emailContact": "cliente.prueba@example.com",
"latitude": "13.692940",
"longitude": "-89.218191",
"municipalityCodigo": "0102",
"typeBranchAddressId": "0199a1b2-1111-7e5f-8a6b-1c2d3e4f0002"
}'
The response (201) includes the new branchAddressId. If there is already an active address with the same name, the API returns 409.
Choose or register the client
Search for the client by name, phone or another field:
curl "https://api.volao.app/api/branchs/branchsClient/search?search=Cliente%20Prueba&favorite=-1" \
-H "Authorization: Bearer <access_token>"
From the response keep two values: the branchsClientId (for the order) and the municipalityId (for the quote).
If it's a new client, register them with their delivery address. Here municipalityCode is the municipality UUID (municipalityId from step 2):
curl -X POST https://api.volao.app/api/branchs/branchsClient \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"recipientName": "Cliente Prueba",
"recipientEmail": "cliente.prueba@example.com",
"recipientPhone": "70000000",
"recipientAddress": "Calle Ficticia #456, Colonia Prueba, San Salvador",
"municipalityCode": "0199a1b2-4444-7e5f-8a6b-1c2d3e4f0005"
}'
The response (201) includes the new branchsClientId.
Quote the shipment
-
Get the service modes and take the
serviceModeCode(for example,NORMAL):Service modescurl https://api.volao.app/api/courier/serviceMode \-H "Authorization: Bearer <access_token>" -
Quote with the pickup address, the client's municipality (UUID), the weight and the amount to collect. Send an empty
courierNameto see every courier:Quotecurl -X POST https://api.volao.app/api/courier \-H "Authorization: Bearer <access_token>" \-H "Content-Type: application/json" \-d '{"branchAddressId": "0199a1b2-3c4d-7e5f-8a6b-1c2d3e4f5a6b","municipalityCode": "0199a1b2-4444-7e5f-8a6b-1c2d3e4f0005","shippingAmount": 10,"weight": 4,"cantPackages": 1,"courierName": "","typeService": "NORMAL"}'
The response has one option per available service, with its cost (deliveryCost), commission, estimated pickup and delivery dates, and agencies. Choose one and keep its courierServiceId.
:::warning The amount must cover the shipment
If you collect cash on delivery, shippingAmount must cover the shipping cost plus the commissions. Otherwise, when creating the order the API returns 409 with the minimum required amount.
:::
Create the order
With the three IDs, create the order:
curl -X POST https://api.volao.app/api/orders \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"branchInfo": {
"branchAddressId": "0199a1b2-3c4d-7e5f-8a6b-1c2d3e4f5a6b",
"branchsClientId": "0199a1b2-2222-7e5f-8a6b-1c2d3e4f0003"
},
"courier": {
"courierServiceId": "019f88a7-40d5-75b5-add9-87e652d9ba69",
"agencias": {}
},
"location": { "latitude": "13.692940", "longitude": "-89.218191" },
"product": { "productDescription": "Ropa", "totalWeight": 4, "cantPackages": 1 },
"order": { "shippingAmount": 10, "onDelivery": 1, "paymentOrderCollection": 0, "comments": "" }
}'
agenciasis required, but it can be empty ({}). It's only filled when the chosen service works with agencies (GET /api/courier/agencies).onDelivery: 1means the amount is collected on delivery.
The response (201) includes the order ID and the shipping label:
{
"response_code": 201,
"response_status": "Success",
"response_message": "Orden creada correctamente",
"data": {
"ordersId": "0199a1b2-7777-7e5f-8a6b-1c2d3e4f0008",
"comprobante": "29137811",
"courierName": "Mensajería Ejemplo",
"availableBalance": 42.22
},
"guide": { "URLguide": "https://..." }
}
Keep data.ordersId: you need it to get the label, the tracking or to cancel the order. The shipping cost is deducted from your prepaid balance (availableBalance is the remaining balance).
Get the label and the tracking
-
Shipping label (to print):
Shipping labelcurl "https://api.volao.app/api/orders?OrderId=0199a1b2-7777-7e5f-8a6b-1c2d3e4f0008" \-H "Authorization: Bearer <access_token>" -
Tracking (current status and movements):
Trackingcurl "https://api.volao.app/api/orders/tracking?OrderId=0199a1b2-7777-7e5f-8a6b-1c2d3e4f0008" \-H "Authorization: Bearer <access_token>" -
Public tracking, without a token, to share with your customer:
GET /api/open/trackingComp?OrderId=....
To cancel one or several orders, use PATCH /api/orders with the list of IDs and the reason.
Common errors
| Response | Cause | What to do |
|---|---|---|
401 Token inválido o expirado | More than 15 minutes passed since the login. | Repeat step 1. |
409 about the amount to collect | shippingAmount doesn't cover the shipment plus the commissions. | Raise the amount to the minimum given in response_message. |
409 about the address | The branchAddressId doesn't exist or doesn't belong to your merchant. | List your addresses again (step 3). |
409 about the balance | Your prepaid balance doesn't cover the shipping cost. | Top up your balance before creating the order. |
400 | A required field is missing or has an invalid format. The API reports the first error. | Check the field given in response_message. |
The API returns its messages in Spanish. See each endpoint in the API reference for every field and to try it from the documentation.