Skip to main content

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:

IDWhat it isStep
branchAddressIdThe pickup address, where the package is collected.3
branchsClientIdThe recipient client. The order is delivered to the client's registered address.4
courierServiceIdThe 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​

Login
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.

  1. List the departments and take the departmentId you need:

    Departments
    curl https://api.volao.app/api/open/departments
  2. Get its municipalities:

    Department's municipalities
    curl -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):

Pickup addresses
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:

Create pickup address
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:

Search client
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):

Register client
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​

  1. Get the service modes and take the serviceModeCode (for example, NORMAL):

    Service modes
    curl https://api.volao.app/api/courier/serviceMode \
    -H "Authorization: Bearer <access_token>"
  2. Quote with the pickup address, the client's municipality (UUID), the weight and the amount to collect. Send an empty courierName to see every courier:

    Quote
    curl -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:

Create 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": "" }
}'
  • agencias is required, but it can be empty ({}). It's only filled when the chosen service works with agencies (GET /api/courier/agencies).
  • onDelivery: 1 means the amount is collected on delivery.

The response (201) includes the order ID and the shipping label:

Response
{
"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 label
    curl "https://api.volao.app/api/orders?OrderId=0199a1b2-7777-7e5f-8a6b-1c2d3e4f0008" \
    -H "Authorization: Bearer <access_token>"
  • Tracking (current status and movements):

    Tracking
    curl "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​

ResponseCauseWhat to do
401 Token inválido o expiradoMore than 15 minutes passed since the login.Repeat step 1.
409 about the amount to collectshippingAmount doesn't cover the shipment plus the commissions.Raise the amount to the minimum given in response_message.
409 about the addressThe branchAddressId doesn't exist or doesn't belong to your merchant.List your addresses again (step 3).
409 about the balanceYour prepaid balance doesn't cover the shipping cost.Top up your balance before creating the order.
400A 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.