Een aanvraag opbouwen

Bijgewerkt op 7 oktober 2026 · Gepubliceerd op 7 oktober 2026

De aanvraag

GET https://app.apiboard.nl/api/v1/<koppeling>/<tabel>
Authorization: Bearer apib_live_JOUW_SLEUTEL

<koppeling> en <tabel> zijn de namen uit de referentie per koppeling, bijvoorbeeld /api/v1/wefact/facturen. Een onbekende combinatie geeft 404 unknown_table.

Parameters

ParameterBetekenis
connectionBeperk het antwoord tot één administratie. Gebruik het id uit connections in een eerder antwoord. Zonder deze parameter krijg je de rijen van alle administraties van die koppeling.
limitAantal rijen per pagina, een geheel getal van 1 tot en met 1000. Standaard 100.
cursorDe waarde van next_cursor uit het vorige antwoord, zie Paginering.
modified_sinceAlleen rijen die sinds dit tijdstip zijn bijgewerkt, zie Incrementeel ophalen. Alleen op tabellen die dit ondersteunen.
include_deletedtrue of false. Neemt rijen mee die bij de bron zijn verwijderd. Alleen op tabellen met de kolom bron_verwijderd_op.

Een van deze parameters mag maar één keer voorkomen. Staat er in je aanvraag iets anders dan deze parameters, dan leest de API het als een filter op een kolom. Bestaat die kolom niet, dan krijg je een 400; de API negeert nooit stilzwijgend iets.

Filteren op kolommen

Elke kolom van de tabel kun je als filter gebruiken. Je kunt filters combineren (alle filters moeten kloppen), tot maximaal 10 per aanvraag.

  • ?status=4 is een gelijkheidsfilter (bij WeFact is 4 de statuscode voor Betaald; de codes per kolom staan in de referentie).
  • ?kolom[operator]=waarde kiest een andere operator: eq, ne, gt, gte, lt, lte of in.
  • gt, gte, lt en lte werken alleen op kolommen van het type numeriek, geheel getal, datum of tijdstip.
  • in neemt 1 tot en met 50 waarden gescheiden door komma’s, bijvoorbeeld ?status[in]=2,3. Staat er een komma in de waarde zelf, schrijf dan \,.
  • Dezelfde combinatie van kolom en operator mag maar één keer voorkomen.

Een onbekende kolom, een operator die niet bij het kolomtype past of een waarde die niet bij de kolom past geeft 400 invalid_filter.

Voorbeeld met een filter op meerdere waarden:

GET https://app.apiboard.nl/api/v1/wefact/facturen?status%5Bin%5D=2%2C3&limit=100 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/wefact/facturen?status%5Bin%5D=2%2C3&limit=100"
import requests

TOKEN = "apib_live_JOUW_SLEUTEL"
URL = "https://app.apiboard.nl/api/v1/wefact/facturen"

resp = requests.get(URL, params={"status[in]": "2,3", "limit": 100}, headers={"Authorization": f"Bearer {TOKEN}"})
resp.raise_for_status()
body = resp.json()

for rij in body["data"]:
    print(rij)
print("Volgende pagina:", body["next_cursor"])
let
    Basis = "https://app.apiboard.nl",
    Pad = "/api/v1/wefact/facturen",
    Token = "apib_live_JOUW_SLEUTEL",
    Filters = [#"status[in]" = "2,3", limit = "100"],

    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

Het antwoord

Rechts staat een voorbeeld van een aanvraag met bijbehorend antwoord. Het antwoord heeft deze vorm:

Velden in het antwoord

connections
De gekoppelde accounts waar dit antwoord over gaat. Elk account heeft een id, een label en backfill_complete: true betekent dat de eerste volledige synchronisatie klaar is, false dat de data nog onvolledig is.
data
De rijen. Elke rij heeft connection_id en connection_label: uit welk account de rij komt.
next_cursor
Waarmee je de volgende pagina ophaalt. null betekent dat je bij de laatste pagina bent.
sync_watermark
Tot dit tijdstip is de data compleet. Gebruik het als startpunt (modified_since) voor de volgende incrementele ophaalronde.

Elk antwoord bevat ook de headers X-RateLimit-Remaining en X-RateLimit-Remaining-Day, zie Gebruikslimieten.

Heeft een koppeling kind-tabellen (bijvoorbeeld factuurregels onder facturen), dan staat op de referentiepagina van die tabel via welke kolom je ze aan de bovenliggende tabel koppelt.

Onze tip: rijen kunnen tijdens het ophalen van pagina’s wijzigen en daardoor twee keer voorkomen. Dedupliceer in je eigen verwerking op id en houd de versie met de nieuwste synced_at.

Aanvraag

GET https://app.apiboard.nl/api/v1/wefact/facturen?limit=100&status=4 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/wefact/facturen?limit=100&status=4"
import requests

TOKEN = "apib_live_JOUW_SLEUTEL"
URL = "https://app.apiboard.nl/api/v1/wefact/facturen"

resp = requests.get(URL, params={"limit": 100, "status": 4}, headers={"Authorization": f"Bearer {TOKEN}"})
resp.raise_for_status()
body = resp.json()

for rij in body["data"]:
    print(rij)
print("Volgende pagina:", body["next_cursor"])
let
    Basis = "https://app.apiboard.nl",
    Pad = "/api/v1/wefact/facturen",
    Token = "apib_live_JOUW_SLEUTEL",
    Filters = [limit = "100", status = "4"],

    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

{
  "connections": [
    {
      "id": "43d9a41a-3529-4be2-b891-b23781997895",
      "label": "Voorbeeld B.V.",
      "backfill_complete": true
    }
  ],
  "data": [
    {
      "connection_id": "43d9a41a-3529-4be2-b891-b23781997895",
      "connection_label": "Voorbeeld B.V.",
      "id": "314feb6e-f809-4f72-b6d8-da1b68d15ab5",
      "synced_at": "2026-10-07T02:58:12.304211+00:00"
    }
  ],
  "next_cursor": null,
  "sync_watermark": "2026-10-07T03:00:00.000000Z"
}

Was dit artikel behulpzaam?