curl --request DELETE \
--url https://ndi-api.nace.ai/v1/jobs/{job_id} \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}delete_job
Hide a job from listings, keeping it for billing. Cost class: fast.
A soft delete. The row survives, so units keep answering and
GET /v1/usage still counts the work; what stops is GET /v1/jobs
returning it. Reading it by id still works, with deleted_at set — the
same reasoning as an expired payload, where a 404 would conflate “gone” with
“never existed”.
A job still queued or running is cancelled first, so hitting delete stops the compute rather than paying for a run nobody will ever see. A job that finished under us is simply hidden: there was nothing left to stop, and refusing the delete over a race the caller cannot see would be noise.
Temporal is not declared as a dependency here because asking for the
client connects: most deletes are of finished runs and need it for nothing,
so an outage must not fail work that is entirely in Postgres.
There is no project-level route to pair with ?project_id=: a run’s
fan-out is one job per file, and the console deletes the group the same way
it renames it — per job, over the ids it already holds.
curl --request DELETE \
--url https://ndi-api.nace.ai/v1/jobs/{job_id} \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}