Ga naar inhoud

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:

Authorization: Bearer exg_live_…

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:

De Toegang-pagina, tabblad API-sleutels: de sleuteltabel met toegangschips, de knop Nieuwe API-sleutel en de toggle Verworpen sleutels tonen

  • 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 leest accounts en contacts.

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:

  1. API-sleutel: de client verzendt Authorization: Bearer exg_live_…. Eenvoudigst; de rechten van de sleutel gelden.
  2. 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 MCP-toestemmingspagina: de naam van de client en redirect-host, de ingelogde gebruiker, de organisatie en de toegangsvoorinstellingen

  • 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.