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

# Delete Logistics Requests (v2)

> Delete up to 5,000 logistics legs by id, asynchronously, as an ingest job

[← Logistics API](https://code.dcycle.io/api-reference/logistics/overview.md)

Delete logistics legs (shipments) by id. The request checks every id and answers `202 Accepted` with a **job** (see
[how bulk ingestion works](https://code.dcycle.io/api-reference/ingest-jobs/overview.md)); the deletion runs in the background, chunk by chunk,
so thousands of ids never hold your request open. Follow it with
[`GET /v2/ingest-jobs/{id}`](https://code.dcycle.io/api-reference/ingest-jobs/get) or, for a job submitted with an API key, the
[`ingest_job.finished`](https://code.dcycle.io/api-reference/webhooks/overview) webhook.

> [!WARNING]
>
> **Permanent.** Deleted legs and their emissions cannot be recovered. Use `dry_run=true` first if you are not sure.

> [!WARNING]
>
> **Beta.** Part of the bulk ingest API, in beta. The contract may still change before general availability.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST "https://api.dcycle.io/v2/logistics/requests/delete" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "Idempotency-Key: 7f3c2b10-5e4d-4a8b-9c1d-2e3f4a5b6c7d" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c", "4a3b2c1d-0e9f-4a8b-9c7d-6e5f4a3b2c1d"]}'
```

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

import requests

response = requests.post(
    "https://api.dcycle.io/v2/logistics/requests/delete",
    headers={
        "x-api-key": os.environ["DCYCLE_API_KEY"],
        "x-organization-id": os.environ["DCYCLE_ORG_ID"],
        "Idempotency-Key": str(uuid.uuid4()),  # keep it to retry this same batch
    },
    json={"ids": ["3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c", "4a3b2c1d-0e9f-4a8b-9c7d-6e5f4a3b2c1d"]},
    timeout=60,
)
response.raise_for_status()
job = response.json()
print(job["id"], job["status"])
```

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

const { data: job } = await axios.post(
  'https://api.dcycle.io/v2/logistics/requests/delete',
  { ids: ['3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c', '4a3b2c1d-0e9f-4a8b-9c7d-6e5f4a3b2c1d'] },
  {
    headers: {
      'x-api-key': process.env.DCYCLE_API_KEY,
      'x-organization-id': process.env.DCYCLE_ORG_ID,
      'Idempotency-Key': randomUUID(), // keep it to retry this same batch
    },
  },
);
console.log(job.id, job.status);
```

```json 202 theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "status": "processing",
  "entity_type": "logistics",
  "operation": "delete",
  "source": "api_bulk",
  "counts": { "submitted": 2, "succeeded": 0, "failed": 0 },
  "chunks_total": 1,
  "chunks_done": 0,
  "created_at": "2026-11-03T11:02:41.118Z",
  "finished_at": null,
  "links": {
    "self": "/v2/ingest-jobs/9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "items": "/v2/ingest-jobs/9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/items"
  }
}
```

```json 422 theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "https://code.dcycle.io/api-reference/errors#BULK_RECORDS_REJECTED",
  "title": "Unprocessable Entity",
  "status": 422,
  "code": "BULK_RECORDS_REJECTED",
  "detail": "1 of the submitted records are invalid; nothing was written.",
  "errors": [
    {
      "source_row_index": 1,
      "client_row_id": null,
      "error_code": "NOT_FOUND",
      "error_params": { "field": "ids", "value": "4a3b2c1d-0e9f-4a8b-9c7d-6e5f4a3b2c1d" }
    }
  ],
  "rejected": 1,
  "request_id": "b2248a31-0f1b-4a7d-83ce-b29bd5977b4c"
}
```

```json 200 (dry_run=true) theme={"theme":{"light":"github-light","dark":"github-dark"}}
{ "dry_run": true, "submitted": 2, "valid": 2 }
```

## How it works

1. **The request checks every id.** One that does not exist, belongs to another organization, is not active or is
   repeated rejects the **whole** request with `422` and nothing is deleted.
2. **The job deletes in the background**, 500 ids per chunk, each leg with its project links. The totals of the
   packages the legs belonged to (distance and emissions) are recalculated from their remaining legs; a package left
   without legs stays, with totals of `0`. A leg that someone else deleted in the meantime ends `failed` with
   `DELETE_FAILED`; the others go on.
3. **When every chunk is done** the job is `completed` (or `completed_with_errors`), and, for a job submitted with an
   API key, `ingest_job.finished` is sent to your webhook endpoints with `"operation": "delete"`.

If a [Create Logistics Requests (v2)](https://code.dcycle.io/api-reference/logistics/create-requests-v2.md) job is still calculating a leg you
delete, that job reports the leg `failed` with `NOT_FOUND`.

The organization's logistics intensity values (by TOC, hub and project) are not recalculated when the job finishes:
they catch up later, in the background, as after [Create Logistics Requests (v2)](https://code.dcycle.io/api-reference/logistics/create-requests-v2.md).
The legs and their packages' totals are already up to date when the job finishes.

The ids are the legs' Dcycle ids: the `entity_id` of each item of the
[Create Logistics Requests (v2)](https://code.dcycle.io/api-reference/logistics/create-requests-v2.md) job, or the `id` in
[List Logistics Requests](https://code.dcycle.io/api-reference/logistics/list-requests.md).

## Request

### Headers

**x-api-key** `string` *required*

Your API key (see [Authentication](https://code.dcycle.io/api-reference/introduction.md#authentication)).

**Example:** `${DCYCLE_API_KEY}`

**x-organization-id** `string` *required*

Your organization UUID. Only this organization's legs can be deleted.

**Example:** `a8315ef3-dd50-43f8-b7ce-d839e68d51fa`

**Idempotency-Key** `string` *required*

1 to 255 characters, one per batch. It is looked up per organization across every v2 bulk route, creates included:
do not reuse the key of the batch that created the legs. Within 24 hours, the same key with the same route and
body returns the original job (with `Idempotent-Replayed: true`) instead of deleting again; the same key with
another body or on another route is `422 IDEMPOTENCY_KEY_REUSED`, and while the first request is still being
processed `409 IDEMPOTENCY_KEY_IN_PROGRESS`. After 24 hours the key is free and a request with it is a new one. See
[The Idempotency-Key](https://code.dcycle.io/api-reference/ingest-jobs/overview.md#the-idempotency-key).

### Query Parameters

**dry\_run** `boolean` (default: false)

Check only: the same `422` for bad ids, nothing deleted, no job; `200` with `{"dry_run": true, "submitted": n,
    "valid": n}` when every id would be deleted. The `Idempotency-Key` header is still required, but a dry run does not check or store it.

### Body Parameters

**ids** `array[uuid]` *required*

Leg ids to delete, 1 to 5,000, each once.

## Response

`202 Accepted`, the job (`operation: delete`) and a `Location` header to it. Per-id outcomes are in
[`GET /v2/ingest-jobs/{id}/items`](https://code.dcycle.io/api-reference/ingest-jobs/list-items): one item per id, in the order sent, with
`stage: delete` and `entity_id` = the leg id.

## Errors

[Problem details](https://code.dcycle.io/api-reference/errors.md). Per-id codes in `errors[].error_code`:

| `error_code` | Cause |
| - | - |
| `NOT_FOUND` | The id does not exist, belongs to another organization or is not active (all answer the same). |
| `DUPLICATE_ID` | The id appears more than once in `ids`. |

The API key and the organization are checked as in
[Create Logistics Requests (v2)](https://code.dcycle.io/api-reference/logistics/create-requests-v2.md): `401`, `400 ORGANIZATION_ID_REQUIRED`
and `403` (`LOGGED_USER_NOT_MEMBER`, `API_KEY_SCOPE_DENIED`, `VIEWER_CANNOT_WRITE`), each in
[Errors](https://code.dcycle.io/api-reference/errors.md#codes). Then `422 REQUEST_VALIDATION_FAILED` for a malformed body (empty `ids`, more
than 5,000, not UUIDs, unknown fields), `422 IDEMPOTENCY_KEY_REUSED` and `409 IDEMPOTENCY_KEY_IN_PROGRESS`.

## Related Endpoints

> [card] [Create Logistics Requests (v2)](https://code.dcycle.io/api-reference/logistics/create-requests-v2.md)
>
> Create up to 5,000 legs in one request

> [card] [Get Ingest Job](https://code.dcycle.io/api-reference/ingest-jobs/get.md)
>
> Follow the deletion


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.