> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Transport Route

> Create a new transport route with one or more sections. Emissions are calculated asynchronously.

# Create Transport Route

Create a new transport route for your organization. A route consists of one or more sections (legs), each describing a segment of the journey with its own transport mode and distance. Distances are geocoded automatically from origin/destination addresses, or you can override them with `kms_manual`.

After creation the route is in `status: pending`. Emissions are calculated asynchronously — poll [GET /v1/transports/{id}](/api-reference/transport/get) until `status` becomes `active` or `error`.

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication

  **Example:** `sk_live_1234567890abcdef`
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization UUID

  **Example:** `a8315ef3-dd50-43f8-b7ce-d839e68d51fa`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

### Body

<ParamField body="name" type="string">
  Optional human-readable label for this route (e.g. `"Barcelona → Damascus Q2"`)
</ParamField>

<ParamField body="transport_date" type="date" required>
  Date of the transport event (YYYY-MM-DD)

  **Example:** `"2024-06-15"`
</ParamField>

<ParamField body="quantity_transported" type="decimal" required>
  Amount of cargo transported. Must be greater than 0, max 10 digits with 3 decimal places.

  **Example:** `1500.000`
</ParamField>

<ParamField body="supplier" type="string">
  Optional supplier or carrier name
</ParamField>

<ParamField body="transport_direction" type="string" required>
  Direction of the transport:

  * `downstream` — outbound, goods sent to customers
  * `upstream` — inbound, goods received from suppliers
</ParamField>

<ParamField body="unit_id" type="UUID" required>
  UUID of the unit of measurement for `quantity_transported`. Common values:

  | Unit             | UUID                                   |
  | ---------------- | -------------------------------------- |
  | kilogram (kg)    | `61743a63-ff70-459c-9567-5eee8f7dfd5c` |
  | metric tonne (t) | `cab66828-c2b1-431b-92af-f9ab37149d3c` |
</ParamField>

<ParamField body="sections" type="array" required>
  Ordered list of transport legs. At least one section is required. Sections are processed in order and assigned `part` numbers starting from 1.

  <Expandable title="section fields">
    <ParamField body="sections[].transport_type" type="string" required>
      Mode of transport for this leg:

      * `road` — truck, car, or other road vehicle
      * `air` — air freight
      * `maritime` — sea freight
      * `rail` — train
      * `do_not_know` — let Dcycle infer the best mode from the origin/destination pair
    </ParamField>

    <ParamField body="sections[].travel_method" type="string">
      Road sub-type (only relevant when `transport_type` is `road`): `car`, `truck`, `motorbike`, `bicycle`, `electric_kick_scooter`
    </ParamField>

    <ParamField body="sections[].electric" type="boolean" required>
      Whether the vehicle is electrically powered. Set to `false` when unknown.
    </ParamField>

    <ParamField body="sections[].refrigerated" type="boolean" required>
      Whether the cargo requires refrigeration. Set to `false` when unknown.
    </ParamField>

    <ParamField body="sections[].distance_manual" type="boolean" required>
      Whether the distance is manually provided via `kms_manual`. Set to `true` when providing `kms_manual`, or `false` when using origin/destination geocoding.
    </ParamField>

    <ParamField body="sections[].detail" type="string">
      Additional detail for emission factor selection. Values use a `property:operator:value` format:

      **Distance bands (maritime/air):** `distance:ge:4000`, `distance:ge:1500`, `distance:ge:800`, `distance:lt:800`

      **Weight classes (road):** `weight:ge:32000`, `weight:ge:16000`, `weight:ge:7500`, `weight:ge:3500`

      Leave unset to use the default factor for the transport type.
    </ParamField>

    <ParamField body="sections[].origin" type="string">
      Origin address for this leg (e.g. `"Madrid, Spain"`). Dcycle geocodes this address and computes the distance to the destination automatically. Required if `kms_manual` is not provided.
    </ParamField>

    <ParamField body="sections[].destination" type="string">
      Destination address for this leg (e.g. `"Barcelona Port, Spain"`). Required if `kms_manual` is not provided.
    </ParamField>

    <ParamField body="sections[].kms_manual" type="decimal">
      Distance override in kilometers. Use this to bypass geocoding entirely. Must be greater than 0, max 7 digits with 2 decimal places.

      **Example:** `4626.00`
    </ParamField>
  </Expandable>
</ParamField>

## Response

Returns the newly created `TransportRouteSch` object with HTTP status **201 Created**.

<Note>
  Emissions are calculated asynchronously. Immediately after creation, `status` will be `pending` and `co2e` will be `null`. Poll [GET /v1/transports/{id}](/api-reference/transport/get) until `status` is `active` (success) or `error` (calculation failed). Typical calculation time is a few seconds per section.
</Note>

<ResponseField name="id" type="string">
  Unique identifier (UUID) of the new route
</ResponseField>

<ResponseField name="name" type="string | null">
  Route name as provided
</ResponseField>

<ResponseField name="transport_date" type="date | null">
  Date of transport (YYYY-MM-DD)
</ResponseField>

<ResponseField name="quantity_transported" type="number">
  Amount transported
</ResponseField>

<ResponseField name="supplier" type="string | null">
  Supplier name as provided
</ResponseField>

<ResponseField name="transport_direction" type="string">
  `downstream` or `upstream`
</ResponseField>

<ResponseField name="transport_frequency" type="string | null">
  Recurrence value set by the system: `once`, `weekly`, `monthly`
</ResponseField>

<ResponseField name="unit" type="object">
  Resolved unit of measurement

  <Expandable title="unit fields">
    <ResponseField name="unit.id" type="string">UUID of the unit</ResponseField>
    <ResponseField name="unit.name" type="string">Unit name, e.g. `kilogram_(kg)`, `metric_tonne_(t)`</ResponseField>
    <ResponseField name="unit.type" type="string">Unit type, e.g. `solid`, `liquid`</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="co2e" type="number | null">
  Total CO2-equivalent emissions in kg. `null` immediately after creation — available once `status` is `active`.
</ResponseField>

<ResponseField name="emissions" type="array">
  Route-level emissions summary. Empty until calculation completes.
</ResponseField>

<ResponseField name="status" type="string">
  `pending` immediately after creation. Transitions to `active` when calculation succeeds, or `error` if it fails.
</ResponseField>

<ResponseField name="file_id" type="string | null">
  Always `null` for routes created via this endpoint (only set for bulk-uploaded routes)
</ResponseField>

<ResponseField name="sections" type="array">
  Created sections with their assigned `part` numbers and initial geocoding state. See [Get Transport Route](/api-reference/transport/get) for the full section schema.
</ResponseField>

<ResponseField name="uploaded_by" type="object | null">
  The authenticated user who created this route
</ResponseField>

<ResponseField name="created_at" type="datetime">
  ISO 8601 creation timestamp
</ResponseField>

<ResponseField name="updated_at" type="datetime | null">
  ISO 8601 last-update timestamp
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL (API Key) theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST "https://api.dcycle.io/v1/transports" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Madrid to Syria Shipment",
      "transport_date": "2024-06-15",
      "quantity_transported": 1500.000,
      "supplier": "LogiTrans S.A.",
      "transport_direction": "downstream",
      "unit_id": "61743a63-ff70-459c-9567-5eee8f7dfd5c",
      "sections": [
        {
          "transport_type": "road",
          "travel_method": "truck",
          "electric": false,
          "refrigerated": false,
          "distance_manual": false,
          "origin": "Madrid, Spain",
          "destination": "Barcelona Port, Spain"
        },
        {
          "transport_type": "maritime",
          "electric": false,
          "refrigerated": false,
          "distance_manual": false,
          "detail": "distance:ge:1500",
          "origin": "Barcelona Port, Spain",
          "destination": "Latakia Port, Syria"
        }
      ]
    }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os
  import time

  response = requests.post(
      "https://api.dcycle.io/v1/transports",
      headers={
          "x-api-key": os.getenv("DCYCLE_API_KEY"),
          "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
      },
      json={
          "name": "Madrid to Syria Shipment",
          "transport_date": "2024-06-15",
          "quantity_transported": 1500.000,
          "supplier": "LogiTrans S.A.",
          "transport_direction": "downstream",
          "unit_id": "61743a63-ff70-459c-9567-5eee8f7dfd5c",
          "sections": [
              {
                  "transport_type": "road",
                  "travel_method": "truck",
                  "electric": False,
                  "refrigerated": False,
                  "distance_manual": False,
                  "origin": "Madrid, Spain",
                  "destination": "Barcelona Port, Spain",
              },
              {
                  "transport_type": "maritime",
                  "electric": False,
                  "refrigerated": False,
                  "distance_manual": False,
                  "detail": "distance:ge:1500",
                  "origin": "Barcelona Port, Spain",
                  "destination": "Latakia Port, Syria",
              },
          ],
      },
  )

  route = response.json()
  route_id = route["id"]
  print(f"Created route {route_id} with status: {route['status']}")

  # Poll until calculated
  while route["status"] == "pending":
      time.sleep(2)
      route = requests.get(
          f"https://api.dcycle.io/v1/transports/{route_id}",
          headers={
              "x-api-key": os.getenv("DCYCLE_API_KEY"),
              "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
          },
      ).json()

  print(f"Final status: {route['status']}, CO2e: {route['co2e']} kgCO2e")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const headers = {
    'x-api-key': process.env.DCYCLE_API_KEY,
    'x-organization-id': process.env.DCYCLE_ORG_ID,
  };

  async function createAndWait() {
    const { data: route } = await axios.post(
      'https://api.dcycle.io/v1/transports',
      {
        name: 'Madrid to Syria Shipment',
        transport_date: '2024-06-15',
        quantity_transported: 1500.0,
        supplier: 'LogiTrans S.A.',
        transport_direction: 'downstream',
        unit_id: '61743a63-ff70-459c-9567-5eee8f7dfd5c',
        sections: [
          {
            transport_type: 'road',
            travel_method: 'truck',
            electric: false,
            refrigerated: false,
            distance_manual: false,
            origin: 'Madrid, Spain',
            destination: 'Barcelona Port, Spain',
          },
          {
            transport_type: 'maritime',
            electric: false,
            refrigerated: false,
            distance_manual: false,
            detail: 'distance:ge:1500',
            origin: 'Barcelona Port, Spain',
            destination: 'Latakia Port, Syria',
          },
        ],
      },
      { headers },
    );

    console.log(`Created route ${route.id} — status: ${route.status}`);

    // Poll until calculated
    let current = route;
    while (current.status === 'pending') {
      await new Promise(resolve => setTimeout(resolve, 2000));
      const { data } = await axios.get(
        `https://api.dcycle.io/v1/transports/${route.id}`,
        { headers },
      );
      current = data;
    }

    console.log(`Final status: ${current.status}, CO2e: ${current.co2e} kgCO2e`);
  }

  createAndWait().catch(console.error);
  ```
</CodeGroup>

### Successful Response (201 Created)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "010ed3b6-b513-40f3-b9fe-0f0a338d9274",
  "name": "Madrid to Syria Shipment",
  "transport_date": "2024-06-15",
  "quantity_transported": 1500.0,
  "supplier": "LogiTrans S.A.",
  "transport_direction": "downstream",
  "transport_frequency": null,
  "unit": {
    "id": "61743a63-ff70-459c-9567-5eee8f7dfd5c",
    "name": "kilogram_(kg)",
    "type": "solid"
  },
  "co2e": null,
  "emissions": [],
  "status": "pending",
  "file_id": null,
  "file_name": null,
  "sections": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "part": 1,
      "transport_type": "road",
      "travel_method": "truck",
      "electric": false,
      "refrigerated": false,
      "detail": null,
      "origin": "Madrid, Spain",
      "destination": "Barcelona Port, Spain",
      "kms": null,
      "kms_manual": null,
      "distance_manual": false,
      "kms_source": null,
      "status": "pending",
      "step": "geocoding",
      "error_messages": null,
      "emissions": null,
      "created_at": "2024-06-10T09:00:00Z",
      "updated_at": "2024-06-10T09:00:00Z"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "part": 2,
      "transport_type": "maritime",
      "travel_method": null,
      "electric": false,
      "refrigerated": false,
      "detail": "distance:ge:1500",
      "origin": "Barcelona Port, Spain",
      "destination": "Latakia Port, Syria",
      "kms": null,
      "kms_manual": null,
      "distance_manual": false,
      "kms_source": null,
      "status": "pending",
      "step": "geocoding",
      "error_messages": null,
      "emissions": null,
      "created_at": "2024-06-10T09:00:00Z",
      "updated_at": "2024-06-10T09:00:00Z"
    }
  ],
  "uploaded_by": {
    "id": "user-123",
    "first_name": "Maria",
    "last_name": "García",
    "profile_img_url": null
  },
  "created_at": "2024-06-10T09:00:00Z",
  "updated_at": "2024-06-10T09:00:00Z"
}
```

## Common Errors

### 401 Unauthorized

**Cause:** Missing or invalid API key / JWT token

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"detail": "Invalid API key for organization", "code": "INVALID_API_KEY"}
```

### 403 Forbidden

**Cause:** The authenticated user is not a member of the organization

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"detail": "Logged User is not Member of Organization", "code": "LOGGED_USER_NOT_MEMBER"}
```

### 404 Not Found

**Cause:** The provided `unit_id` does not exist

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"detail": "Unit not found", "code": "UNIT_NOT_FOUND"}
```

### 422 Unprocessable Entity

**Cause:** Missing required field or invalid value

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["body", "transport_direction"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
```

**Cause:** `sections` array is empty

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["body", "sections"],
      "msg": "ensure this value has at least 1 items",
      "type": "value_error.list.min_items"
    }
  ]
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Get Transport Route" icon="magnifying-glass" href="/api-reference/transport/get">
    Retrieve a single route by ID (use this to poll for calculated emissions)
  </Card>

  <Card title="List Transport Routes" icon="list" href="/api-reference/transport/list">
    Retrieve all transport routes with filtering and pagination
  </Card>

  <Card title="Update Transport Route" icon="pencil" href="/api-reference/transport/update">
    Modify a transport route and its sections
  </Card>

  <Card title="Transport Overview" icon="book" href="/api-reference/transport/overview">
    Full data model and distance calculation reference
  </Card>
</CardGroup>
