Eigen tabellen ophalen

Bijgewerkt op 7 oktober 2026 · Gepubliceerd op 7 oktober 2026

De aanvraag

Een eigen tabel heeft een API-naam. Die gebruik je in het pad:

GET https://app.apiboard.nl/api/v1/datawerkbank/<naam>
Authorization: Bearer apib_live_JOUW_SLEUTEL

Een naam die niet bestaat, of een tabel die nog niet voor het eerst is berekend, geeft 404 unknown_table. De API toont alleen tabellen van je eigen organisatie.

Parameters

Op eigen tabellen werken alleen deze parameters:

ParameterBetekenis
limitAantal rijen per pagina, 1 tot en met 1000, standaard 100.
cursorDe waarde van next_cursor uit het vorige antwoord.
modified_sinceEen tijdstip in ISO 8601, zie hieronder.

Alle andere parameters geven 400 unknown_parameter. Filteren op kolommen, connection en include_deleted bestaan hier dus niet. Filter en combineer in de Datawerkbank zelf, voordat je de tabel ophaalt.

Het antwoord

Rechts staat een voorbeeld van een aanvraag met bijbehorend antwoord. De velden:

  • table.naam: de API-naam van de tabel.
  • table.status: actueel, verouderd, bezig of fout, de berekeningsstatus in de Datawerkbank.
  • table.laatst_berekend_op: wanneer de tabel voor het laatst is berekend.
  • table.volledig: true als data de volledige inhoud geeft die bij je aanvraag hoort. Bij false is er niets veranderd sinds je modified_since, en is data bewust leeg.
  • next_cursor en sync_watermark werken zoals bij Paginering: sync_watermark staat alleen op de laatste pagina.

Incrementeel ophalen werkt hier anders

Een eigen tabel wordt als geheel berekend. Daarom is modified_since alles of niets: is de tabel sinds dat tijdstip niet opnieuw berekend, dan krijg je geen rijen en volledig: false. Is hij wel opnieuw berekend, dan krijg je de hele tabel, niet alleen de gewijzigde rijen. Vervang in dat geval je eigen kopie volledig.

  1. Haal de tabel op en bewaar sync_watermark van de laatste pagina.
  2. Vraag de volgende keer aan met ?modified_since=<sync_watermark>.
  3. Zegt het antwoord volledig: false, dan is er niets veranderd. Anders vervang je je kopie.
GET https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant?modified_since=2026-10-07T03%3A00%3A00.000000Z HTTP/1.1
Host: app.apiboard.nl
Authorization: Bearer apib_live_JOUW_SLEUTEL
curl -H "Authorization: Bearer apib_live_JOUW_SLEUTEL" \
  "https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant?modified_since=2026-10-07T03%3A00%3A00.000000Z"
import json
import os
import requests

TOKEN = "apib_live_JOUW_SLEUTEL"
URL = "https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant"
STAAT_BESTAND = "datawerkbank_omzet_per_klant_staat.json"  # bewaart de kopie + watermark tussen runs

staat = {"watermark": None, "rijen": []}
if os.path.exists(STAAT_BESTAND):
    with open(STAAT_BESTAND) as f:
        staat = json.load(f)

params = {}
if staat["watermark"]:
    params["modified_since"] = staat["watermark"]

rijen = []
while True:
    resp = requests.get(URL, params=params, headers={"Authorization": f"Bearer {TOKEN}"})
    resp.raise_for_status()
    body = resp.json()
    if body["table"]["status"] != "actueel":
        print(f"Let op: de tabel heeft status {body['table']['status']}.")
    rijen += body["data"]
    if body["next_cursor"] is None:
        watermark = body["sync_watermark"]
        volledig = body["table"]["volledig"]
        break
    params["cursor"] = body["next_cursor"]

if volledig:
    staat["rijen"] = rijen  # tabel opnieuw berekend: kopie volledig vervangen
    staat["watermark"] = watermark
    with open(STAAT_BESTAND, "w") as f:
        json.dump(staat, f)
    print(f"{len(rijen)} rijen vervangen.")
else:
    print("Niets veranderd sinds de vorige run.")

Opnieuw berekende tabel tijdens het ophalen

Wordt de tabel opnieuw berekend terwijl je pagina’s ophaalt, dan krijg je bij een oude cursor 409 table_recomputed. Begin dan opnieuw zonder cursor. Een cursor is 24 uur geldig en hoort bij één tabel.

Onze tip: controleer table.status voordat je de data gebruikt. Bij bezig of fout is de berekening nog niet klaar of mislukt, en kijk je beter eerst in de Datawerkbank.

Aanvraag

GET https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant HTTP/1.1
Host: app.apiboard.nl
Authorization: Bearer apib_live_JOUW_SLEUTEL
curl -H "Authorization: Bearer apib_live_JOUW_SLEUTEL" \
  "https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant"
import json
import os
import requests

TOKEN = "apib_live_JOUW_SLEUTEL"
URL = "https://app.apiboard.nl/api/v1/datawerkbank/omzet_per_klant"
STAAT_BESTAND = "datawerkbank_omzet_per_klant_staat.json"  # bewaart de kopie + watermark tussen runs

staat = {"watermark": None, "rijen": []}
if os.path.exists(STAAT_BESTAND):
    with open(STAAT_BESTAND) as f:
        staat = json.load(f)

params = {}
if staat["watermark"]:
    params["modified_since"] = staat["watermark"]

rijen = []
while True:
    resp = requests.get(URL, params=params, headers={"Authorization": f"Bearer {TOKEN}"})
    resp.raise_for_status()
    body = resp.json()
    if body["table"]["status"] != "actueel":
        print(f"Let op: de tabel heeft status {body['table']['status']}.")
    rijen += body["data"]
    if body["next_cursor"] is None:
        watermark = body["sync_watermark"]
        volledig = body["table"]["volledig"]
        break
    params["cursor"] = body["next_cursor"]

if volledig:
    staat["rijen"] = rijen  # tabel opnieuw berekend: kopie volledig vervangen
    staat["watermark"] = watermark
    with open(STAAT_BESTAND, "w") as f:
        json.dump(staat, f)
    print(f"{len(rijen)} rijen vervangen.")
else:
    print("Niets veranderd sinds de vorige run.")
let
    Basis = "https://app.apiboard.nl",
    Pad = "/api/v1/datawerkbank/omzet_per_klant",
    Token = "apib_live_JOUW_SLEUTEL",
    Filters = [],

    HaalPaginaOp = (cursor as nullable text) =>
        Json.Document(Web.Contents(Basis, [
            RelativePath = Pad,
            Query = if cursor = null then Filters else Record.AddField(Filters, "cursor", cursor),
            Headers = [Authorization = "Bearer " & Token]
        ])),

    // Volg next_cursor tot die null is; de pagina met next_cursor = null telt ook mee.
    Paginas = List.Generate(
        () => HaalPaginaOp(null),
        each _ <> null,
        each if [next_cursor] = null then null else HaalPaginaOp([next_cursor]),
        each [data]
    ),

    AlleRijen = List.Combine(Paginas),
    Tabel = if List.IsEmpty(AlleRijen)
        then #table({"id", "synced_at"}, {})
        else Table.FromRecords(AlleRijen, null, MissingField.UseNull),
    // Dedupliceer op id: eerst de nieuwste versie bovenaan, dan houdt Distinct die.
    // Verwijder daarna rijen die bij de bron verwijderd zijn.
    NieuwsteEerst = Table.Buffer(Table.Sort(Tabel, {{"synced_at", Order.Descending}})),
    ZonderDubbel = Table.Distinct(NieuwsteEerst, {"id"}),
    ZonderVerwijderd = Table.SelectRows(ZonderDubbel, each Record.FieldOrDefault(_, "bron_verwijderd_op", null) = null)
in
    ZonderVerwijderd

Antwoord

{
  "table": {
    "naam": "omzet_per_klant",
    "status": "actueel",
    "volledig": true,
    "laatst_berekend_op": "2026-10-07T03:00:00.000000Z"
  },
  "data": [
    {
      "…": "…"
    }
  ],
  "next_cursor": null,
  "sync_watermark": "2026-10-07T03:00:00.000000Z"
}

Was dit artikel behulpzaam?