# DELETE /v1/jobs/{id}

> Index: https://kartpunkt.se/llms.txt

operationId: `cancelJob`. Cancel a job.
Tag: `jobs`.

Cancels a job and answers it. A queued job is cancelled at once; a running one stops at its next unit of work, so the answer may still say running. A job that has ended is answered as it is.

## Request

`DELETE https://api.kartpunkt.se/v1/jobs/{id}` with `Authorization: Bearer $KARTPUNKT_API_KEY`, from your backend (never browser code: the key would leak, and CORS is not enabled).

Parameters:
- `id` (path, string, pattern `^job_[a-z0-9]+$`, required): The job's id, from POST /v1/jobs.

## Response 200

Example:

```json
{
  "operation": "route",
  "id": "job_01k7exampleexampleexample0",
  "status": "cancelled",
  "progress": null,
  "created_at": "2026-10-13T07:00:00.000Z",
  "started_at": null,
  "finished_at": "2026-10-13T07:01:00.000Z",
  "expires_at": "2026-10-13T07:02:00.000Z",
  "error": null,
  "result": null
}
```

The shape [Job](https://api.kartpunkt.se/docs/shapes/Job.md).

One of 9 forms, by `operation` ("route", "distances", "matrix", "reach", "trace", "nearest", "optimize", "check_plan", "address_list").

Every form:
- `id` (string): The job's id: read it with GET /v1/jobs/{id}.
- `status` ("queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired"): Where the job is: 'queued' or 'running' until it ends 'succeeded', 'failed' or 'cancelled', then 'expired' once its result is deleted at expires_at.
- `progress` (object | null): How far the running job has come. null until it first reports.
  - `done` (number): Units of work done.
  - `total` (number): Units of work in all.
- `created_at` (string): When the job was submitted, RFC 3339.
- `started_at` (string | null): When it last started running, RFC 3339; null until it has.
- `finished_at` (string | null): When it ended, RFC 3339; null until it has.
- `expires_at` (string | null): When the result is deleted, RFC 3339; null until the job ends. Its sources' policies set how long it is kept (GET /v1/sources).
- `error` (object | null): Why a failed job failed. null in every other status.
  - `code` (string): A code from the error table.
  - `message` (string): That code's message, saying what to do next.

By `operation`:
- `operation`: "route":
  - `result` (object): the 200 answer of [POST /v1/route](https://api.kartpunkt.se/docs/operations/planRoute.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "distances":
  - `result` (object): the 200 answer of [POST /v1/distances](https://api.kartpunkt.se/docs/operations/measureDistances.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "matrix":
  - `result` (object): the 200 answer of [POST /v1/matrix](https://api.kartpunkt.se/docs/operations/buildMatrix.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "reach":
  - `result` (object): the 200 answer of [POST /v1/reach](https://api.kartpunkt.se/docs/operations/measureReach.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "trace":
  - `result` (object): the 200 answer of [POST /v1/trace](https://api.kartpunkt.se/docs/operations/matchTrace.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "nearest":
  - `result` (object): the 200 answer of [POST /v1/nearest](https://api.kartpunkt.se/docs/operations/findNearest.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "optimize":
  - `result` (object): the 200 answer of [POST /v1/optimize](https://api.kartpunkt.se/docs/operations/optimizeRoutes.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "check_plan":
  - `result` (object): the 200 answer of [POST /v1/optimize/check](https://api.kartpunkt.se/docs/operations/checkPlan.md). The operation's answer once the job has succeeded; null in every other status.
- `operation`: "address_list":
  - `result` (object | null): The operation's answer once the job has succeeded; null in every other status.
    - `kind` ("validate" | "geocode" | "reverse"): The kind sent.
    - `rows` (array of object): One row per row sent, in the order sent.
      - `id` (string | null): The id sent with the row; null where none was.
      - `status` ("matched" | "ambiguous" | "unmatched"): 'matched': the row is one address, in address. 'ambiguous': it fits several addresses; send its postnummer or postort. 'unmatched': no address is the row. The recipe Your own address list says when each applies.
      - `address` ([Address](https://api.kartpunkt.se/docs/shapes/Address.md) | null): The address the row is, when status is 'matched'; otherwise null, never a guess or another address.
      - `issues` (array of "street_not_found" | "number_not_found" | "letter_not_found" | "postcode_mismatch" | "locality_mismatch" | "ambiguous"): For validate, what POST /v1/addresses/validate says is wrong with the row (empty when it is valid); for geocode and reverse, always empty.
    - `summary` (object): Your own rows counted by status: how many of them match an address. A count of your list, never of the register.
      - `rows` (integer)
      - `matched` (integer)
      - `ambiguous` (integer)
      - `unmatched` (integer)
    - `provenance` ([Provenance](https://api.kartpunkt.se/docs/shapes/Provenance.md))

## Errors

Every error is `{ error, message, param?, doc_url }`; `message` says what to do next. All codes: [https://api.kartpunkt.se/errors](https://api.kartpunkt.se/errors). What to do on each, with retries: [https://api.kartpunkt.se/docs/recipes/errors-and-retries.md](https://api.kartpunkt.se/docs/recipes/errors-and-retries.md).

- [`invalid_request`](https://api.kartpunkt.se/errors/invalid_request) (400): The request does not match the API schema. Fix the fields named in this message; see /openapi.json.
- [`unauthorized`](https://api.kartpunkt.se/errors/unauthorized) (401): Missing or unknown API key. Send it as 'Authorization: Bearer <key>' (or 'x-api-key'), read from the KARTPUNKT_API_KEY environment variable. The user creates a kp_test_ key on their Kartpunkt account page (https://kartpunkt.se/konto) and puts it in KARTPUNKT_API_KEY themselves; never ask them to paste a key into chat.
- [`live_access_required`](https://api.kartpunkt.se/errors/live_access_required) (403): This account is not approved for live data: kp_live_ keys are for customers under contract. Use a kp_test_ key. To ask for live access, the account holder writes to hej@kartpunkt.se, or orders a plan at https://kartpunkt.se/konto#plan.
- [`job_not_found`](https://api.kartpunkt.se/errors/job_not_found) (404): No job with that id for this account, or its result has expired. Results are kept for the time GET /v1/sources gives each source; submit the job again.
- [`quota_exceeded`](https://api.kartpunkt.se/errors/quota_exceeded) (429): Request limit or plan quota reached (per minute, per day, or the account plan's monthly quota). Wait the number of seconds in the Retry-After header, then retry; without Retry-After, no wait helps: tell the account holder what this message says.
- [`internal_error`](https://api.kartpunkt.se/errors/internal_error) (500): Something failed on our side. Retry after a few seconds; if it keeps failing, contact hej@kartpunkt.se.
- [`live_data_unavailable`](https://api.kartpunkt.se/errors/live_data_unavailable) (503): Live data is not available yet: it opens when Kartpunkt's import of Lantmäteriet's address register completes. Use a kp_test_ key until then.

## Limits

none

## Metering

A request only: no calculations, no live call, no address limit.
