---
title: "Cancel a job"
method: POST
path: "/api/v1/jobs/{id}/cancel"
tags: ["Job Management"]
---

# Cancel a job

`POST /api/v1/jobs/{id}/cancel`

## Request

- Base URL: `https://api.imagestep.dev`
- URL: `https://api.imagestep.dev/api/v1/jobs/{id}/cancel`
- Auth: API key in header `Authorization`

Stops a `PENDING` or `PROCESSING` job. Items not yet handed to a provider or a worker are cancelled
and never charged; items already running finish, and are charged for what they complete — nothing
is taken at submit, so there is nothing to refund. The answer is the job: `CANCELLED` when nothing
was in flight, else `CANCELLING` until the running items settle, and then `CANCELLED`. A `chain`
item lets the segment in flight finish and starts no further one.

The job settles as `CANCELLED` and a `job.failed` event goes out. What it did make is kept; a
resume retries the cancelled items.

USE THIS WHEN:
- Stopping a running or queued job you no longer want

DO NOT USE WHEN:
- The job is already terminal (`COMPLETED`, `FAILED`, `CANCELLED`) or `CANCELLING` → `400 invalid_state`

## Path parameters

- `id` string, required

## Headers

- `Idempotency-Key` string

## Response `200`

The job — `CANCELLING` or `CANCELLED`

## Other responses

- `400`: `invalid_state` — there is nothing left to cancel: the job is already terminal or `CANCELLING`; `details.status` says which
- `404`: `job_not_found` — no such job, or it is not yours
- `409`: Conflict — `error.code` is `idempotency_key_reuse` (the key already means a different request) or `request_in_progress` (the first request under this key has not settled yet; retryable).
- `429`: Rate limited — `error.code` is `rate_limited` and `retryable` is true. `Retry-After` says how many seconds to wait.

---

[API](https://skmtc.dev/imagestep/apis/imagestep-api.md) · [All operations](https://skmtc.dev/imagestep/apis/imagestep-api/llms.txt) · [OpenAPI document](https://skmtc.dev/imagestep/apis/imagestep-api/revisions/5e8e922a3085?raw)
