Skip to content

API Reference

Base URL — production: https://backend.linkeddata.open-regels.nl Base URL — acceptance: https://acc.backend.linkeddata.open-regels.nl

All endpoints are under /v1/. Every response includes an API-Version header. Legacy /api/* endpoints exist with Deprecation headers and will be removed in v2.0.0.


Root

GET /

Returns API metadata and a directory of current and legacy endpoint paths.

Response:

{
  "name": "Linked Data Explorer Backend",
  "version": "0.4.0",
  "status": "running",
  "environment": "production",
  "documentation": "/v1/openapi.json",
  "health": "/v1/health",
  "endpoints": {
    "health": "/v1/health",
    "dmns": "/v1/dmns",
    "chains": "/v1/chains"
  },
  "legacy": {
    "health": "/api/health (deprecated)",
    "dmns": "/api/dmns (deprecated)",
    "chains": "/api/chains (deprecated)"
  }
}

Health

GET /v1/health

Returns service health and dependency status. Used by CI/CD pipelines and the frontend status indicator.

Response:

{
  "name": "Linked Data Explorer Backend",
  "version": "0.4.0",
  "environment": "production",
  "status": "healthy",
  "uptime": 123.456,
  "timestamp": "2026-01-13T19:44:14.971Z",
  "services": {
    "triplydb": {
      "status": "up",
      "latency": 165,
      "lastCheck": "2026-01-13T19:44:15.401Z"
    },
    "operaton": {
      "status": "up",
      "latency": 119,
      "lastCheck": "2026-01-13T19:44:15.401Z"
    }
  },
  "documentation": "/v1/openapi.json"
}

Response headers:

HTTP/1.1 200 OK
API-Version: 0.4.0
Content-Type: application/json

status values:

Value HTTP Meaning
healthy 200 All dependencies operational
degraded 503 One or more dependencies down
unhealthy 503 Health check itself failed

DMN discovery

GET /v1/dmns

Query TriplyDB for all published DMN decision models at the given endpoint.

Query parameters:

Parameter Required Description
endpoint Yes SPARQL endpoint URL (URL-encoded)

Response:

{
  "success": true,
  "data": {
    "dmns": [
      {
        "id": "https://regels.overheid.nl/services/aow-leeftijd/dmn",
        "identifier": "SVB_LeeftijdsInformatie",
        "title": "AOW Leeftijdsberekening",
        "xmlUrl": "/v1/dmns/SVB_LeeftijdsInformatie/xml",
        "inputs": [
          {
            "identifier": "geboortedatum",
            "title": "Geboortedatum",
            "type": "Date"
          }
        ],
        "outputs": [
          {
            "identifier": "aanvragerIs181920",
            "title": "Aanvrager is 18/19/20",
            "type": "Boolean"
          }
        ],
        "validationStatus": "validated",
        "validatedByName": "Sociale Verzekeringsbank",
        "validatedAt": "2026-02-14",
        "vendorCount": 1,
        "vendors": ["..."]
      }
    ],
    "endpoint": "https://api.open-regels.triply.cc/...",
    "cached": false
  }
}

Response is cached per endpoint for 5 minutes. cached: true in subsequent responses.


GET /v1/dmns/:identifier

Returns full metadata for a single DMN by its identifier.

Path parameters:

Parameter Description
identifier The dct:identifier value of the DMN (e.g., SVB_LeeftijdsInformatie)

Query parameters: endpoint (required)

Response: Same shape as a single entry in the GET /v1/dmns response array. The response also includes an xmlUrl field pointing to the XML download endpoint below.


GET /v1/dmns/:identifier/xml

Streams the deployed DMN XML for a single DMN, fetched from Operaton. The file is returned as <identifier>.dmn with Content-Type: application/xml and a Content-Disposition: attachment header, so browsers save it directly.

Path parameters:

Parameter Description
identifier The dct:identifier value of the DMN

Response: The raw DMN XML document (not the JSON envelope).


POST /v1/dmns/deploy

Deploys raw DMN XML to Operaton ad hoc, without requiring a pre-registered LDE norm identifier.

Added in v2026.08.2 for the CPSV Editor's DMN tab, which holds an uploaded or generated DMN file that has no registry entry of its own. The browser cannot call Operaton's /engine-rest/deployment/create directly — CORS blocks it for a local dev origin — so the call is routed here and forwarded server-to-server. A thin wrapper around the same operatonService.deployDrd() the registry-backed deploy path uses.

Body: the DMN XML plus a deployment name.

Response: the standard { success, data, error } envelope.


POST /v1/dmns/evaluate/:decisionKey

Evaluates a deployed decision on Operaton and returns the engine's response.

Added in v2026.08.2 alongside the deploy route above, for the same CORS reason. It backs Evaluate Decision, Run intermediate tests and Run test cases in the CPSV Editor's DMN tab — see its DMN Implementation.

This route is a raw passthrough — it does not use the standard envelope

Unlike every other endpoint in this reference, the response is Operaton's own JSON forwarded byte-for-byte and status-for-status: the raw success array, or the raw exception object on failure. There is no { success, data, error } wrapper, because the calling DMN tab reads Operaton's shape directly.

The request body is passed through equally unchanged. evaluateRaw() skips the plain-JS-value type inference that evaluateDecision() applies for its own, different caller contract — the DMN tab already constructs Operaton-shaped bodies, so re-wrapping would double-wrap and break the request.

Path parameters:

Parameter Description
decisionKey The Operaton decision-definition key to evaluate

Body: { "variables": { ... } }, in Operaton's own variable format.


Returns all DMN variable pairs that are connectable, including both exact identifier matches and semantic skos:exactMatch matches.

Query parameters: endpoint (required)

Response:

{
  "success": true,
  "data": [
    {
      "dmn1": { "identifier": "SVB_LeeftijdsInformatie", "title": "..." },
      "dmn2": { "identifier": "SZW_BijstandsnormInformatie", "title": "..." },
      "outputVariable": "aanvragerIs181920",
      "inputVariable": "aanvragerIs181920",
      "variableType": "Boolean",
      "matchType": "exact",
      "sharedConcept": null
    },
    {
      "dmn1": { "identifier": "ZorgtoeslagVoorwaardenCheck", "title": "..." },
      "dmn2": { "identifier": "berekenrechtenhoogtezorg", "title": "..." },
      "outputVariable": "heeftJuisteLeeftijd",
      "inputVariable": "leeftijd_requirement",
      "variableType": "Boolean",
      "matchType": "semantic",
      "sharedConcept": "https://regels.overheid.nl/concepts/leeftijd_requirement"
    }
  ]
}

GET /v1/dmns/semantic-equivalences

Returns variable pairs from different DMNs that share a skos:exactMatch concept.

Query parameters: endpoint (required)


GET /v1/dmns/cycles

Returns circular dependencies detected via semantic links (3-hop traversal).

Query parameters: endpoint (required)


Chain discovery

GET /v1/chains

Returns all discoverable chains — DMN pairs where an output variable of one model matches an input variable of another by exact identifier.

Query parameters: endpoint (required)


Chain execution

POST /v1/chains/execute

Execute a DMN chain sequentially.

Request body:

{
  "chain": ["SVB_LeeftijdsInformatie", "SZW_BijstandsnormInformatie"],
  "inputs": {
    "geboortedatum": "1960-01-01"
  },
  "endpoint": "https://api.open-regels.triply.cc/...",
  "isDrd": false
}

Set isDrd: true and provide a single entry-point identifier in chain for DRD execution.

Response:

{
  "success": true,
  "data": {
    "results": {
      "aanvragerIs181920": true,
      "bijstandsnorm": 1200.0
    },
    "steps": [
      {
        "dmn": "SVB_LeeftijdsInformatie",
        "inputs": { "geboortedatum": "1960-01-01" },
        "outputs": { "aanvragerIs181920": true },
        "duration": 145
      },
      {
        "dmn": "SZW_BijstandsnormInformatie",
        "inputs": { "aanvragerIs181920": true },
        "outputs": { "bijstandsnorm": 1200.0 },
        "duration": 98
      }
    ],
    "totalDuration": 243
  }
}

POST /v1/chains/execute/heusdenpas

Convenience endpoint for the Heusdenpas chain — a fixed three-step chain (SVB_LeeftijdsInformatie → SZW_BijstandsnormInformatie → RONL_HeusdenpasEindresultaat) with known-good production test data. Target execution time: <1000ms.

Request body:

{
  "inputs": {
    "geboortedatumAanvrager": "1980-01-23",
    "geboortedatumPartner": null,
    "dagVanAanvraag": "2025-12-24",
    "aanvragerAlleenstaand": true,
    "aanvragerHeeftKinderen": true,
    "aanvragerHeeftKind4Tm17": true,
    "aanvragerInwonerHeusden": true,
    "maandelijksBrutoInkomenAanvrager": 1500,
    "aanvragerUitkeringBaanbrekers": false,
    "aanvragerVoedselbankpasDenBosch": false,
    "aanvragerKwijtscheldingGemeentelijkeBelastingen": false,
    "aanvragerSchuldhulptrajectKredietbankNederland": false,
    "aanvragerDitKalenderjaarAlAangevraagd": false,
    "aanvragerAanmerkingStudieFinanciering": false
  },
  "options": {
    "includeIntermediateSteps": true
  }
}

Response:

{
  "success": true,
  "data": {
    "success": true,
    "chainId": "SVB_LeeftijdsInformatie->SZW_BijstandsnormInformatie->RONL_HeusdenpasEindresultaat",
    "executionTime": 827,
    "finalOutputs": {
      "aanmerkingHeusdenPas": true,
      "aanmerkingKindPakket": true
    },
    "steps": [
      {
        "dmnId": "SVB_LeeftijdsInformatie",
        "dmnTitle": "SVB Leeftijdsinformatie Berekening",
        "inputs": {
          "geboortedatumAanvrager": "1980-01-23",
          "dagVanAanvraag": "2025-12-24"
        },
        "outputs": {
          "aanvragerLeeftijd": 45,
          "aanvragerIs18": true,
          "aanvragerIs65": false
        },
        "executionTime": 234
      },
      {
        "dmnId": "SZW_BijstandsnormInformatie",
        "dmnTitle": "SZW Bijstandsnorm Informatie",
        "inputs": {
          "aanvragerAlleenstaand": true,
          "aanvragerHeeftKinderen": true,
          "aanvragerIs18": true
        },
        "outputs": {
          "bijstandsNorm": 1234.56,
          "toepasselijkeNorm": "alleenstaandeOuder"
        },
        "executionTime": 178
      },
      {
        "dmnId": "RONL_HeusdenpasEindresultaat",
        "dmnTitle": "Heusden Pas Eindresultaat",
        "inputs": {
          "aanvragerHeeftKind4Tm17": true,
          "aanvragerInwonerHeusden": true,
          "maandelijksBrutoInkomenAanvrager": 1500,
          "bijstandsNorm": 1234.56,
          "aanvragerUitkeringBaanbrekers": false,
          "aanvragerVoedselbankpasDenBosch": false,
          "aanvragerKwijtscheldingGemeentelijkeBelastingen": false,
          "aanvragerSchuldhulptrajectKredietbankNederland": false,
          "aanvragerDitKalenderjaarAlAangevraagd": false,
          "aanvragerAanmerkingStudieFinanciering": false
        },
        "outputs": {
          "aanmerkingHeusdenPas": true,
          "aanmerkingKindPakket": true
        },
        "executionTime": 415
      }
    ]
  },
  "timestamp": "2026-01-13T19:44:15.401Z"
}

POST /v1/chains/export

Assemble a DRD XML from a DRD-compatible chain and deploy it to Operaton. See DRD Generation for the full deployment flow.

Request body:

{
  "chain": ["SVB_LeeftijdsInformatie", "SZW_BijstandsnormInformatie"],
  "name": "Social Benefits DRD",
  "endpoint": "https://api.open-regels.triply.cc/..."
}

Response:

{
  "success": true,
  "data": {
    "deploymentId": "43c759d6-082b-11f1-a5e9-f68ed60940f5",
    "entryPointId": "dmn1_SZW_BijstandsnormInformatie",
    "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."
  }
}

TriplyDB proxy

POST /v1/triplydb/query

Execute a SPARQL query against any TriplyDB endpoint, bypassing browser CORS restrictions. Used by the frontend Query Editor for dynamic endpoint support.

Request body:

{
  "endpoint": "https://api.open-regels.triply.cc/datasets/stevengort/DMN-discovery/services/DMN-discovery/sparql",
  "query": "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5"
}

Response: SPARQL results in application/sparql-results+json format, wrapped in the standard response envelope.


eDOCS

Endpoints for integrating with the OpenText eDOCS document management system. Used by the RIP Phase 1 process to file project documents into project workspaces.

A legacy alias exists at /api/edocs (deprecated, returns Deprecation: true header).

See eDOCS Integration for configuration and stub mode details.

GET /v1/edocs/status

Returns eDOCS connectivity status and whether stub mode is active.

Response:

{
  "success": true,
  "data": {
    "status": "stub",
    "stubMode": true
  }
}

status values: "up" — live connection healthy, "down" — connection failed, "stub" — stub mode active.


POST /v1/edocs/workspaces/ensure

Creates a project workspace if one does not already exist for the given project number, or returns the existing one. Idempotent — safe to call multiple times for the same project.

Request body:

Field Type Required Description
projectNumber string Yes Unique project identifier. Used as the workspace search key.
projectName string Yes Human-readable project name.

Response:

{
  "success": true,
  "data": {
    "workspaceId": "2993897",
    "workspaceName": "123456789 — N308 Reconstructie",
    "created": true
  }
}

POST /v1/edocs/documents

Uploads a base64-encoded document to an eDOCS workspace.

Request body:

Field Type Required Description
workspaceId string Yes eDOCS workspace ID returned by /workspaces/ensure.
filename string Yes Filename for the document.
contentBase64 string Yes Base64-encoded file content.
metadata.docName string Yes eDOCS DOCNAME profile field.
metadata.appId string No eDOCS APP_ID profile field. Defaults to "INFRA".
metadata.formName string No eDOCS form name for profile selection.
metadata.extra object No Additional eDOCS profile fields passed through as-is.

Response:

{
  "success": true,
  "data": {
    "documentId": "2993898",
    "documentNumber": "2993898",
    "workspaceId": "2993897"
  }
}

GET /v1/edocs/workspaces/:workspaceId/documents

Lists all documents stored in an eDOCS workspace.

Path parameters:

Parameter Description
workspaceId eDOCS workspace ID.

Response:

{
  "success": true,
  "data": {
    "documents": [
      {
        "id": "2993898",
        "name": "123456789 — Intake Report — N308 Reconstructie",
        "documentNumber": "2993898"
      }
    ],
    "count": 1
  }
}

Asset Storage

These endpoints persist and retrieve BPMN processes, form schemas, and document templates. They require a configured DATABASE_URL on the backend — if the database is not configured, all endpoints return 503 DB_NOT_CONFIGURED.

GET /v1/assets/bpmn

Returns all non-readonly BPMN processes stored in the database.

Response:

{
  "success": true,
  "data": [
    {
      "id": "process_1774384869117",
      "bpmnProcessId": "HrOnboardingProcess",
      "name": "HR Onboarding Process",
      "processRole": "standalone",
      "calledElement": null,
      "status": "wip",
      "linkedDmnTemplates": [],
      "createdAt": "2026-03-25T07:00:00.000Z",
      "updatedAt": "2026-03-25T07:00:00.000Z"
    }
  ]
}

POST /v1/assets/bpmn

Creates or updates a BPMN process (upsert by id).

DELETE /v1/assets/bpmn/:id

Deletes a BPMN process by its LDE id.

GET /v1/assets/bpmn/by-bpmn-id/:bpmnProcessId

Looks up a process by its BPMN <process id="..."> value. Used by the deploy bundle assembler to resolve calledElement subprocess references.

Response:

{
  "success": true,
  "data": {
    "id": "example_tree_felling",
    "bpmnProcessId": "TreeFellingPermitSubProcess",
    "xml": "<?xml version=\"1.0\"...>"
  }
}

GET /v1/assets/forms

Returns all non-readonly form schemas.

POST /v1/assets/forms

Creates or updates a form schema (upsert by id).

DELETE /v1/assets/forms/:id

Deletes a form schema.

GET /v1/assets/documents

Returns all non-readonly document templates.

POST /v1/assets/documents

Creates or updates a document template (upsert by id).

DELETE /v1/assets/documents/:id

Deletes a document template.


SHACL validation

POST /v1/shacl/validate

Validates a CPSV-AP Turtle document against the CPSV-AP 3.2.0, CPRMV 0.4.1, and RONL SHACL shape layers (file-local). The CPRMV layer was added in v1.9.5.

Request body: { "content": "<turtle>" }

Response:

{
  "success": true,
  "data": {
    "valid": false,
    "parseError": null,
    "layers": {
      "cpsv-ap":     { "label": "CPSV-AP 3.2.0", "loaded": true, "issues": [] },
      "cprmv":       { "label": "CPRMV 0.4.1",   "loaded": true, "issues": [] },
      "ronl-custom": { "label": "RONL Custom",   "loaded": true, "issues": [] }
    },
    "summary": { "errors": 0, "warnings": 0, "infos": 0 }
  }
}

Each issue has the shape { severity, code, message, location? }. See the SHACL Validation Reference for codes and shapes.


POST /v1/shacl/validate-merged

As above, but first fetches the already-published triples for the document's subjects via a read-only SPARQL CONSTRUCT and unions them with the document before validating — catching collisions that only appear once the file is merged into the store.

Request body: { "content": "<turtle>", "endpoint": "https://…/sparql" }

endpoint is optional; the configured default TriplyDB endpoint is used when omitted.

Response: Identical shape to POST /v1/shacl/validate.


DSO Integration

Server-side proxy for the Digitaal Stelsel Omgevingswet (DSO) APIs. Proxying server-side keeps the DSO API key off the client and avoids browser CORS.

Five upstream APIs sit behind this one /v1/dso surface:

# API Upstream path Backs
1 Stelselcatalogus catalogus/api/opvragen/v3 /begrippen
2 RTR Gegevens toepasbare-regels/api/rtrgegevens/v2 /activiteiten*
3 Zoekinterface toepasbare-regels/api/zoekinterface/v2 /werkzaamheden/zoek, /werkzaamheden/suggereer
4 Opvragen Werkzaamheden toepasbare-regels/api/opvragenwerkzaamheden/v1 /werkzaamheden/:urn
5 Toepasbare Regels Uitvoeren Gegevens toepasbare-regels/api/toepasbareregelsuitvoerengegevens/v1 /toepasbare-regels*

Pre-production base URLs are service.pre.omgevingswet.overheid.nl/publiek/<path>; production is the same path on service.omgevingswet.overheid.nl. Each is overridable via DSO_CATALOGUE_BASE_URL, DSO_RTR_BASE_URL, DSO_ZOEKINTERFACE_BASE_URL, DSO_OPVRAGEN_WERKZAAMHEDEN_BASE_URL and DSO_UITVOEREN_GEGEVENS_BASE_URL, each with a _PROD counterpart.

Environment selection. Every DSO endpoint targets the pre-production DSO by default. To target production, send the header X-Dso-Env: prod (used by the frontend) or append ?env=prod — the header wins when both are present, and any other value falls back to pre. Each environment uses its own base URLs and API key (DSO_API_KEY / DSO_API_KEY_PROD).

Transport. Outbound calls carry x-api-key and Accept: application/hal+json — except STTR downloads (application/xml) and _suggereer (application/json). The request timeout is DSO_TIMEOUT, default 15 000 ms, enforced with an AbortController; the production config block has no timeout of its own, so both environments share the pre-production value.

Unless noted, responses are the DSO payload — HAL, returned verbatim, _embedded and _links intact for the caller to unwrap — wrapped in LDE's standard { success, data } envelope. On failure the DSO routes return { "success": false, "error": "<message>" } (a plain string, not the { code, message } error object used elsewhere): 400 for missing required parameters, 404 for an unknown URN/resource, 422 when a Conclusie STTR has no DMN to extract, and 502 for upstream DSO failures (the upstream body travels in the message).

Concepts (Stelselcatalogus)

GET /v1/dso/begrippen

Full-text search over the Stelselcatalogus concepts.

Parameter In Required Description
zoekTerm query No Free-text search term
geldigOp query No Validity date YYYY-MM-DD (defaults to current)
page query No Page number (default 1)
pageSize query No 10 | 20 | 40 | 100 (default 20)

Route comments say 10

The source comments on /begrippen and /activiteiten still claim a pageSize default of 10, while dso.service.ts has used DEFAULT_PAGE_SIZE = 20 since. The frontend always sends an explicit pageSize, so the discrepancy only reaches direct API consumers — for whom 20 is the value that applies.

Activities (RTR)

GET /v1/dso/activiteiten

All legal activities valid on a given date.

Parameter In Required Description
datum query No Date dd-MM-yyyy (defaults to today)
page query No Page number (default 1)
pageSize query No 10 | 20 | 40 | 100 (default 20)

GET /v1/dso/activiteiten/:urn

Fetch a single activity by URN. datum query param (dd-MM-yyyy, optional, defaults to today). Returns 404 when the URN does not exist in the active DSO environment.

POST /v1/dso/activiteiten/oin

All activities registered by one authority (OIN) — backs the Lelystad, Flevoland, Ede and Gelderland presets.

Request body: { "oin": "<OIN>", "datum"?: "dd-MM-yyyy" }oin is required (400 otherwise).

Upstream this is POST /activiteiten/_zoek with { datum, bestuursorgaan: { oin } } and a fixed pageSize=200, so one call returns the authority's complete set and the Activities tab can filter by name client-side.

POST /v1/dso/activiteiten/zoek

Search activities by date and optional point geometry.

Request body: { "datum"?: "dd-MM-yyyy", "lat"?: number, "lon"?: number, "page"?: number, "pageSize"?: number }

When lat and lon are both supplied they become a WGS84 geometrie point ({ type: "Point", coordinates: [lon, lat] }) with crs=epsg:4326 on the query string; without them the search is date-only.

Implemented, but no UI calls it

Geometry search is complete and tested end to end in both the backend and dsoService.ts, yet nothing in the DSO Explorer uses it — the Activities tab offers date and authority modes only. It is ready for a map or point-selection feature.

Werkzaamheden (Zoekinterface + Opvragen Werkzaamheden)

Search and autocomplete go to the Zoekinterface; the versioned detail call goes to a different API, Opvragen Werkzaamheden.

POST /v1/dso/werkzaamheden/zoek

Search werkzaamheden. Request body: { "zoekterm"?: string, "page"?: number, "pageSize"?: number }

POST /v1/dso/werkzaamheden/suggereer

Autocomplete suggestions. Request body: { "zoekterm": string } — required (400 otherwise).

GET /v1/dso/werkzaamheden/:urn

Versioned detail (version history) for a single werkzaamheid. Unlike the two endpoints above, this one proxies Opvragen Werkzaamheden (GET /werkzaamheden/{urn}?pageSize=100), which is what returns the full _embedded.werkzaamheidversies list with trefwoorden and logischeRelaties.

Toepasbare regels (Uitvoeren Gegevens API)

The Phase 4 extraction endpoints (v1.9.3+). They resolve an activity's toepasbare regels and turn STTR files into deploy-ready LDE assets.

GET /v1/dso/toepasbare-regels

Metadata for the toepasbare regels of an activity, grouped by rule type (Conclusie / Indieningsvereisten) with validity date and STTR version.

Parameter In Required Description
functioneleStructuurRef query Yes Full concept URI of the activity (400 when omitted)

GET /v1/dso/toepasbare-regels/:id/sttr

Streams the raw STTR XML as sttr-<id>.xml (Content-Type: application/xml, Content-Disposition: attachment). Returns the XML document, not the JSON envelope.

GET /v1/dso/toepasbare-regels/:id/dmn

Extracts the embedded DMN <definitions> from a Conclusie STTR and streams it as a standalone, deploy-ready decision-<id>.dmn (normalized to DMN 1.3 — input ids, FEEL-safe variable names, output typeRefs, camunda:historyTimeToLive). Returns 422 when the STTR contains no DMN. This is the endpoint the CPSV Editor's DSO → DMN import consumes (…/toepasbare-regels/{dmnId}/dmn).

GET /v1/dso/toepasbare-regels/:id/form-scaffold

Generates a form-js field scaffold from an Indieningsvereisten STTR questionnaire (boolean → checkbox, list → select, number → number field, attachment → labelled textfield).

Parameter In Required Description
formId query No Desired form-js schema id (defaults to the toepasbare-regel :id)

Response: the form-js JSON scaffold wrapped in the standard envelope.

Two of the three STTR endpoints above — /dmn and /form-scaffold — fetch the same upstream file as /sttr (GET /toepasbareRegels/{id}/sttrBestand) and differ only in what LDE does with the XML: pass it through, extract and normalise the embedded DMN, or parse uitv:uitvoeringsregels into a form-js schema.

/toepasbare-regels/:id/dmn is a cross-application contract, not an internal route: the CPSV Editor is handed only identifiers in its deep link and fetches the DMN from this endpoint itself.

Endpoint map

Every /v1/dso route and the upstream call it makes:

LDE endpoint Method DSO API Upstream call
/v1/dso/begrippen GET 1 Catalogus GET /begrippen
/v1/dso/activiteiten GET 2 RTR GET /activiteiten
/v1/dso/activiteiten/:urn GET 2 RTR GET /activiteiten/{urn}
/v1/dso/activiteiten/oin POST 2 RTR POST /activiteiten/_zoek (bestuursorgaan)
/v1/dso/activiteiten/zoek POST 2 RTR POST /activiteiten/_zoek (date + geometry)
/v1/dso/werkzaamheden/zoek POST 3 Zoekinterface POST /werkzaamheden/_zoek
/v1/dso/werkzaamheden/suggereer POST 3 Zoekinterface POST /werkzaamheden/_suggereer
/v1/dso/werkzaamheden/:urn GET 4 Opvragen Werkzaamheden GET /werkzaamheden/{urn}
/v1/dso/toepasbare-regels GET 5 Uitvoeren Gegevens GET /toepasbareRegels
/v1/dso/toepasbare-regels/:id/sttr GET 5 Uitvoeren Gegevens GET /toepasbareRegels/{id}/sttrBestand
/v1/dso/toepasbare-regels/:id/dmn GET 5 Uitvoeren Gegevens GET /toepasbareRegels/{id}/sttrBestand + DMN extraction
/v1/dso/toepasbare-regels/:id/form-scaffold GET 5 Uitvoeren Gegevens GET /toepasbareRegels/{id}/sttrBestand + form-js scaffold

Note that a single activity-detail click in the UI is not a single upstream call: the Activity Detail panel resolves each child activity with its own GET /v1/dso/activiteiten/:urn, so one click costs 1 + N RTR requests. See DSO Integration — child-activity fan-out.


Error responses

All error responses follow a standard envelope:

{
  "success": false,
  "error": {
    "code": "EXECUTION_ERROR",
    "message": "Chain execution failed: DMN not found"
  },
  "timestamp": "2026-01-13T19:44:15.401Z"
}

Error codes:

Code Meaning
INVALID_REQUEST Invalid or missing request parameters
NOT_FOUND Resource not found
QUERY_ERROR SPARQL query to TriplyDB failed
EXECUTION_ERROR DMN execution via Operaton failed
DISCOVERY_ERROR Chain discovery query failed

Legacy endpoints and deprecation

Note

Asset storage endpoints (/v1/assets/*) have no legacy /api/ equivalents. They were introduced in v1.3.0 as v1-only routes.

All /api/* endpoints are deprecated and will be removed in v2.0.0. They return identical responses to their /v1/* counterparts plus the following headers:

HTTP/1.1 200 OK
API-Version: 0.4.0
Deprecation: true
Link: </v1/health>; rel="successor-version"

Migration: replace every /api/ prefix with /v1/ in API calls.

Deprecated Replacement
GET /api/health GET /v1/health
GET /api/dmns GET /v1/dmns
GET /api/dmns/:identifier GET /v1/dmns/:identifier
GET /api/dmns/:definitionKey/xml GET /v1/dmns/:identifier/xml
GET /api/chains GET /v1/chains
POST /api/chains/execute POST /v1/chains/execute
POST /api/chains/execute/heusdenpas POST /v1/chains/execute/heusdenpas
GET /api/edocs/status GET /v1/edocs/status
POST /api/edocs/workspaces/ensure POST /v1/edocs/workspaces/ensure
POST /api/edocs/documents POST /v1/edocs/documents
GET /api/edocs/workspaces/:id/documents GET /v1/edocs/workspaces/:id/documents