GET
/api/v1/zenvoices/facturen Opmerkingen
-
Authenticeer met je API-sleutel in de header
Authorization: Bearer apib_live_JOUW_SLEUTEL. - Het antwoord is gepagineerd: herhaal de aanvraag met
?cursor=<next_cursor>totnext_cursornullis. - Deze tabel ondersteunt incrementeel ophalen met
modified_since. - Rijen die bij de bron zijn verwijderd blijven bestaan met een gevulde
bron_verwijderd_op. Standaard worden ze niet getoond, metinclude_deleted=truewel.
Queryparameters
| Parameter | Omschrijving |
|---|---|
connection | Beperk tot één gekoppeld account (UUID uit connections). |
limit | Aantal rijen per pagina, 1 t/m 1000 (standaard 100). |
cursor | De waarde van next_cursor uit het vorige antwoord (24 uur geldig). |
modified_since | Alleen rijen die sinds dit tijdstip zijn gewijzigd (ISO 8601), inclusief verwijderde rijen. |
include_deleted | true = ook rijen die bij de bron zijn verwijderd (bron_verwijderd_op is dan gevuld). |
Filteren kan op elk veld hieronder: schrijf veld=waarde (gelijk aan) of veld[operator]=waarde,
bijvoorbeeld id[ne]=waarde. De operatoren die per veld beschikbaar zijn staan in de
OpenAPI-specificatie.
Velden
| Veld | Type | Omschrijving |
|---|---|---|
connection_id | uuid | Account (connection) |
connection_label | text | Accountnaam |
id | uuid | ID |
synced_at | timestamptz | Laatst gesynchroniseerd |
bron_verwijderd_op | timestamptz | Verwijderd bij de bron |
external_id | text | Bron-ID |
dagboek_code | text | Dagboek (code) |
dagboek_naam | text | Dagboek (naam, na detail) |
dagboek_soort | integer | Dagboeksoort |
dagboek_soort_label | text | Dagboeksoort (label) |
soort | integer | Soort |
soort_label | text | Soort (label) |
factuurnummer | text | Factuurnummer |
factuurdatum | date | Factuurdatum |
boekdatum | date | Boekdatum |
boekjaar | integer | Boekjaar |
periode | integer | Periode |
vervaldatum | date | Vervaldatum |
omschrijving | text | Omschrijving |
betalingskenmerk | text | Betalingskenmerk |
valuta | text | Valuta |
crediteur_code | text | Crediteur (code) |
crediteur_naam | text | Crediteur (naam) |
betalingsconditie_code | text | Betalingsconditie (code) |
btw_scenario_code | text | Btw-scenario (code) |
kostenplaats_code | text | Kostenplaats (code) |
kostendrager_code | text | Kostendrager (code) |
project_code | text | Project (code) |
bedrag_excl | numeric | Bedrag excl. btw |
btw_bedrag | numeric | Btw-bedrag |
bedrag_incl | numeric | Bedrag incl. btw |
openstaand_bedrag | numeric | Openstaand bedrag |
goedkeuringsstatus | integer | Goedkeuringsstatus |
goedkeuringsstatus_label | text | Goedkeuringsstatus (label) |
goedgekeurd | boolean | Goedgekeurd |
goedgekeurd_op | timestamptz | Goedgekeurd op |
goedgekeurd_door | text | Goedgekeurd door |
goedgekeurd_door_regel | boolean | Goedgekeurd door regel |
goedkeuringsschema | text | Goedkeuringsschema (na detail) |
huidig_goedkeuringsniveau | integer | Huidig goedkeuringsniveau (na detail) |
exportstatus | integer | Exportstatus |
exportstatus_label | text | Exportstatus (label) |
geexporteerd_op | timestamptz | Geëxporteerd op |
exportfout | text | Exportfout |
extern_boekstuknummer | text | Extern boekstuknummer |
betaalbaar_status | integer | Betaalbaarstatus (na detail) |
betaalbaar_status_label | text | Betaalbaarstatus (label, na detail) |
concept | boolean | Concept |
geldig | boolean | Geldig |
voorstel_gewijzigd | boolean | Voorstel gewijzigd |
herkenningszekerheid | numeric | Herkenningszekerheid |
beoordeling | integer | Beoordeling |
beoordeling_label | text | Beoordeling (label) |
crediteur_match | integer | Crediteurmatch |
crediteur_match_label | text | Crediteurmatch (label) |
kostensoort | integer | Kostensoort (na detail) |
kostensoort_label | text | Kostensoort (label, na detail) |
inbox_document_id | text | Inboxdocument (bron-ID, na detail) Verwijst naar |
ontvangen_op | timestamptz | Ontvangen op |
herkomst | integer | Herkomst |
herkomst_label | text | Herkomst (label) |
afzender_naam | text | Afzender |
kanaal | text | Kanaal (na detail) |
aangemaakt_op | timestamptz | Aangemaakt op |
gewijzigd_op | timestamptz | Gewijzigd op |
Importeren in je tools
Aanvraag
GET https://app.apiboard.nl/api/v1/zenvoices/facturen?modified_since=2026-01-01T00%3A00%3A00Z HTTP/1.1
Host: app.apiboard.nl
Authorization: Bearer apib_live_JOUW_SLEUTEL
# Let op: gepagineerd. Herhaal met &cursor=<next_cursor> tot next_cursor null is.
# Deze aanroep haalt alleen rijen op die sinds die datum zijn gewijzigd (ook verwijderde,
# met bron_verwijderd_op). De laatste pagina bevat sync_watermark: geef die bij de volgende
# run mee als modified_since om daarna alleen nieuwe wijzigingen op te halen. curl -H "Authorization: Bearer apib_live_JOUW_SLEUTEL" \
"https://app.apiboard.nl/api/v1/zenvoices/facturen?modified_since=2026-01-01T00%3A00%3A00Z"
# Let op: gepagineerd. Herhaal met &cursor=<next_cursor> tot next_cursor null is.
# Deze aanroep haalt alleen rijen op die sinds die datum zijn gewijzigd (ook verwijderde,
# met bron_verwijderd_op). De laatste pagina bevat sync_watermark: geef die bij de volgende
# run mee als modified_since om daarna alleen nieuwe wijzigingen op te halen. import json
import os
import requests
TOKEN = "apib_live_JOUW_SLEUTEL"
URL = "https://app.apiboard.nl/api/v1/zenvoices/facturen"
STAAT_BESTAND = "zenvoices_facturen_staat.json" # bewaart rijen + watermark tussen runs
staat = {"watermark": None, "rijen": {}}
if os.path.exists(STAAT_BESTAND):
with open(STAAT_BESTAND) as f:
staat = json.load(f)
basis_params = {}
# Alleen wijzigingen: de eerste run vanaf 2026-01-01, daarna telkens vanaf de vorige run
# (inclusief verwijderingen, die hieronder uit de lokale set gaan).
basis_params["modified_since"] = staat["watermark"] or "2026-01-01T00:00:00Z"
cursor = None
onvolledig = set()
while True:
params = dict(basis_params)
if cursor:
params["cursor"] = cursor
resp = requests.get(URL, params=params, headers={"Authorization": f"Bearer {TOKEN}"})
resp.raise_for_status()
body = resp.json()
for koppeling in body["connections"]:
if not koppeling["backfill_complete"]:
onvolledig.add(koppeling["label"])
for rij in body["data"]:
staat["rijen"][rij["id"]] = rij # dedupliceren op id, laatste versie wint
cursor = body["next_cursor"]
if cursor is None:
staat["watermark"] = body["sync_watermark"]
break
# Rijen die bij de bron verwijderd zijn, uit de lokale set halen.
staat["rijen"] = {i: r for i, r in staat["rijen"].items() if not r.get("bron_verwijderd_op")}
with open(STAAT_BESTAND, "w") as f:
json.dump(staat, f)
for label in sorted(onvolledig):
print(f"Waarschuwing: {label} is nog niet volledig gesynchroniseerd; de data kan onvolledig zijn.")
print(f"{len(staat['rijen'])} rijen.")
# Tip: verwijder af en toe (bv. maandelijks) zenvoices_facturen_staat.json voor een volledige run; een
# hele koppeling die is losgekoppeld, zie je incrementeel namelijk niet. let
Basis = "https://app.apiboard.nl",
Pad = "/api/v1/zenvoices/facturen",
Token = "apib_live_JOUW_SLEUTEL",
Filters = [modified_since = "2026-01-01T00:00:00Z"],
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 (een rij die tijdens de refresh wijzigt, kan twee keer terugkomen):
// 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
// Let op: het token staat hierboven in de M-query, en dus in het .pbix-bestand zelf -
// wees voorzichtig met het delen van dat bestand.
// Let op: staat een administratie in "connections" op backfill_complete = false, dan is
// die nog niet volledig gesynchroniseerd - de data hierboven kan dan onvolledig zijn.
// Let op: Power BI onthoudt geen stand tussen refreshes. Deze query haalt bij elke refresh
// de rijen op die sinds 2026-01-01 zijn gewijzigd, niet de hele tabel. Voorbeeldantwoord
{
"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",
"bron_verwijderd_op": null,
"external_id": "voorbeeld external_id",
"dagboek_code": "voorbeeld dagboek_code",
"dagboek_naam": "voorbeeld dagboek_naam",
"dagboek_soort": 42,
"dagboek_soort_label": "voorbeeld dagboek_soort_label",
"soort": 42,
"soort_label": "voorbeeld soort_label",
"factuurnummer": "voorbeeld factuurnummer",
"factuurdatum": "2026-01-15",
"boekdatum": "2026-01-15",
"boekjaar": 42,
"periode": 42,
"vervaldatum": "2026-01-15",
"omschrijving": "voorbeeld omschrijving",
"betalingskenmerk": "voorbeeld betalingskenmerk",
"valuta": "voorbeeld valuta",
"crediteur_code": "voorbeeld crediteur_code",
"crediteur_naam": "voorbeeld crediteur_naam",
"betalingsconditie_code": "voorbeeld betalingsconditie_code",
"btw_scenario_code": "voorbeeld btw_scenario_code",
"kostenplaats_code": "voorbeeld kostenplaats_code",
"kostendrager_code": "voorbeeld kostendrager_code",
"project_code": "voorbeeld project_code",
"bedrag_excl": 125.5,
"btw_bedrag": 125.5,
"bedrag_incl": 125.5,
"openstaand_bedrag": 125.5,
"goedkeuringsstatus": 42,
"goedkeuringsstatus_label": "voorbeeld goedkeuringsstatus_label",
"goedgekeurd": true,
"goedgekeurd_op": "2026-10-07T02:58:12.304211+00:00",
"goedgekeurd_door": "voorbeeld goedgekeurd_door",
"goedgekeurd_door_regel": true,
"goedkeuringsschema": "voorbeeld goedkeuringsschema",
"huidig_goedkeuringsniveau": 42,
"exportstatus": 42,
"exportstatus_label": "voorbeeld exportstatus_label",
"geexporteerd_op": "2026-10-07T02:58:12.304211+00:00",
"exportfout": "voorbeeld exportfout",
"extern_boekstuknummer": "voorbeeld extern_boekstuknummer",
"betaalbaar_status": 42,
"betaalbaar_status_label": "voorbeeld betaalbaar_status_label",
"concept": true,
"geldig": true,
"voorstel_gewijzigd": true,
"herkenningszekerheid": 125.5,
"beoordeling": 42,
"beoordeling_label": "voorbeeld beoordeling_label",
"crediteur_match": 42,
"crediteur_match_label": "voorbeeld crediteur_match_label",
"kostensoort": 42,
"kostensoort_label": "voorbeeld kostensoort_label",
"inbox_document_id": "voorbeeld inbox_document_id",
"ontvangen_op": "2026-10-07T02:58:12.304211+00:00",
"herkomst": 42,
"herkomst_label": "voorbeeld herkomst_label",
"afzender_naam": "voorbeeld afzender_naam",
"kanaal": "voorbeeld kanaal",
"aangemaakt_op": "2026-10-07T02:58:12.304211+00:00",
"gewijzigd_op": "2026-10-07T02:58:12.304211+00:00"
}
],
"next_cursor": null,
"sync_watermark": "2026-10-07T03:00:00.000000Z"
} De waarden zijn fictief; de vorm komt overeen met wat de API teruggeeft.
Velden in het antwoord
connections-
De gekoppelde accounts waar dit antwoord over gaat. Elk account heeft een
id, eenlabelenbackfill_complete:truebetekent dat de eerste volledige synchronisatie klaar is,falsedat de data nog onvolledig is. data-
De rijen. Elke rij heeft
connection_idenconnection_label: uit welk account de rij komt. next_cursor- Waarmee je de volgende pagina ophaalt.
nullbetekent 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.