Koppel uw gereedschap¶
Data Bridge heeft twee toegangen: een REST API voor integraties en scripts, en een MCP-server voor AI-gereedschappen. Beide volgen hetzelfde toegangsbeleid: elke aanroep wordt gecontroleerd tegen de rechten van de aanvrager (datatype × niveau × administratie) en tegen het abonnement, en elke aanroep wordt bijgehouden.
De basis-URL's, zichtbaar op het dashboard:
| Toegang | URL |
|---|---|
| REST API | https://apps.mvdw-software.com/exact/data-bridge/api/v1 |
| MCP-server | https://apps.mvdw-software.com/exact/data-bridge/api/mcp |
| OpenAPI-document | https://apps.mvdw-software.com/exact/data-bridge/api/v1/openapi.json |
REST API¶
Authenticatie¶
Elk verzoek draagt de API-sleutel:
De rechten van de sleutel bepalen wat de aanroep mag doen; de IP-toestemmingslijst van de sleutel (indien ingesteld) bepaalt waarvandaan deze mag komen.
Eindpunten¶
| Eindpunt | Wat het retourneert |
|---|---|
GET /resources |
de datatypes die het portaal aanbiedt: naam, versie, beschrijving, bewerkingen, beschikbare filters en sortersleutels. Eerst aanroepen |
GET /divisions |
de administraties (afdelingscodes) die deze sleutel mag gebruiken |
GET /divisions/:division/:resource |
een lijst met genormaliseerde records |
GET /divisions/:division/:resource/:id |
één record, op basis van Exact-id |
GET /openapi.json |
het OpenAPI 3-document |
Elk antwoord is ingewikkeld: { "data": … }.
Datatypen¶
| Resource | Wat het is | Bewerkingen |
|---|---|---|
accounts |
klanten, leveranciers en prospects (relaties): naam, code, contactgegevens, status | list, get |
contacts |
contactpersonen van relaties | list, get |
items |
producten en diensten | list, get |
sales-invoices |
verkoopfactuurkoppen: nummer, klant, data, status, bedragen | list, get |
gl-accounts |
grootboekrekeningen (rekeningoverzicht) | list, get |
De genormaliseerde velden zijn stabiel en leesbaar (accountId, invoiceDate, isSupplier, …), niet de OData-veldnamen van Exact. De GET /resources-respons en het OpenAPI-document vermelden ze allemaal, per datatype.
Filters, sortering, limiet¶
Lijsteindpunten nemen een kleine, strikte query-syntaxis op; onbekende parameters worden afgewezen in plaats van geraden:
| Parameter | Betekenis |
|---|---|
filter[name]=value |
gelijkheid |
filter[name][op]=value |
een vergelijking: startswith, ge, gt, le, lt (welke ops een veld heeft staat in GET /resources) |
sort=field |
sorteren op één van de sortsleutels van het resource |
limit=n |
maximaal n records, 1–1000 |
# klanten waarvan de naam begint met "A", gesorteerd op naam, max 20
curl -H "Authorization: Bearer exg_live_…" \
"https://apps.mvdw-software.com/exact/data-bridge/api/v1/divisions/321654/accounts?filter[name][startswith]=A&sort=name&limit=20"
# facturen van één klant gedateerd in oktober 2026
curl -H "Authorization: Bearer exg_live_…" \
"https://apps.mvdw-software.com/exact/data-bridge/api/v1/divisions/321654/sales-invoices?filter[customerId]=d527…&filter[invoiceDate][ge]=2026-10-01&filter[invoiceDate][lt]=2026-11-01"
De beschikbare filters per datatype:
| Resource | Filters |
|---|---|
accounts |
name (eq, startswith), code, email, vatNumber, isSupplier, modifiedAt (ge, gt, le, lt) |
contacts |
accountId, email, lastName (eq, startswith), modifiedAt |
items |
code (eq, startswith), isSalesItem, isStockItem, isTime, modifiedAt |
sales-invoices |
customerId, status (enum), invoiceDate (eq, ge, gt, le, lt), invoiceNumber (eq, ge, le), modifiedAt |
gl-accounts |
code (eq, startswith), modifiedAt |
Formaten en linked data¶
Leesaanvragen antwoorden in het formaat van de Accept-header. Zonder header krijg je JSON ({ "data": …, "meta": … }).
Accept |
Antwoord |
|---|---|
application/json (standaard) |
de genormaliseerde JSON |
application/ld+json |
JSON-LD met een inline @context |
text/turtle |
Turtle |
application/rdf+xml |
RDF/XML |
De linked-dataformaten beschrijven dezelfde records met standaardvocabularia: schema.org
(schema:Organization, schema:Person, schema:Product, schema:Invoice, schema:Project, postadressen en
geldbedragen), Dublin Core terms (identificatoren en datums) en
Hydra (een lijst is een hydra:Collection). Elk record heeft een IRI
(…/divisions/<division>/<resource>/<id>) en verwijst met IRI's naar gerelateerde records (de customer van een
factuur, de worksFor van een contact). Termen die geen standaardvocabularium dekt, zoals isSupplier, gebruiken
https://mvdw-software.com/exact/data-bridge/vocab#. De JSON-LD-context staat inline, er is dus niets op te halen.
Filters, sortering en rechten werken in elk formaat hetzelfde; een mediatype dat de API niet kan leveren geeft
406 resource.not_acceptable.
curl -H "Authorization: Bearer exg_live_…" -H "Accept: text/turtle" \
"https://apps.mvdw-software.com/exact/data-bridge/api/v1/divisions/321654/accounts?limit=2"
Fouten¶
Fouten zijn { "error": { "code": …, "message": … } }:
| Status | Code | Betekenis |
|---|---|---|
| 400 | resource.bad_parameter, resource.bad_limit |
een query-parameter is herhaald, onbekend of buiten bereik |
| 401 | credential.invalid |
de sleutel is onbekend, ingetrokken of het verkeerde type |
| 402 | billing.inactive |
het abonnement van de organisatie is niet actief |
| 403 | access.denied |
de rechten van de sleutel dekken dit datatype, niveau of administratie niet |
| 403 | credential.ip_not_allowed |
de sleutel heeft een IP-toestemmingslijst en dit adres staat er niet op |
| 404 | exact.not_found |
het record bestaat niet in Exact |
| 429 | exact.rate_limited |
Exact's eigen limiet; de respons bevat Retry-After, wacht en probeer opnieuw |
| 429 | exact.paused |
te veel recente fouten op dat Exact-eindpunt; de aanroep wordt een tijdje gepauzeerd |
De API is per sleutel snelheidsgelimiteerd (60 calls per minuut) bovenop Exact's eigen limieten.
API-sleutels¶
Sleutels bevinden zich onder Toegang → API-sleutels:

- Aanmaken: naam, toegangsvoorinstelling (of de aangepaste matrix), administraties, optionele IP-toestemmingslijst. De sleutel wordt één keer getoond.
- Intrekken: een sleutel kan altijd worden ingetrokken; consumenten die deze gebruiken werken onmiddellijk niet meer. Intrekkende sleutels blijven in de lijst (toggle Verworpen sleutels tonen) totdat je zeker weet dat geen enkele consument ze nog gebruikt.
- Rechten zijn per sleutel: twee integraties binnen één organisatie kunnen compleet verschillende rechten hebben: het facturatie-script leest alleen
sales-invoices, de AI-assistent leestaccountsencontacts.
De aangepaste matrix groepeert de datatypes per domein (CRM, Verkoop, Logistiek, Financieel) en biedt LEZEN / SCHRIJVEN / VERWIJDEREN per type. SCHRIJF- en WISRECHTEN zijn reeds opgeslagen, maar de API is momenteel alleen-lezen.
MCP voor AI-gereedschappen¶
De MCP-server spreekt het standaard Model Context Protocol (Streamable HTTP). Zijn tools worden gegenereerd uit de datatypes en gefilterd door de rechten van de aanvrager:
list_divisions, de administraties die de aanvrager mag gebruiken;list_accounts,get_accounts,list_contacts, …, één list-tool en één get-tool per datatype die de aanvrager mag lezen;- elke tool neemt dezelfde filters als de REST-lijsteindpunten (en de divisie).
Een AI-client ziet precies wat zijn rechten toestaan, niets meer, en elke toolaanroep wordt opnieuw gecontroleerd bij aanroeptijd, dus een ingetrokken sleutel of een gedegradeerde beheerder werkt onmiddellijk niet meer.
Authenticatie¶
Twee manieren, kies per gereedschap:
- API-sleutel: de client verzendt
Authorization: Bearer exg_live_…. Eenvoudigst; de rechten van de sleutel gelden. - OAuth 2.1: de client voert een standaard authorization-code flow uit; helemaal geen sleutel in de client. Dit is de aanbevolen manier voor gereedschappen die dit ondersteunen (Claude, ChatGPT, …).
De server adverteert zichzelf voor OAuth-clients:
- discovery:
https://apps.mvdw-software.com/.well-known/oauth-authorization-server/exact/data-bridge/api/oauth - metadata beveiligde resource:
https://apps.mvdw-software.com/.well-known/oauth-protected-resource/exact/data-bridge/api/mcp
De toestemming¶
Bij OAuth opent de eerste verbinding een toestemmingspagina voor een organisatie-eigenaar of -beheerder (met tweefactorauthenticatie):

- de pagina vermeldt de client en zijn redirect-host (ontvangt toegang), en wie er ingelogd is;
- de beheerder kiest de organisatie (wanneer er meer dan één is) en de toegang: Alleen lezen (standaard), Lezen & schrijven of Aangepast (de volledige matrix);
- Toestaan koppelt het gereedschap; Weigeren weigert het.
Elke MCP-aanroep hercontroleert bij het portaal dat de goedkeurende beheader nog steeds eigenaar/beheerder is met tweefactor ingeschakeld; indien dit niet langer het geval is, stopt het gereedschap. De gekoppelde app verschijnt onder Toegang → Gekoppelde apps, waar deze op elk moment kan worden ingetrokken.
Instellen per gereedschap¶
Het tabblad MCP op het dashboard bevat de server-URL en de twee veelgebruikte clients, klaar om te kopiëren:
Claude Code:
claude mcp add --transport http exact-gateway https://apps.mvdw-software.com/exact/data-bridge/api/mcp
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"exact-gateway": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://apps.mvdw-software.com/exact/data-bridge/api/mcp"]
}
}
}
Elke andere MCP-client die Streamable HTTP ondersteunt werkt op dezelfde manier: wijs hem naar de server-URL en verzend de API-sleutel als een bearer token of voltoon de OAuth-flow.
De cache¶
Onder Cache kan de organisatie inschakelen op een kortlevende cache van lijstantwoorden:
- standaard uit: elke aanroep gaat naar Exact;
- wanneer ingeschakeld, worden herhaalde list-aanroepen binnen de TTL (tot 24 uur) vanuit de cache beantwoord in plaats van Exact;
- de cache is versleuteld, per organisatie, en wordt automatisch geleegd wanneer het Exact-verbinding verliest of opnieuw moet autoriseren, zodat een verouderde kopie nooit over organisaties heen gaat;
- Nu leegmaken verwijdert hem handmatig (bijvoorbeeld na een grote import in Exact).
Het dashboard toont of de cache aan staat, en de Gebruikspagina toont het cachetrefferpercentage.