Skip to main content

Logistics API

The Logistics API allows you to calculate, track, and report CO2e emissions for freight transport operations. Following the ISO 14083 standard, it provides accurate Well-to-Wheel (WTW) emissions calculations for road, rail, maritime, and air transport.
New API: This endpoint is part of the new API architecture with improved design and maintainability.

Key Features

  • ISO 14083 Compliant: Calculations follow the international standard for transport emissions
  • Multiple Transport Modes: Support for road, rail, maritime, and air freight
  • Flexible Distance Input: Provide addresses for automatic calculation or direct distance values
  • Hub Integration: Use registered logistics hubs as origin/destination points
  • Package Tracking: Track emissions across multi-leg shipments with package aggregation
  • High-Volume Processing: Bulk endpoint for processing up to 5,000 records per request
  • Client Segmentation: Track emissions by client for reporting and billing

Authentication

All endpoints require authentication using:
  • API Key: Include in x-api-key header

Headers

All requests must include:
x-api-key
string
required
Your API key for authenticationExample: sk_live_1234567890abcdef
x-organization-id
string
required
Your organization UUIDExample: a8315ef3-dd50-43f8-b7ce-d839e68d51fa

Available Endpoints

Core Concepts

Transport Operation Categories (TOCs)

ISO 14083 defines standard vehicle categories for emissions calculation:
CategoryExamplesTypical Use
roadvan, rigid truck, articulated truckGround freight
railfreight trainBulk goods, intermodal
maritimecontainer ship, bulk carrierInternational shipping
aircargo aircraftExpress shipments

Well-to-Wheel (WTW) Methodology

Emissions include the complete fuel cycle:
  • WTT (Well-to-Tank): Fuel extraction, refining, and distribution
  • TTW (Tank-to-Wheel): Direct combustion emissions

Packages and Legs

  • Leg: A single transport segment (origin → destination)
  • Package: A tracked item that may travel through multiple legs
  • Package Key: Unique identifier linking legs to a package

Workflow

Single Shipment Calculation

import requests

response = requests.post(
    "https://api.dcycle.io/v1/logistics/requests",
    headers={
        "x-api-key": api_key,
        "x-organization-id": org_id
    },
    json={
        "origin": "Madrid, Spain",
        "destination": "Barcelona, Spain",
        "load": 1000,
        "load_unit": "kg",
        "category": "road"
    }
)

result = response.json()
print(f"Distance: {result['distance_km']} km")
print(f"CO2e: {result['co2e']} kg")

Bulk Processing

For high-volume operations (e.g., daily batch uploads):
response = requests.post(
    "https://api.dcycle.io/v1/logistics/requests/bulk",
    headers=headers,
    json={
        "records": [
            {"origin": "Madrid", "destination": "Barcelona", "load": 500, "category": "road"},
            {"origin": "Madrid", "destination": "Valencia", "load": 300, "category": "road"},
            # ... up to 5,000 records
        ],
        "options": {"continue_on_error": True}
    }
)

result = response.json()
print(f"Success: {result['success']}, Failed: {result['failed']}")

Multi-leg Package Tracking

Track a package through its journey:
# Leg 1: Hub to regional center
requests.post(url, json={
    "origin": "Madrid Hub",
    "destination": "Valencia Hub",
    "package_key": "PKG-12345",
    "movement_id": "SHIP-001",
    "load": 15, "category": "road"
})

# Leg 2: Regional center to final destination
requests.post(url, json={
    "origin": "Valencia Hub",
    "destination": "Customer Address",
    "package_key": "PKG-12345",  # Same package
    "movement_id": "SHIP-001",
    "load": 15, "category": "road"
})

# Get aggregated package emissions
package = requests.get(f"{url}/packages?package_key=PKG-12345")
print(f"Total CO2e: {package.json()['items'][0]['total_co2e']} kg")

Request Attributes

Location Input

You can specify locations in two ways: Option 1: Addresses (auto-calculate distance)
{
  "origin": "Madrid, Spain",
  "destination": "Barcelona, Spain"
}
Option 2: Direct distance
{
  "distance_km": 620
}

Load Specification

  • load (number): Cargo weight/quantity
  • load_unit (string): kg, ton, pallets, teu, feu
  • load_factor (number): Multiplier 0-1 (e.g., 0.5 for half load)

Vehicle Selection

  • toc (string): Specific vehicle type (e.g., van_diesel, rigid_diesel)
  • category (string): General category if TOC unknown (road, rail, maritime, air)

Traceability

  • movement_id (string): Unique shipment identifier
  • client (string): Client/customer code
  • shipment_date (date): Date of shipment
  • package_key (string): Package identifier for multi-leg tracking

Response Format

Logistics Request Object

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "origin": "Madrid, Spain",
  "destination": "Barcelona, Spain",
  "distance_km": 621.5,
  "load": 1000,
  "load_unit": "kg",
  "category": "road",
  "toc": "generic_average_road",
  "co2e": 95.23,
  "tkm": 621.5,
  "movement_id": "SHIP-001",
  "client": "AMAZON",
  "package_id": "660e8400-e29b-41d4-a716-446655440000",
  "created_at": "2024-12-01T10:30:00Z"
}

Package Object

{
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "package_key": "PKG-12345",
  "total_distance_km": 850.0,
  "total_co2e": 130.45,
  "legs_count": 2,
  "created_at": "2024-12-01T10:30:00Z"
}

Error Handling

Common HTTP Status Codes

StatusMeaningSolution
200Success-
400Bad RequestCheck request parameters
401UnauthorizedVerify API key
404Not FoundCheck organization ID or resource
422Validation ErrorReview error details

Error Response Format

{
  "detail": "Error description",
  "code": "ERROR_CODE"
}

Common Validation Errors

ErrorCauseSolution
TOC not foundInvalid vehicle typeUse /tocs endpoint to get valid options
Load not foundMissing load and no defaultProvide load parameter
Distance calculation failedInvalid addressesUse distance_km directly or fix addresses

Use Cases

Logistics Provider Daily Upload

Process daily shipment data:
import pandas as pd

# Load daily shipments from CSV
df = pd.read_csv("daily_shipments.csv")

records = df.to_dict(orient="records")

# Process in bulk
response = requests.post(
    "https://api.dcycle.io/v1/logistics/requests/bulk",
    headers=headers,
    json={"records": records, "options": {"continue_on_error": True}}
)

result = response.json()
print(f"Processed: {result['success']}/{result['total_received']}")

Client Emissions Report

Generate emissions report for a specific client:
report = requests.get(
    "https://api.dcycle.io/v1/logistics/report",
    headers=headers,
    params={
        "start_date": "2024-01-01",
        "end_date": "2024-12-31",
        "client": "AMAZON"
    }
)

data = report.json()
print(f"Total CO2e: {data['summary']['total_co2e_kg']} kg")
print(f"Total packages: {data['summary']['total_items']}")

GHG Protocol Context

Logistics emissions typically fall under Scope 3 of the GHG Protocol:
  • Category 4: Upstream Transportation and Distribution
  • Category 9: Downstream Transportation and Distribution
The classification depends on who pays for the transport:
  • Category 4: Transport paid by your organization (inbound logistics)
  • Category 9: Transport paid by customers (outbound logistics)

Rate Limiting

API requests are subject to rate limiting:
  • X-RateLimit-Limit: Maximum requests per minute
  • X-RateLimit-Remaining: Requests remaining
  • X-RateLimit-Reset: Unix timestamp when limit resets
For high-volume processing, use the bulk endpoint to minimize API calls and improve throughput.