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

# Bulk Delete Transport Routes by Filters

> Delete all transport routes matching the same filters used in the list endpoint

# Bulk Delete Transport Routes by Filters

Delete every transport route that matches a given set of filters — the same filters accepted by the `GET /v1/transports` list endpoint. This avoids having to collect IDs manually when you want to clear a whole date range, file upload, or status group.

A `filter_hash` safety token (returned by the list endpoint) must be included in the request body. This confirms you are deleting exactly the set of records you previewed, and rejects the request if the filters changed in the meantime.

<Warning>
  This operation is irreversible. All matching transport routes, their sections, and their `total_impacts` records are permanently deleted. Always call `GET /v1/transports` with the same filters first and review the results before proceeding.
</Warning>

## Typical Flow

1. Call `GET /v1/transports` with your desired filters.
2. Save the `filter_hash` field from the response.
3. Call `POST /v1/transports/bulk-delete-by-filters` with the **same query parameters** and the `filter_hash` in the request body.

If any filter parameter differs between steps 1 and 3, the server returns a `409 Conflict`.

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

### Query Parameters

At least one non-empty query parameter is required to prevent accidental mass deletion.

<ParamField query="search" type="string">
  Free-text search against route name and supplier
</ParamField>

<ParamField query="from_date" type="date">
  Include only routes with a transport date on or after this date (YYYY-MM-DD)
</ParamField>

<ParamField query="to_date" type="date">
  Include only routes with a transport date on or before this date (YYYY-MM-DD)
</ParamField>

<ParamField query="status" type="array of string">
  Filter by route status. Allowed values: `pending`, `active`, `error`. Repeat the parameter to include multiple statuses.
</ParamField>

<ParamField query="transport_direction" type="string">
  `downstream` (outbound) or `upstream` (inbound)
</ParamField>

<ParamField query="file_id" type="array of UUID">
  Filter to routes created by a specific file upload. Repeat the parameter for multiple files.
</ParamField>

<ParamField query="created_at_from" type="datetime">
  Include only routes created on or after this ISO 8601 datetime
</ParamField>

<ParamField query="created_at_to" type="datetime">
  Include only routes created on or before this ISO 8601 datetime
</ParamField>

<ParamField query="co2e_status" type="string">
  `calculated` (routes with at least one impact) or `not_calculated` (routes with no impacts yet)
</ParamField>

<ParamField query="supplier" type="array of string">
  Filter by supplier name (exact match). Pass multiple values to include routes from several suppliers.
</ParamField>

### Body

<ParamField body="filter_hash" type="string" required>
  The `filter_hash` value returned by `GET /v1/transports` with the same set of filters. Acts as a safety token: if the hash does not match the current filter combination a `409 Conflict` is returned.

  **Example:** `"a3f1c9e2d7b84056af19c3e0b1d72a84"`
</ParamField>

## Response

<ResponseField name="success_count" type="integer">
  Number of transport routes successfully deleted
</ResponseField>

<ResponseField name="success_ids" type="array">
  UUIDs of the transport routes that were successfully deleted
</ResponseField>

<ResponseField name="failed_count" type="integer">
  Number of transport routes that could not be deleted
</ResponseField>

<ResponseField name="failed_ids" type="array">
  UUIDs of the transport routes that failed
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable summary of the operation outcome
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL (API Key) theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Step 1 — list and capture the filter_hash
  curl -G "https://api.dcycle.io/v1/transports" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    --data-urlencode "from_date=2024-01-01" \
    --data-urlencode "to_date=2024-03-31" \
    --data-urlencode "status=error"

  # Step 2 — delete using the same filters + the filter_hash from step 1
  curl -X POST "https://api.dcycle.io/v1/transports/bulk-delete-by-filters?from_date=2024-01-01&to_date=2024-03-31&status=error" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{"filter_hash": "a3f1c9e2d7b84056af19c3e0b1d72a84"}'
  ```

  ```bash cURL (JWT) theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST "https://api.dcycle.io/v1/transports/bulk-delete-by-filters?from_date=2024-01-01&to_date=2024-03-31&status=error" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{"filter_hash": "a3f1c9e2d7b84056af19c3e0b1d72a84"}'
  ```

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

  base_url = "https://api.dcycle.io/v1/transports"
  headers = {
      "x-api-key": os.getenv("DCYCLE_API_KEY"),
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
  }
  filters = {
      "from_date": "2024-01-01",
      "to_date": "2024-03-31",
      "status": "error",
  }

  # Step 1 — list to get the filter_hash
  list_response = requests.get(base_url, headers=headers, params=filters)
  filter_hash = list_response.json()["filter_hash"]
  print(f"Deleting {list_response.json()['total']} routes matching filters...")

  # Step 2 — delete with same filters + filter_hash
  delete_response = requests.post(
      f"{base_url}/bulk-delete-by-filters",
      headers=headers,
      params=filters,
      json={"filter_hash": filter_hash},
  )

  result = delete_response.json()
  print(result["message"])
  ```

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

  const baseUrl = 'https://api.dcycle.io/v1/transports';
  const headers = {
    'x-api-key': process.env.DCYCLE_API_KEY,
    'x-organization-id': process.env.DCYCLE_ORG_ID,
  };
  const filters = {
    from_date: '2024-01-01',
    to_date: '2024-03-31',
    status: 'error',
  };

  // Step 1 — list to get the filter_hash
  axios.get(baseUrl, { headers, params: filters })
    .then(({ data: listData }) => {
      const filterHash = listData.filter_hash;
      console.log(`Deleting ${listData.total} routes matching filters...`);

      // Step 2 — delete with same filters + filter_hash
      return axios.post(
        `${baseUrl}/bulk-delete-by-filters`,
        { filter_hash: filterHash },
        { headers, params: filters },
      );
    })
    .then(({ data }) => console.log(data.message))
    .catch(error => console.error(error));
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "success_count": 47,
  "success_ids": [
    "010ed3b6-b513-40f3-b9fe-0f0a338d9274",
    "550e8400-e29b-41d4-a716-446655440000"
  ],
  "failed_count": 0,
  "failed_ids": [],
  "message": "Successfully deleted 47 transport route(s)"
}
```

### No matching records

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "success_count": 0,
  "success_ids": [],
  "failed_count": 0,
  "failed_ids": [],
  "message": "No records match the given filters"
}
```

## 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"}
```

### 409 Conflict

**Cause:** The `filter_hash` does not match the current set of query parameters. This happens when the filters passed to this endpoint differ from the ones used when the list was fetched.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Filter hash mismatch. The filters have changed since the list was loaded. Please refresh and try again."
}
```

**Solution:** Re-fetch `GET /v1/transports` with your intended filters, copy the new `filter_hash`, and retry with exactly the same query parameters.

### 422 Unprocessable Entity

**Cause:** No query parameters were provided (all filters are empty)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "At least one filter parameter is required for bulk delete by filters."
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Transport Routes" icon="list" href="/api-reference/transport/list">
    Retrieve all transport routes — the source of the filter\_hash
  </Card>

  <Card title="Bulk Delete by IDs" icon="trash" href="/api-reference/transport/bulk-delete">
    Delete specific transport routes by their IDs
  </Card>

  <Card title="Delete Transport Route" icon="circle-minus" href="/api-reference/transport/delete">
    Delete a single transport route by ID
  </Card>

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