Skip to main content
POST
/
v2
/
logistics
/
requests
Create Logistics Request (v2)
const options = {method: 'POST'};

fetch('https://api.dcycle.io/v2/logistics/requests', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
{
  "co2e": {},
  "distance_km": {},
  "tkm": {}
}

Create Logistics Request (v2)

v2 of Create Logistics Request. It accepts the exact same request body and returns the same response shape, but the expensive distance and emissions calculation is performed asynchronously instead of inline. This keeps the request fast and predictable for high-volume integrations.
Same contract as v1. Headers, body parameters and validation are identical to POST /v1/logistics/requests. Only the timing of the distance/emissions calculation changes. See the v1 reference for the full list of body parameters.

v1 vs v2

Behaviourv1 (/v1/logistics/requests)v2 (/v2/logistics/requests)
Distance calculation (when distance_km omitted)Calculated inline, returned in the responseDeferred to an async worker, null in the immediate response
Emissions (co2e)Calculated inline, returned in the responseDeferred to an async worker, null in the immediate response
tkmReturned in the responseReturned only if distance_km was provided; otherwise null until the async calc runs
Response latencyHigher (waits for geocoding + distance APIs)Low (returns as soon as the record is persisted)
In v2, co2e is always null in the immediate response, and distance_km / tkm are null whenever the client did not supply distance_km. These fields are populated asynchronously. Read them back later via GET /v1/logistics/requests (filter by movement_id) once the calculation has completed.

Request

The request is identical to v1. Minimal example:
curl -X POST "https://api.dcycle.io/v2/logistics/requests" \
  -H "x-api-key: $DCYCLE_API_KEY" \
  -H "x-organization-id: $DCYCLE_ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "origin": "Madrid, Spain",
    "destination": "Barcelona, Spain",
    "origin_country": "ES",
    "load": 1000,
    "load_unit": "kg",
    "toc": "truck_diesel",
    "year": 2024
  }'

Response

The response shape matches v1, with co2e (and distance_km / tkm when not provided) returned as null while the asynchronous calculation is pending.
{
  "id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
  "origin": "Madrid, Spain",
  "destination": "Barcelona, Spain",
  "origin_country": "ES",
  "distance_km": null,
  "load": 1000,
  "load_unit": "kg",
  "toc": "truck_diesel",
  "category": "road",
  "year": 2024,
  "co2e": null,
  "tkm": null,
  "created_at": "2026-06-23T09:00:00Z",
  "updated_at": "2026-06-23T09:00:00Z"
}
co2e
number | null
Total CO2 equivalent emissions in kilograms. null in v2 until the asynchronous calculation completes.
distance_km
number | null
Distance in kilometers. Echoes the value you provided; null when omitted (it is calculated asynchronously).
tkm
number | null
Tonne-kilometers. Computed up front when distance_km is provided; otherwise null until the asynchronous calculation completes.
All other response fields (id, origin, destination, load, toc, category, traceability fields, etc.) are returned exactly as documented for v1.

Reading back the calculated values

Because the calculation is asynchronous, poll the list endpoint (filtering by the movement_id you submitted) until kgco2e / distance_km are populated:
curl -X GET "https://api.dcycle.io/v1/logistics/requests?search=MOV-2024-001234" \
  -H "x-api-key: $DCYCLE_API_KEY" \
  -H "x-organization-id: $DCYCLE_ORG_ID"
Migrating from v1? No code changes are required beyond the URL prefix and handling co2e (and possibly distance_km / tkm) being null in the immediate response.