Spring til indhold

Job: lange lister i baggrunden

Send en hel kundeliste, en fil med koordinater eller tusindvis af BFE-numre som ét job. Grundfast slår hver række op i baggrunden, og du henter resultatet og fejlene som to filer.

Et job er til lister, der er for lange til et batch-kald. Hver række slås op med de samme opslag som enkeltkaldene, og svaret lægges ved siden af dine egne kolonner. Du kan også uploade en fil uden at skrive kode fra dashboardet.

Hvad et job kan

kindHver rækkeKolonner, jobbet læser
datavaskFritekstadresse → DAR-adgangsadresse med kategori A/B/C og scoreadresse, eller vej + husnr med postnr og/eller by
reversePunkt → nærmeste adgangsadresse inden for 200 mx + y
bbrBBR-overblik for ejendommen: arealer, opførelsesår, anvendelse, materialer, varmebfe, adgangsadresse_id eller en adresse
dagiRegion, kommune, sogn, retskreds, politikreds og opstillingskredsx + y, adgangsadresse_id eller en adresse
miljoeMiljøscreeningens niveau pr. stof, grund, olietanke og affaldsmængdebfe, adgangsadresse_id eller en adresse

Har en række flere af kolonnerne, bruges den mest præcise: et BFE-nummer før et adresse-id før en adresse, der skal vaskes. En adresse, der kun kan vaskes med kategori C, bruges aldrig til at slå en ejendom op — rækken havner i fejlfilen, så ingen får data om en forkert ejendom.

Send listen

Listen kan sendes på tre måder til POST /v1/jobs. Én upload må fylde 10 MB.

curl "https://api.grundfast.dk/v1/jobs?kind=datavask&label=Kunder" \
  -H "Authorization: Bearer gf_live_..." \
  -H "Content-Type: text/csv" \
  --data-binary @kunder.csv
  • CSV med komma, semikolon eller tabulator virker; skilletegnet læses af overskriftslinjen. Et UTF-8-BOM fra Excel ignoreres.
  • NDJSON er ét JSON-objekt pr. linje. En fil i multipart kan også være et JSON-array af objekter.
  • Hver række må have op til 100 kolonner. Alle dine kolonner kommer med tilbage i resultatet.

En liste over uploadgrænsen

  1. Opret en kladde

    POST /v1/jobs med start: false (eller ?start=false). Kladden behandles ikke.

  2. Tilføj rækker

    POST /v1/jobs/:id/rows så mange gange, det skal være. Rækkerne nummereres i den rækkefølge, de kommer.

  3. Start

    POST /v1/jobs/:id/start. En kladde, der ikke er startet efter et døgn, stoppes.

Kolonner og koordinater

Uden columns genkendes rollerne på kolonnenavnene, fx Adresse, Vejnavn, Hus nr., Postnummer, By, lon/lat, x/y, BFE-nr og adgangsadresse_id. Store og små bogstaver, mellemrum og tegnsætning er ligegyldige, men navnet skal passe helt: kundenr bliver ikke til et husnummer. Svaret viser i job.columns, hvad der blev valgt.

columns
{ "vej": "Gade", "husnr": "Nr", "postnr": "Postnr", "by": "By" }

Koordinater kan være WGS84 (lon/lat) eller UTM32 i meter (EPSG:25832). Systemet genkendes på værdierne — alt over 180 er meter — eller du sætter srid til 4326 eller 25832. Decimalkomma som i 55,6761 er i orden.

Fremdrift, pause og stop

Spørg GET /v1/jobs/:id med få sekunders mellemrum. processedRows og progress vokser, efterhånden som bidder af listen bliver færdige. Status går fra queued til running og ender i completed — eller failed, hvis ikke en eneste række lykkedes.

  • Pause lader bidden, der er i gang, blive færdig og stopper derefter. Genoptag fortsætter fra samme række.
  • Stop afslutter jobbet. Det, der allerede er gjort, kan stadig hentes; resten behandles aldrig og koster intet.
  • Du kan have 5 åbne job ad gangen (kladder, i kø, kørende og på pause).
  • Vil du ikke spørge, så abonnér på webhook-hændelsen job.completed, der sendes, når den sidste række er behandlet. Se Webhooks.

Tempo

Job behandles i baggrunden i små bidder, på skift mellem kunderne, så ingen liste fylder databasen og kilderne for andre. Adresser med vej, husnummer og postnummer slås op direkte og går hurtigt; adresser, der skal vaskes som fritekst, tager op mod et sekund pr. række. En liste på 10.000 frie adresser kan derfor tage et par timer. Opslag i BBR, DAGI og miljøscreening går gennem de samme kilder som enkeltkaldene og følger deres tempo. Er en kilde nede, venter jobbet og prøver igen i stedet for at fylde fejlfilen.

Resultat- og fejlfilen

Resultatfilen har rækkerne med et svar, fejlfilen dem uden. Begge kan hentes, mens jobbet kører, og indeholder så det, der er færdigt.

  • CSV: dine kolonner først, præcis som du sendte dem, og vores til højre med præfikset gf_. Filen starter med et UTF-8-BOM, og ?separator=semicolon giver en fil, en dansk Excel åbner direkte.
  • NDJSON (?format=ndjson): { "raekke", "input", "resultat" } pr. linje i resultatfilen og { "raekke", "input", "fejl", "status" } i fejlfilen. raekke er rækkens nummer i din liste, fra 1.
  • status i fejlfilen er den HTTP-status, enkeltkaldet ville have givet: 404 for en adresse uden match, 422 for et for usikkert adressematch, 400 for en række uden de kolonner, jobbet læser.
kindKolonner i resultatet
datavaskkategori, score, antal_kandidater, adgangsadresse_id, betegnelse, vejnavn, husnr, postnr, postnrnavn, kommunekode, bfe_nummer, lon, lat
reverseafstand_m, adgangsadresse_id, betegnelse, vejnavn, husnr, postnr, postnrnavn, kommunekode, bfe_nummer, lon, lat
bbradresse_kategori, adgangsadresse_id, betegnelse, bfe_nummer, kommunekode, matrikelnummer, ejerlav_kode, ejerlav_navn, antal_bygninger, samlet_bygningsareal_m2, samlet_boligareal_m2, samlet_erhvervsareal_m2, hovedbygning_anvendelse_kode, hovedbygning_anvendelse, opfoerelsesaar, om_tilbygningsaar, antal_etager, ydervaeg, tag, varmeinstallation, opvarmningsmiddel, asbest_registrering
dagiadresse_kategori, adgangsadresse_id, betegnelse, lon, lat, region_kode, region_navn, kommune_kode, kommune_navn, sogn_kode, sogn_navn, retskreds_kode, retskreds_navn, politikreds_kode, politikreds_navn, opstillingskreds_kode, opstillingskreds_navn
miljoeadresse_kategori, adgangsadresse_id, betegnelse, bfe_nummer, antal_bygninger, asbest, pcb, bly, pah, klorerede_paraffiner, tungmetaller, grund_niveau, jordforurening, olietanke, affald_ton, over_affaldsgraensen, mangler

Resultatet er et kompakt udtræk pr. række, så en liste på en million rækker ikke bliver en million fulde objekter. Har du brug for hele BBR-objektet eller hele screeningen, så slå de ejendomme, du er interesseret i, op med enkeltkaldet.

Pris og grænser

  • Én enhed pr. række, der lykkes — samme pris som enkeltkaldet. Rækker i fejlfilen koster intet.
  • Uploaden tælles mod månedskvoten, så Free-planens loft også gælder for et job. Rækker, der ender i fejlfilen, og rækker i et stoppet job gives tilbage.
  • 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. En længere liste afvises med 402 og tæller ikke.
  • Rækker og svar slettes 30 dage efter, at jobbet er færdigt eller stoppet. Jobbet står stadig på listen med resultsAvailable: false.

Med SDK’et

job.ts
import { readFile } from 'node:fs/promises';
import { GrundfastClient } from '@grundfast/sdk';

const gf = new GrundfastClient({ apiKey: process.env.GRUNDFAST_API_KEY });

const csv = await readFile('kunder.csv', 'utf8');
const job = await gf.createJobFromCsv('datavask', csv, { label: 'Kunder' });

const faerdig = await gf.waitForJob(job.id, {
  onProgress: (j) => console.log(Math.round(j.progress * 100), '%'),
});
console.log(faerdig.succeeded, 'fundet,', faerdig.failed, 'i fejlfilen');

const resultat = await gf.downloadJobResults(job.id, { separator: 'semicolon' });
const fejl = await gf.downloadJobErrors(job.id, { format: 'ndjson' });