curl -X POST "https://api.dcycle.io/v2/wastes/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"]}'
import os
import uuid
import requests
response = requests.post(
"https://api.dcycle.io/v2/wastes/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"])
const axios = require('axios');
const { randomUUID } = require('crypto');
const { data: job } = await axios.post(
'https://api.dcycle.io/v2/wastes/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);
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "processing",
"entity_type": "wastes",
"operation": "delete",
"source": "api_bulk",
"counts": { "submitted": 2, "succeeded": 0, "failed": 0 },
"chunks_total": 1,
"chunks_done": 0,
"created_at": "2026-10-05T11: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"
}
}
{
"type": "https://code.dcycle.io/api-reference/errors#BULK_RECORDS_REJECTED",
"title": "Unprocessable Content",
"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"
}
{ "dry_run": true, "submitted": 2, "valid": 2 }
Delete Wastes (v2)
Delete up to 5,000 wastes by id, asynchronously, as an ingest job
POST
/
v2
/
wastes
/
delete
curl -X POST "https://api.dcycle.io/v2/wastes/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"]}'
import os
import uuid
import requests
response = requests.post(
"https://api.dcycle.io/v2/wastes/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"])
const axios = require('axios');
const { randomUUID } = require('crypto');
const { data: job } = await axios.post(
'https://api.dcycle.io/v2/wastes/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);
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "processing",
"entity_type": "wastes",
"operation": "delete",
"source": "api_bulk",
"counts": { "submitted": 2, "succeeded": 0, "failed": 0 },
"chunks_total": 1,
"chunks_done": 0,
"created_at": "2026-10-05T11: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"
}
}
{
"type": "https://code.dcycle.io/api-reference/errors#BULK_RECORDS_REJECTED",
"title": "Unprocessable Content",
"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"
}
{ "dry_run": true, "submitted": 2, "valid": 2 }
← Wastes API
Delete wastes by id. The request checks every id and answers
202 Accepted with a job; 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} or the ingest_job.finished webhook.
Permanent. Deleted wastes and their emissions cannot be recovered. Use
dry_run=true first if you are not sure.Beta. Part of the bulk ingest API, currently in beta. The contract may still change before general availability.
curl -X POST "https://api.dcycle.io/v2/wastes/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"]}'
import os
import uuid
import requests
response = requests.post(
"https://api.dcycle.io/v2/wastes/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"])
const axios = require('axios');
const { randomUUID } = require('crypto');
const { data: job } = await axios.post(
'https://api.dcycle.io/v2/wastes/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);
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "processing",
"entity_type": "wastes",
"operation": "delete",
"source": "api_bulk",
"counts": { "submitted": 2, "succeeded": 0, "failed": 0 },
"chunks_total": 1,
"chunks_done": 0,
"created_at": "2026-10-05T11: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"
}
}
{
"type": "https://code.dcycle.io/api-reference/errors#BULK_RECORDS_REJECTED",
"title": "Unprocessable Content",
"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"
}
{ "dry_run": true, "submitted": 2, "valid": 2 }
How it works
- The request checks every id. One that does not exist, is outside your organization’s perimeter (your
organization and its accepted subsidiaries) or is repeated rejects the whole request with
422and nothing is deleted. - The job deletes in the background, 500 ids per chunk, together with each waste’s emissions and calculation
data. A waste that someone else deleted in the meantime ends
failedwithDELETE_FAILED; the others go on. - When every chunk is done the job is
completed(orcompleted_with_errors), andingest_job.finishedis sent to your webhook endpoints with"operation": "delete".
Request
Headers
string
required
Your API key for authenticationExample:
sk_live_1234567890abcdefstring
required
Your organization UUIDExample:
a8315ef3-dd50-43f8-b7ce-d839e68d51fastring
required
1 to 255 characters, unique per batch. A retry with the same key and body returns the original job instead of
deleting again; the same key with another body is
422 IDEMPOTENCY_KEY_REUSED.Query Parameters
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.Body Parameters
array[uuid]
required
Waste 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: one item per id, in the order sent, with
stage: delete and entity_id = the waste id.
Errors
Problem details. Per-id codes inerrors[].error_code:
error_code | Cause |
|---|---|
NOT_FOUND | The id does not exist or is outside your organization’s perimeter (both answer the same). |
DUPLICATE_ID | The id appears more than once in ids. |
401 for a missing or invalid API key, 403 LOGGED_USER_NOT_MEMBER when the key’s user is not a member of the
organization, 422 REQUEST_VALIDATION_FAILED for a malformed body (empty ids, more than 5,000, not UUIDs).
Related Endpoints
Create Wastes (v2)
Create up to 5,000 wastes in one request
Get Ingest Job
Follow the deletion
Was this page helpful?