Skip to main content
POST
/
v1
/
transports
/
upload
Upload Transport File
const options = {
  method: 'POST',
  headers: {'x-organization-id': '<x-organization-id>', 'Content-Type': 'application/json'},
  body: JSON.stringify({transport_direction: '<string>'})
};

fetch('https://api.dcycle.io/v1/transports/upload', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
{
  "message": "<string>",
  "file_id": "<string>"
}

Upload Transport File

Upload a spreadsheet file containing transport routes. The file is processed asynchronously — rows are parsed, geocoded, and emission factors are resolved in the background after the upload returns.
For files larger than a few MB, use the Presigned URL approach instead. It uploads the file directly to S3 without routing the bytes through the API server.

Request

Headers

x-api-key
string
API key for authentication. Either this header or Authorization is required.Example: sk_live_1234567890abcdef
Authorization
string
Bearer token for authentication. Either this header or x-api-key is required.Example: Bearer sk_live_1234567890abcdef
x-organization-id
string
required
Your organization UUID.Example: a8315ef3-dd50-43f8-b7ce-d839e68d51fa

Body (multipart/form-data)

transport_direction
string
required
The GHG Protocol scope 3 direction of these transport routes.
  • downstream — transport paid by your organization after the sale (Category 9)
  • upstream — inbound transport paid by your organization (Category 4)
upload_file
file
required
The spreadsheet file to upload. Accepted formats: .csv, .xls, .xlsx.

Response

message
string
Human-readable confirmation message.Example: "Transport route file uploaded"
file_id
string
UUID that identifies this upload batch. Use it to filter routes via GET /v1/transports?file_id=<file_id> or to track processing progress.Example: "b3d7c1e2-4a5f-48d9-b6e8-1234567890ab"

Example

curl -X POST "https://api.dcycle.io/v1/transports/upload" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -F "transport_direction=downstream" \
  -F "upload_file=@transport_routes.xlsx"

Successful Response

{
  "message": "Transport route file uploaded",
  "file_id": "b3d7c1e2-4a5f-48d9-b6e8-1234567890ab"
}

Asynchronous Processing

The endpoint returns immediately with status 201. The actual processing happens in the background:
  1. Rows are parsed from the uploaded file.
  2. Origin and destination addresses are geocoded (Google Maps Distance Matrix API for road/rail, haversine for air, sea-distance tables for maritime).
  3. Emission factors are resolved and CO2e values are calculated.
You can poll the processing status by listing routes filtered by the returned file_id:
curl "https://api.dcycle.io/v1/transports?file_id=b3d7c1e2-4a5f-48d9-b6e8-1234567890ab" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}"
Route statuses move through pendingactive (success) or error as processing completes.

Common Errors

401 Unauthorized

Cause: Missing or invalid API key / Bearer token.
{
  "detail": "Invalid API key",
  "code": "INVALID_API_KEY"
}

422 Unprocessable Entity

Cause: transport_direction is missing or not one of the accepted values.
{
  "detail": [
    {
      "loc": ["body", "transport_direction"],
      "msg": "value is not a valid enumeration member",
      "type": "type_error.enum"
    }
  ]
}
Solution: Set transport_direction to downstream or upstream.

400 Bad Request

Cause: Unsupported file format (not .csv, .xls, or .xlsx).
{
  "detail": "Unsupported file format. Use CSV, XLS, or XLSX.",
  "code": "INVALID_FILE_FORMAT"
}

Presigned URL Upload

Upload large files directly to S3 via a presigned URL

List Transport Routes

Retrieve transport routes, filter by file_id to track batch processing

Transport Combinations

Explore valid transport type and method combinations before creating routes

Transport Overview

Learn the full Transport API data model and workflow