# Opret et job

`POST /v1/jobs` · Job

Send en lang liste — adresser, punkter eller BFE-numre — og få den behandlet i baggrunden række for række.

Et job tager en liste, der er for lang til et batch-kald, og slår hver række op med de samme opslag, som enkeltkaldene bruger. `kind` vælger opslaget: `datavask` (fritekst til adresse med kategori og score), `reverse` (punkt til nærmeste adresse), `bbr`, `dagi` eller `miljoe` (pr. BFE, adgangsadresse-id eller adresse).

Listen kan sendes som JSON `{ kind, rows }`, som en fil i `multipart/form-data` (CSV, NDJSON eller et JSON-array) eller som en rå `text/csv`- eller `application/x-ndjson`-body med felterne som query-parametre. En upload må fylde 10 MB; en længere liste sender du i dele: opret jobbet med `start: false`, tilføj rækker med [Tilføj rækker](https://grundfast.dk/docs/api/jobs-rows), og start det.

Uden `columns` genkendes rollerne på kolonnenavnene (fx `Adresse`, `Vejnavn` + `Husnr` + `Postnr`, `lon`/`lat` eller `x`/`y`, `BFE`). Koordinatsystemet genkendes på værdierne, medmindre du sender `srid`. Kan kolonnerne ikke føde den valgte `kind`, afvises jobbet med `400`, før en eneste række gemmes.

Rækker pr. job følger planen: 250 på Free, 10.000 på Starter, 100.000 på Pro, 500.000 på Scale og 1.000.000 på Enterprise. Du kan have 5 åbne job ad gangen. Læs [guiden om job](https://grundfast.dk/docs/jobs) for tempo, filer og fakturering.

**Godkendelse:** API-nøgle eller dashboard-session

**Afregning:** Én enhed pr. række, der lykkes. Uploaden tælles mod kvoten, og rækker, der ender i fejlfilen, gives tilbage.

## Parametre

| Navn | Placering | Type | Påkrævet | Beskrivelse |
| --- | --- | --- | --- | --- |
| `kind` | body | string | ja | Opslaget, hver række får. |
| `rows` | body | object[] | nej | Dine rækker som objekter med højst 100 kolonner. Alle kolonner kommer med tilbage ved siden af svaret. Må være tom sammen med `start: false`. |
| `columns` | body | object | nej | Rolle → kolonnenavn: `adresse`, `vej`, `husnr`, `postnr`, `by`, `x`, `y`, `bfe`, `adgangsadresse_id`. Udelades den, genkendes rollerne på navnene. |
| `srid` | body | integer | nej | Koordinatsystemet for `x`/`y`: `4326` (lon/lat) eller `25832` (UTM32 i meter). |
| `label` | body | string | nej | Dit eget navn til jobbet, højst 120 tegn. |
| `start` | body | boolean | nej | `false` opretter en kladde, der fyldes og startes senere. |

## Request-body

```json
{
  "kind": "datavask",
  "label": "Kundeliste oktober",
  "rows": [
    { "kunde": "1001", "adresse": "Rådhuspladsen 1, 1550 København V" },
    { "kunde": "1002", "adresse": "Store Torv 1, 8000 Aarhus C" }
  ]
}
```

## Eksempel

```bash
curl -X POST "https://api.grundfast.dk/v1/jobs" \
  -H "Authorization: Bearer $GRUNDFAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"datavask","label":"Kundeliste oktober","rows":[{"kunde":"1001","adresse":"Rådhuspladsen 1, 1550 København V"},{"kunde":"1002","adresse":"Store Torv 1, 8000 Aarhus C"}]}'
```

## Svar (201)

```json
{
  "job": {
    "id": "job_4n8q2v7k1m9x3c5z0w6r2t8b",
    "kind": "datavask",
    "status": "queued",
    "label": "Kundeliste oktober",
    "totalRows": 2,
    "processedRows": 0,
    "succeeded": 0,
    "failed": 0,
    "billedUnits": 0,
    "progress": 0,
    "columns": { "adresse": "adresse" },
    "srid": 4326,
    "inputColumns": ["kunde", "adresse"],
    "error": null,
    "createdAt": "2026-10-05T09:12:03.418Z",
    "startedAt": null,
    "completedAt": null,
    "updatedAt": "2026-10-05T09:12:05.117Z",
    "resultsAvailable": true
  }
}
```

## Vigtige felter

| Felt | Type | Betydning |
| --- | --- | --- |
| `job.id` | string | Jobbets id, fx `job_…`. |
| `job.status` | string | `draft`, `queued`, `running`, `paused`, `completed`, `failed` eller `cancelled`. `failed` betyder, at jobbet blev færdigt uden en eneste række, der lykkedes. |
| `job.progress` | number | `processedRows / totalRows` mellem 0 og 1 — andelen af rækker, der har et svar eller en fejl. |
| `job.succeeded` | integer | Rækker med et svar. Kun dem faktureres (`billedUnits`). |
| `job.columns` | object | Hvilke af dine kolonner jobbet læser, som rolle → kolonnenavn — angivet af dig eller genkendt ud fra navnene. |
| `job.resultsAvailable` | boolean | `false`, når rækkerne er slettet efter opbevaringsperioden. |

## Fejl

| Status | Betydning |
| --- | --- |
| 400 | Body’en kan ikke læses, `kind` er ukendt, en række er ugyldig, eller kolonnerne kan ikke føde den valgte `kind`. Beskeden siger hvorfor. |
| 401 | Hverken en gyldig nøgle eller en session. |
| 403 | Nøglen er en admin-nøgle, eller kontoen er suspenderet. |
| 409 | Du har allerede 5 åbne job. |
| 413 | Uploaden er over 10 MB. Send listen i dele. |
| 429 | Burst-grænsen eller månedskvoten er nået — kvoten tjekkes mod alle rækker i uploaden. |

> Er listen længere, end din plan tager pr. job, svarer kaldet `402` med grænsen og tæller ikke mod kvoten.
