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

# Get Route Counts

> Count transport routes grouped by calculation status, to show how many are still processing, calculated or failed

[← Transport API](/api-reference/transport/overview)

Count your transport routes grouped by calculation status. This is the cheap call behind a "12 pending · 480 calculated · 3 failed" header — it returns three integers rather than the routes themselves, so you can poll it after an upload without paging through the data.

<Note>
  **The three keys are always present.** The query only returns statuses that have rows, but the response fills the missing ones with `0`. A response of `{"pending": 0, "active": 0, "error": 0}` means "no routes match", not "no data available" — you never have to check whether a key exists.
</Note>

## Request

### Headers

<ParamField header="x-organization-id" type="string" required>
  UUID of the organization whose routes you are counting. Counting is scoped to this organization alone — routes belonging to child organizations of a holding are **not** included.

  **Format:** UUID
</ParamField>

<ParamField header="x-api-key" type="string">
  Your API key.
</ParamField>

### Query Parameters

<ParamField query="transport_direction" type="string">
  Restrict the count to one direction. Omit it to count both.

  **Available values:** `upstream`, `downstream`
</ParamField>

<ParamField query="file_id" type="string">
  Restrict the count to the routes imported from one file. This is the parameter that makes the endpoint useful right after a bulk upload: it answers "how is *my* import doing", not "how is the whole organization doing".

  **Format:** UUID

  Takes a single value. The [list](/api-reference/transport/list) endpoint accepts several through a repeated `file_id` parameter; this one does not.
</ParamField>

<Warning>
  **These counts are not the same population as the list or the totals**, in two ways, and neither is visible in the response.

  **No date filter.** Unlike [Get Totals](/api-reference/transport/totals), this endpoint counts every route that matches the two filters above, whatever its date. It cannot build a per-period counter — it will silently include every other period.

  **Disabled routes are counted.** The list and the totals both restrict themselves to `enabled` routes; this endpoint does not. A route that was logically deleted still adds to these numbers while contributing nothing to your emissions, so `active` here can exceed the record count you see anywhere else.
</Warning>

## Response

<ResponseField name="pending" type="integer" default="0">
  Routes queued for calculation and not yet processed.
</ResponseField>

<ResponseField name="active" type="integer" default="0">
  Routes calculated successfully. Note that this includes logically deleted routes, which do **not** feed your emissions totals — see the warning above.
</ResponseField>

<ResponseField name="error" type="integer" default="0">
  Routes whose calculation failed. A non-zero value here means part of your data is not in the totals — inspect them through the [list](/api-reference/transport/list) endpoint with `status=error`.
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Every route in the organization, by status
  curl -X GET "https://api.dcycle.io/v1/transports/counts" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "x-organization-id: YOUR_ORGANIZATION_ID"

  # Just the routes that came from one upload
  curl -X GET "https://api.dcycle.io/v1/transports/counts?file_id=YOUR_FILE_ID" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "x-organization-id: YOUR_ORGANIZATION_ID"
  ```

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

  import requests

  HEADERS = {
      "x-api-key": "YOUR_API_KEY",
      "x-organization-id": "YOUR_ORGANIZATION_ID",
  }


  def wait_for_import(file_id, timeout=600, interval=10):
      """Poll until nothing is pending, then report what happened."""
      deadline = time.time() + timeout
      while time.time() < deadline:
          counts = requests.get(
              "https://api.dcycle.io/v1/transports/counts",
              headers=HEADERS,
              params={"file_id": file_id},
              timeout=30,
          ).json()

          if counts["pending"] == 0:
              return counts

          time.sleep(interval)

      raise TimeoutError(f"still pending after {timeout}s")


  result = wait_for_import("YOUR_FILE_ID")
  print(f"{result['active']} calculated, {result['error']} failed")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const params = new URLSearchParams({ file_id: fileId });
  const response = await fetch(
    `https://api.dcycle.io/v1/transports/counts?${params}`,
    {
      headers: {
        "x-api-key": "YOUR_API_KEY",
        "x-organization-id": "YOUR_ORGANIZATION_ID",
      },
    },
  );
  const counts = await response.json();

  const done = counts.pending === 0;
  console.log(`${counts.active} calculated, ${counts.error} failed`);
  ```
</CodeGroup>

### Successful Response

Returns `200 OK`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "pending": 12,
  "active": 480,
  "error": 3
}
```

## Common Errors

### 422 Unprocessable Entity

**Cause:** `x-organization-id` is missing.

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

**Cause:** `transport_direction` is not one of the two accepted values.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["query", "transport_direction"],
      "msg": "value is not a valid enumeration member; permitted: 'downstream', 'upstream'",
      "type": "type_error.enum",
      "ctx": {
        "enum_values": ["downstream", "upstream"]
      }
    }
  ]
}
```

## Use Cases

### Know when a bulk import has finished

After uploading transport routes, poll this endpoint with the `file_id` you uploaded until `pending` reaches `0`. It is far cheaper than paging the list endpoint, and it gives you the failure count in the same response — so you learn both *when* the import finished and *whether* it worked.

### Surface failures instead of losing them

A route in `error` is a route whose emissions are missing from your totals, and nothing in the totals themselves will tell you it is missing. Checking that `error` is `0` after each import turns a silent gap into a visible one.

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Transport Routes" icon="list" href="/api-reference/transport/list">
    The routes behind these counts, filterable by `status`
  </Card>

  <Card title="Get Totals" icon="chart-simple" href="/api-reference/transport/totals">
    Aggregated CO2e and quantity, with date filters
  </Card>

  <Card title="Create Transport Route" icon="plus" href="/api-reference/transport/create">
    Add the routes you will then be counting
  </Card>

  <Card title="Transport API" icon="truck" href="/api-reference/transport/overview">
    Everything the Transport API covers
  </Card>
</CardGroup>
