Ga naar de hoofdinhoud
Praxikon

Voor ontwikkelaars

Bouwen op de Praxikon regulatory graph

Deze pagina beschrijft de publieke v1-endpoints, hun werkelijke respons, wat er misgaat als u ze verkeerd aanroept, en welke afspraken over identifiers en versies blijven staan. Alle voorbeelden hieronder zijn tegen de draaiende API uitgevoerd.

Wat de regulatory graph is

De regulatory graph is de gepubliceerde vorm van de EU AI Act zoals Praxikon die heeft uitgewerkt: verplichtingen, wijzigingen, acties, bewijsstukken, controles, definities, richtsnoeren, normen, praktijkgevallen en actoren, elk als een eigen object met een eigen identifier, versie en payload-hash. Bronherleidbaarheid zit niet in een voetnoot maar in de vorm zelf. Elke uitspraak binnen een object draagt haar soort (officieel feit, Praxikon-duiding of aanbevolen actie), haar vindplaats (bron-id, bronlocator zoals "Article 50(1)-(5)", bron-URL en waar aanwezig de ELI) en haar reviewmetadata (wanneer gecontroleerd, door wie, met welke methode). Het bronregister achter die verwijzingen komt in dezelfde respons mee onder included.sources, inclusief uitgaveversie, controledatum en een hash over onze bronregistratie. Er wordt niets op verzoek gegenereerd: elk antwoord is een projectie van opgeslagen objecten, en dat is precies wat een citatie citeerbaar maakt.

Twee tijdassen houden recht en kennis uit elkaar. effective_at is de datum waarop een regel juridisch gold; known_at is de grens van wat wij op dat moment gepubliceerd en gecontroleerd hadden. U kunt dus niet alleen vragen wat vandaag geldt, maar ook wat op 1 maart 2025 gold, en wat wij daar toen over hadden staan. Nieuwe informatie overschrijft die eerdere momentopname niet. Wat inhoudelijk verandert, verandert via een nieuwe versie van het object met een eigen payload-hash, niet door een stille overschrijving van de oude.

De identifier, en de oude vorm ernaast

Elk object heet praxikon:{jurisdictie}:{regelgeving}:{type}:{slug}, bijvoorbeeld praxikon:eu:ai-act:obligation:article-50-transparency. Altijd vijf segmenten, zodat een parser nooit op het aantal hoeft te vertakken. De eerste twee segmenten zijn er omdat een platte vorm precies zo lang werkt als er één verordening is: de AI Act heeft een artikel 11, de AVG heeft er een, en een nationale uitvoeringswet ook. Jurisdictie en regelgeving beantwoorden twee verschillende vragen en zijn daarom twee segmenten.

Tot en met datasetversie 1.1.0 was de gepubliceerde vorm raip:{type}:{slug}. Die vorm is niet hernoemd en niet ingetrokken: elke oude identifier lost permanent op naar hetzelfde object, elk object draagt zijn oude naam mee in legacy_id, en meta.identifiers in elke graph-respons zegt welke vorm canoniek is en hoe uw invoer is opgelost. Een identifier die met het merk meebeweegt is geen identifier, dus hernoemen was nooit een optie. De afkorting leeft daarom door in technische contracten (raip: in de oude identifiers, raipv: in de JSON-LD-context, X-RAIP-Signature als koptekst) en nergens als naam van het platform.

De release die deze pagina beschrijft

dataset_id
praxikon:sys:registry:dataset:ai-act-implementation-graph
meta.dataset_id op elke graph-respons
dataset_version
2.1.0
meta.dataset_version
schema_version
1.4.0
meta.schema_version
Laatste releasecontrole
2026-08-08
meta.last_reviewed_at en de Last-Modified-header

Vijf minuten

Geen sleutel, geen account, geen registratie. Vijf aanroepen die u van een vraag naar een verantwoord dossier brengen.

  1. Minuut 1

    Stel een vraag

    Het antwoord-endpoint is het snelste startpunt: geen sleutel, geen registratie, en de uitkomst noemt meteen de identifiers waarmee u verder kunt.

    Aanroep
    curl -s "https://www.praxikon.com/api/v1/answer?q=our+chatbot+talks+to+customers&lang=en"
    Respons (ingekort)
    {
      "mode": "scenario",
      "question": "Our chatbot talks to customers. Does it have to say it is AI?",
      "likely_role": "Deployer (you use the system)",
      "obligations": [
        { "slug": "article-50-transparency", "legal_status": "applicable", "deadline_at": "2026-08-02T00:00:00.000Z" },
        { "slug": "article-4-ai-literacy",   "legal_status": "applicable", "deadline_at": "2025-02-02T00:00:00.000Z" }
      ],
      "dataset": { "version": "2.1.0", "effective_at": "2026-08-08T00:00:00.000Z", "known_at": "2026-08-14T00:00:00.000Z" }
    }
  2. Minuut 2

    Lees het object waar het antwoord op rust

    Elke slug uit stap 1 hoort bij een identifier van de vorm praxikon:eu:ai-act:obligation:{slug}. Vraag dat object op en u ziet de uitspraken, de vindplaatsen en de reviewmetadata waar het antwoord uit is samengesteld.

    Aanroep
    curl -s "https://www.praxikon.com/api/v1/obligations?lang=en&id=praxikon:eu:ai-act:obligation:article-50-transparency"
    Respons (ingekort)
    {
      "meta": { "count": 1, "dataset_version": "2.1.0", "effective_at": "2026-08-08T00:00:00.000Z", ... },
      "data": [
        {
          "id": "praxikon:eu:ai-act:obligation:article-50-transparency",
          "legacy_id": "raip:obligation:article-50-transparency",
          "version": "1.0.0",
          "effective_at": "2026-08-02T00:00:00.000Z",
          "known_at": "2026-08-14T00:00:00.000Z",
          "payload_hash_sha256": "239fbac0e4728dc239352b2f88b199c3cc098082ff72e2972b4b5e8a2b121406",
          "statements": [
            {
              "kind": "official_fact",
              "citations": [
                { "source_id": "praxikon:eu:ai-act:source:reg-eu-2024-1689", "source_locator": "Article 50(1)-(5) and Article 113" }
              ]
            }
          ]
        }
      ],
      "included": { "sources": [ { "id": "praxikon:eu:ai-act:source:reg-eu-2024-1689", "source_version": "original-oj-2024-07-12" } ] }
    }
  3. Minuut 3

    Zet de klok terug

    effective_at bepaalt welk recht u bevraagt. Op 1 maart 2025 golden er twee plichten, vandaag staan er 27 in de graph. Dezelfde vraag, een ander peilmoment, een ander antwoord, en dat verschil is de bedoeling.

    Aanroep
    curl -s "https://www.praxikon.com/api/v1/obligations?lang=en&effective_at=2025-03-01"
    curl -s "https://www.praxikon.com/api/v1/obligations?lang=en"
    Respons (ingekort)
    # effective_at=2025-03-01
    "count": 2   ->  article-4-ai-literacy, article-5-prohibited-practices
    
    # default (2026-08-08T00:00:00.000Z)
    "count": 27  ->  annex-iii-high-risk, article-10-data-governance, article-11-technical-documentation, ...
  4. Minuut 4

    Cache op de ETag

    De graph-endpoints geven een ETag over de payload en een Last-Modified die gelijk is aan de laatste releasecontrole. Stuur de ETag terug en u krijgt 304 zonder body. Zo hoeft een agent die de graph volgt niet telkens megabytes te herhalen.

    Aanroep
    ETAG=$(curl -sI "https://www.praxikon.com/api/v1/obligations?lang=en" \
      | awk 'tolower($1)=="etag:"{print $2}' | tr -d '\r')
    
    curl -s -o /dev/null -w '%{http_code}\n' \
      -H "If-None-Match: $ETAG" \
      "https://www.praxikon.com/api/v1/obligations?lang=en"
    Respons (ingekort)
    304
  5. Minuut 5

    Draai een volledige beoordeling

    Wie meer wil dan één vraag, geeft een gecodeerd profiel door aan de implementatiekaart. Terug komt een dossier met per plicht de uitkomst, het regelspoor eronder en een payload-hash waarmee twee partijen kunnen vaststellen dat ze naar hetzelfde dossier kijken.

    Aanroep
    curl -s -X POST "https://www.praxikon.com/api/v1/implementation-map" \
      -H "Content-Type: application/json" \
      -d '{"lang":"en","profile":{
            "actor_role":"deployer","object_type":"ai_system",
            "eu_nexus":"offered_or_used_in_eu","article_5_signal":"none_known",
            "annex_iii_domain":"employment","annex_iii_use_case":"emp-4a",
            "decision_influence":"materially_influences",
            "article_50_scenarios":["none"],"article_50_market_date":"not_relevant",
            "direct_interaction_obvious":"not_relevant",
            "public_interest_editorial_control":"not_relevant",
            "fria_context":"none","gpai_union_market":"not_relevant",
            "gpai_market_date":"not_relevant","gpai_open_source_status":"not_relevant"}}'
    Respons (ingekort)
    {
      "summary": { "applies": 2, "possibly_applies": 0, "not_indicated": 3, "insufficient_context": 0 },
      "results": [
        { "slug": "article-4-ai-literacy",     "applicability": "applies",       "timing": "current" },
        { "slug": "article-50-transparency",   "applicability": "not_indicated", "timing": "current" },
        { "slug": "annex-iii-high-risk",       "applicability": "applies",       "timing": "future"  },
        { "slug": "article-27-fria",           "applicability": "not_indicated", "timing": "future"  },
        { "slug": "article-53-gpai",           "applicability": "not_indicated", "timing": "current" }
      ],
      "snapshot_id": "praxikon:sys:assessment:implementation-snapshot:281d68208ff578821847c141",
      "payload_hash_sha256": "281d68208ff578821847c14127233cd3b52b4a700bb6662eefcc1df969db05b0",
      "decision_engine_version": "1.0.0"
    }

De endpoints

Het OpenAPI-contract is de normatieve vorm; hieronder staat per endpoint waar het voor is, wat het aanneemt en wat het teruggeeft. Een guard in de bouw toetst deze lijst in twee richtingen tegen de routes, zodat er hier geen endpoint kan staan dat niet bestaat en geen endpoint kan bestaan dat hier ontbreekt.

GET/api/v1/answer

Een vraag in gewone taal koppelen aan de scenariolexicon en er een deterministisch antwoord uit samenstellen: welke plichten spelen, welke eerste acties horen erbij, welk bewijs hoort bewaard te blijven. Er komt geen taalmodel aan te pas. Herkent de engine niets, dan volgt mode "none" met alternatieven, niet een gegokt antwoord.

Parameters

q
Verplicht. De vraag, afgekapt op 200 tekens. Ontbreekt hij, dan volgt 400 missing_q.
lang
"nl" of "en". Alles wat niet "en" is, wordt gelezen als "nl".
view
Optioneel. Laat weg of geef "full" voor de volledige respons; die blijft de standaard en verandert niet. Met "brief" krijgt u de compacte vorm voor agents: de vraag, de vermoedelijke rol, de verplichtingen met label, identifier, status en toepassingsmoment, de eerste acties, het gevraagde bewijs en per verplichting één vindplaats. Hetzelfde antwoord uit dezelfde engine, ongeveer een tiende van de bytes, met een "full"-link terug. Een onbekende waarde valt terug op de volledige vorm en geeft geen 400.
Aanroep
curl -s "https://www.praxikon.com/api/v1/answer?q=our+chatbot+talks+to+customers&lang=en"
Respons (ingekort)
{
  "query": "our chatbot talks to customers",
  "lang": "en",
  "mode": "scenario",
  "question": "Our chatbot talks to customers. Does it have to say it is AI?",
  "likely_role": "Deployer (you use the system)",
  "dataset": {
    "id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "version": "2.1.0",
    "schema_version": "1.4.0",
    "effective_at": "2026-08-08T00:00:00.000Z",
    "known_at": "2026-08-14T00:00:00.000Z",
    "last_reviewed_at": "2026-08-08T00:00:00.000Z",
    "licence": "https://www.praxikon.com/nl/legal/terms",
    "canonical_url": "https://www.praxikon.com/api/v1/entities"
  },
  "obligations": [
    {
      "slug": "article-50-transparency",
      "label": "Article 50: transparency",
      "legal_status": "applicable",
      "deadline_at": "2026-08-02T00:00:00.000Z",
      "human_page": "https://www.praxikon.com/en/verplichtingen/article-50-transparency",
      "citations": [
        {
          "kind": "official_fact",
          "source_id": "praxikon:eu:ai-act:source:reg-eu-2024-1689",
          "source_locator": "Article 50(1)-(5) and Article 113",
          "source_url": "https://eur-lex.europa.eu/eli/reg/2024/1689/oj",
          "eli": "http://data.europa.eu/eli/reg/2024/1689/oj"
        }
      ]
    }
  ],
  "sources": [ ... ],
  "first_actions": [ ... ],
  "evidence": [ ... ],
  "guidance": [ ... ],
  "examples": [ ... ],
  "follow_up_questions": [ ... ],
  "disclaimer": "General interpretation, not legal advice. The official source remains authoritative.",
  "methodology": "https://www.praxikon.com/en/methodologie"
}

GET/api/v1/obligations

De verplichtingsobjecten: de kern van de graph. Elk object draagt zijn voorwaarden, uitzonderingen, gekoppelde acties, bewijsstukken en controles, en per uitspraak de vindplaats waarop die rust.

Parameters

lang
"nl" of "en". Standaard "nl". Iets anders geeft 400 invalid_lang.
id
Eén object opvragen op zijn volledige identifier, bijvoorbeeld praxikon:eu:ai-act:obligation:article-50-transparency. De oude vorm raip:obligation:article-50-transparency blijft werken en lost naar hetzelfde object op. Maximaal 200 tekens.
role
Filter op actor, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op actor_ids en beantwoordt de vraag welke objecten over deze rol gaan, inclusief de gevallen waarin de rol ontvanger of geraakte partij is. Maximaal 128 tekens.
duty_holder
Filter op juridische normadressaat, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op duty_holder_ids en beantwoordt de smallere vraag welke plichten op deze rol rusten. Objecten zonder uitgesplitste plichtdrager blijven eruit, zodat een leeg veld nooit als plicht wordt gelezen. Werkt via dezelfde rolhierarchie als role en combineert daarmee als een EN. Maximaal 128 tekens.
topic
Filter op onderwerp, bijvoorbeeld high-risk of timeline. Maximaal 128 tekens.
effective_at
De juridische peildatum. ISO-datum of volledige timestamp. Standaard de peildatum van de release.
known_at
De kennisgrens: tot waar onze gepubliceerde en gecontroleerde kennis reikt. Standaard de kennisdatum van de release.
format
"json" (standaard) of "jsonld". Een Accept-header met application/ld+json doet hetzelfde.
Aanroep
curl -s "https://www.praxikon.com/api/v1/obligations?lang=en&id=praxikon:eu:ai-act:obligation:article-50-transparency"
Respons (ingekort)
{
  "meta": {
    "dataset_id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "lang": "en",
    "effective_at": "2026-08-08T00:00:00.000Z",
    "known_at": "2026-08-14T00:00:00.000Z",
    "count": 1,
    "filters": { "id": "praxikon:eu:ai-act:obligation:article-50-transparency", "type": "obligation", "role": null, "duty_holder": null, "topic": null },
    "identifiers": {
      "canonical_namespace": "praxikon",
      "canonical_form": "praxikon:<jurisdiction>:<regulation>:<type>:<slug>",
      "legacy_namespace": "raip",
      "legacy_resolution": "permanent",
      "resolved": { "id": "praxikon:eu:ai-act:obligation:article-50-transparency", "role": null, "duty_holder": null }
    }
  },
  "data": [
    {
      "id": "praxikon:eu:ai-act:obligation:article-50-transparency",
      "legacy_id": "raip:obligation:article-50-transparency",
      "type": "obligation",
      "slug": "article-50-transparency",
      "version": "1.0.0",
      "effective_at": "2026-08-02T00:00:00.000Z",
      "known_at": "2026-08-14T00:00:00.000Z",
      "valid_until": null,
      "payload_hash_sha256": "239fbac0e4728dc239352b2f88b199c3cc098082ff72e2972b4b5e8a2b121406",
      "label": "Article 50: transparency",
      "topics": ["transparency"],
      "actor_ids": ["praxikon:eu:ai-act:actor:deployer", "praxikon:eu:ai-act:actor:provider"],
      "duty_holder_ids": ["praxikon:eu:ai-act:actor:deployer", "praxikon:eu:ai-act:actor:provider"],
      "affected_actor_ids": [],
      "oversight_actor_ids": [],
      "evidence_owner_ids": [],
      "duty_holder_uncertainty_status": null,
      "action_ids": ["praxikon:eu:ai-act:action:article-50-disclosure"],
      "evidence_ids": ["praxikon:eu:ai-act:evidence:article-50-implementation-record"],
      "conditions": [ ... ],
      "exceptions": [ ... ],
      "statements": [
        {
          "kind": "official_fact",
          "text": "Article 50 applies since 2 August 2026. The precise duty differs by scenario: ...",
          "citations": [
            {
              "source_id": "praxikon:eu:ai-act:source:reg-eu-2024-1689",
              "source_locator": "Article 50(1)-(5) and Article 113",
              "source_url": "https://eur-lex.europa.eu/eli/reg/2024/1689/oj",
              "eli": "http://data.europa.eu/eli/reg/2024/1689/oj"
            }
          ],
          "review": {
            "reviewed_at": "2026-08-14T00:00:00.000Z",
            "reviewer": "Praxikon release validation",
            "review_method": "source_link_and_rule_validation",
            "legal_status": "source_checked"
          }
        }
      ],
      "legal_status": "applicable",
      "deadline_at": "2026-08-02T00:00:00.000Z"
    }
  ],
  "included": {
    "sources": [
      {
        "id": "praxikon:eu:ai-act:source:reg-eu-2024-1689",
        "title": { "nl": "...", "en": "..." },
        "publisher": { "nl": "...", "en": "..." },
        "canonical_url": "https://eur-lex.europa.eu/eli/reg/2024/1689/oj",
        "eli": "http://data.europa.eu/eli/reg/2024/1689/oj",
        "source_version": "original-oj-2024-07-12",
        "verified_at": "2026-08-14T00:00:00.000Z",
        "fingerprint_basis": "canonical_url|source_version|verified_at",
        "source_record_hash_sha256": "bf0fca3e..."
      }
    ]
  },
  "links": {
    "self": "https://www.praxikon.com/api/v1/obligations?lang=en&id=praxikon%3Aeu%3Aai-act%3Aobligation%3Aarticle-50-transparency",
    "alternate": "https://www.praxikon.com/api/v1/obligations?lang=en&id=...&format=jsonld",
    "licence": "https://www.praxikon.com/nl/legal/terms"
  }
}

GET/api/v1/changes

De tijdlijn als objecten: wat ging wanneer gelden, wat verschoof, en welke plichten zijn erdoor geraakt. Dezelfde vorm als de verplichtingen, met type "change".

Parameters

lang
"nl" of "en". Standaard "nl". Iets anders geeft 400 invalid_lang.
id
Eén object opvragen op zijn volledige identifier, bijvoorbeeld praxikon:eu:ai-act:obligation:article-50-transparency. De oude vorm raip:obligation:article-50-transparency blijft werken en lost naar hetzelfde object op. Maximaal 200 tekens.
role
Filter op actor, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op actor_ids en beantwoordt de vraag welke objecten over deze rol gaan, inclusief de gevallen waarin de rol ontvanger of geraakte partij is. Maximaal 128 tekens.
duty_holder
Filter op juridische normadressaat, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op duty_holder_ids en beantwoordt de smallere vraag welke plichten op deze rol rusten. Objecten zonder uitgesplitste plichtdrager blijven eruit, zodat een leeg veld nooit als plicht wordt gelezen. Werkt via dezelfde rolhierarchie als role en combineert daarmee als een EN. Maximaal 128 tekens.
topic
Filter op onderwerp, bijvoorbeeld high-risk of timeline. Maximaal 128 tekens.
effective_at
De juridische peildatum. ISO-datum of volledige timestamp. Standaard de peildatum van de release.
known_at
De kennisgrens: tot waar onze gepubliceerde en gecontroleerde kennis reikt. Standaard de kennisdatum van de release.
format
"json" (standaard) of "jsonld". Een Accept-header met application/ld+json doet hetzelfde.
Aanroep
curl -s "https://www.praxikon.com/api/v1/changes?lang=en"
Respons (ingekort)
{
  "meta": { "count": 20, "filters": { "type": "change", ... }, "identifiers": { ... }, ... },
  "data": [
    {
      "id": "praxikon:eu:ai-act:change:2024-08-01-entry-into-force",
      "legacy_id": "raip:change:2024-08-01-entry-into-force",
      "type": "change",
      "slug": "2024-08-01-entry-into-force",
      "version": "1.0.0",
      "effective_at": "2024-08-01T00:00:00.000Z",
      "known_at": "2026-08-14T00:00:00.000Z",
      "payload_hash_sha256": "3005c4a62c53f5c6606f6537159ec01ea6aaf834bfdc68728e4d8d8dece75259",
      "label": "The AI Act enters into force",
      "topics": ["timeline"],
      "obligation_ids": [
        "praxikon:eu:ai-act:obligation:article-4-ai-literacy",
        "praxikon:eu:ai-act:obligation:article-5-prohibited-practices"
      ],
      "statements": [ ... ],
      "legal_status": "applicable",
      "deadline_at": "2024-08-01T00:00:00.000Z"
    }
  ],
  "included": { "sources": [ ... ] },
  "links": { ... }
}

GET/api/v1/entities

Alle objecttypen in één endpoint. Zonder filter krijgt u de hele graph voor het gevraagde peilmoment; met type= haalt u één soort op.

Parameters

lang
"nl" of "en". Standaard "nl". Iets anders geeft 400 invalid_lang.
id
Eén object opvragen op zijn volledige identifier, bijvoorbeeld praxikon:eu:ai-act:obligation:article-50-transparency. De oude vorm raip:obligation:article-50-transparency blijft werken en lost naar hetzelfde object op. Maximaal 200 tekens.
role
Filter op actor, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op actor_ids en beantwoordt de vraag welke objecten over deze rol gaan, inclusief de gevallen waarin de rol ontvanger of geraakte partij is. Maximaal 128 tekens.
duty_holder
Filter op juridische normadressaat, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op duty_holder_ids en beantwoordt de smallere vraag welke plichten op deze rol rusten. Objecten zonder uitgesplitste plichtdrager blijven eruit, zodat een leeg veld nooit als plicht wordt gelezen. Werkt via dezelfde rolhierarchie als role en combineert daarmee als een EN. Maximaal 128 tekens.
topic
Filter op onderwerp, bijvoorbeeld high-risk of timeline. Maximaal 128 tekens.
effective_at
De juridische peildatum. ISO-datum of volledige timestamp. Standaard de peildatum van de release.
known_at
De kennisgrens: tot waar onze gepubliceerde en gecontroleerde kennis reikt. Standaard de kennisdatum van de release.
format
"json" (standaard) of "jsonld". Een Accept-header met application/ld+json doet hetzelfde.
type
Eén van: actor, obligation, change, action, evidence, control, template, definition, guidance, standard, example. Iets anders geeft 400 invalid_type.
Aanroep
curl -s "https://www.praxikon.com/api/v1/entities?type=evidence&lang=en"
Respons (ingekort)
{
  "meta": {
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "lang": "en",
    "count": 36,
    "filters": { "id": null, "type": "evidence", "role": null, "duty_holder": null, "topic": null },
    ...
  },
  "data": [
    {
      "id": "praxikon:eu:ai-act:evidence:annex-iii-article-49-2-registration-record",
      "type": "evidence",
      "version": "1.0.0",
      "payload_hash_sha256": "6b15d546edc41ffd88f61b5c03d4f1c57d60aac40411f5339e09eb7399081b1e",
      "label": "Article 49(2) registration record for the system assessed as not high-risk",
      "summary": "...",
      "obligation_ids": ["praxikon:eu:ai-act:obligation:annex-iii-high-risk"],
      "statements": [ ... ]
    }
  ],
  "included": { "sources": [ ... ] },
  "links": { ... }
}

Zoeken over alle objecttypen wanneer u nog niet weet welke plicht relevant is. Elk resultaat draagt een score. De zoekopdracht geeft opgeslagen objecten terug en genereert geen antwoord.

Parameters

q
Verplicht, maximaal 200 tekens. Ontbreekt hij, dan volgt 400 missing_q.
limit
Geheel getal van 1 tot en met 50. Standaard 20. Buiten dat bereik volgt 400 invalid_limit.
lang
"nl" of "en". Standaard "nl". Iets anders geeft 400 invalid_lang.
id
Eén object opvragen op zijn volledige identifier, bijvoorbeeld praxikon:eu:ai-act:obligation:article-50-transparency. De oude vorm raip:obligation:article-50-transparency blijft werken en lost naar hetzelfde object op. Maximaal 200 tekens.
role
Filter op actor, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op actor_ids en beantwoordt de vraag welke objecten over deze rol gaan, inclusief de gevallen waarin de rol ontvanger of geraakte partij is. Maximaal 128 tekens.
duty_holder
Filter op juridische normadressaat, bijvoorbeeld praxikon:eu:ai-act:actor:deployer. Dit filtert op duty_holder_ids en beantwoordt de smallere vraag welke plichten op deze rol rusten. Objecten zonder uitgesplitste plichtdrager blijven eruit, zodat een leeg veld nooit als plicht wordt gelezen. Werkt via dezelfde rolhierarchie als role en combineert daarmee als een EN. Maximaal 128 tekens.
topic
Filter op onderwerp, bijvoorbeeld high-risk of timeline. Maximaal 128 tekens.
effective_at
De juridische peildatum. ISO-datum of volledige timestamp. Standaard de peildatum van de release.
known_at
De kennisgrens: tot waar onze gepubliceerde en gecontroleerde kennis reikt. Standaard de kennisdatum van de release.
format
"json" (standaard) of "jsonld". Een Accept-header met application/ld+json doet hetzelfde.
type
Beperk de zoekopdracht tot één objecttype.
Aanroep
curl -s "https://www.praxikon.com/api/v1/search?q=chatbot&lang=en&limit=1"
Respons (ingekort)
{
  "meta": {
    "dataset_version": "2.1.0",
    "lang": "en",
    "count": 1,
    "query": "chatbot",
    "limit": 1,
    "filters": { "id": null, "type": null, "role": null, "duty_holder": null, "topic": null },
    ...
  },
  "data": [
    {
      "id": "praxikon:eu:ai-act:example:example-high-risk-benefits-chatbot-factual",
      "type": "example",
      "slug": "example-high-risk-benefits-chatbot-factual",
      "version": "1.0.0",
      "payload_hash_sha256": "ccd4592906b30dd15e8f2c82b781487573d638c6715c0b0b4593ee2316f7fac9",
      "label": "Chatbot answering factual questions from a benefits case handler",
      "obligation_ids": ["praxikon:eu:ai-act:obligation:annex-iii-high-risk"],
      "statements": [ ... ],
      "legal_status": "guidance",
      "score": 80
    }
  ],
  "included": { "sources": [ ... ] },
  "links": { ... }
}

GET/api/v1/enforcement

De EU-brede stand van handhaving: welke lidstaat welke markttoezichthouder heeft aangewezen, hoe ver de uitvoeringswet staat, en de onderzoeken, besluiten en boetes die zijn vastgelegd. Sinds datasetversie 2.0.0 komt daar het uitsprakenregister bij: per uitspraak welke relatie zij tot een bepaling draagt (interpreteert, verengt, verruimt, bevestigt of spreekt tegen). Elke entry draagt zijn primaire bron.

Parameters

country
ISO-landcode van twee letters. Wordt naar hoofdletters omgezet en filtert zowel de gebeurtenissen als de uitspraken. Een onbekende code geeft 200 met lege lijsten, geen fout; meta.empty_result_note zegt dan waarom de lijst leeg is.
type
Filter op soort gebeurtenis: designation, implementing_law, investigation, decision, fine, enforcement_signal of related_gdpr.
obligation
Slug van een verplichting, bijvoorbeeld article-5-prohibited-practices. Geeft alleen de uitspraken terug die aan die bepaling raken. Een slug die de graph niet kent is te onderscheiden van een bepaling waarover nog niets is beslist.
known_at
De kennis-as van de uitsprakenlaag, als ISO-datum. Pin hem en u krijgt de uitspraken zoals wij ze op dat moment hadden opgenomen. Een uitspraak verzet de tekst van een bepaling niet; wat verschuift is recorded_at, het moment waarop wij vastlegden wat wij weten dat zij betekent.
Aanroep
curl -s "https://www.praxikon.com/api/v1/enforcement?country=NL"
Respons (ingekort)
{
  "meta": {
    "verified_at": "2026-08-10",
    "version": "1.1.0",
    "source": "https://www.praxikon.com/nl/enforcement",
    "stats": {
      "totalEvents": 88,
      "aiActEvents": 79,
      "totalFinesEur": 138200000,
      "countriesWithDesignatedMsa": 11,
      "countriesTotal": 27
    },
    "rulings": {
      "register_id": "praxikon:sys:registry:register:rulings",
      "register_started_at": "2026-08-13",
      "source": "https://www.praxikon.com/nl/rechtspraak",
      "stats": { "total": 7, "aiAct": 0, "relatedGdpr": 7, "obligationsTouched": 4, "byRelation": { "illustrates": 8, ... } },
      "ai_act_case_law_note": "No case law or supervisory decision under the AI Act itself has been recorded. ...",
      "axes": "A ruling does not move the text of a provision. ..."
    },
    "filters": { "country": "NL", "type": null, "known_at": null, "obligation": null },
    "unrecognised_filters": [],
    "empty_result_note": null
  },
  "countries": [
    {
      "country_code": "NL",
      "country_name_en": "Netherlands",
      "msa_status": "draft",
      "implementing_law_status": "consultation",
      ...
    }
  ],
  "events": [
    {
      "id": "implementing_law-nl-dutch-ai-act-implementation-act-enters-public-consultation",
      "type": "implementing_law",
      "date": "2026-04-20",
      "country": "NL",
      "authority": "Ministerie van Economische Zaken",
      "title_en": "Dutch AI Act Implementation Act enters public consultation",
      "summary_en": "...",
      ...
    }
  ],
  "rulings": [
    {
      "id": "praxikon:eu:gdpr:ruling:nl-ap-clearview-2024",
      "basis": "related_gdpr",
      "forum": "supervisory_authority",
      "authority": "Autoriteit Persoonsgegevens (AP)",
      "jurisdiction": "NL",
      "decided_at": "2024-09-03",
      "recorded_at": "2026-08-13",
      "status": "final",
      "title_en": "Dutch DPA fines Clearview AI 30.5 million euros",
      ...
    }
  ]
}

GET/api/v1/corrections

Het correctielogboek: elke inhoudelijke fout van ons die wij hebben hersteld, met datum, wat er stond, wat er nu klopt, waarom, en de geraakte object-identifiers. Het register wordt altijd volledig teruggegeven en nooit afgekapt. Een lege lijst betekent dat er sinds register_started_at niets is vastgelegd, niet dat er geen fout mogelijk is.

Parameters

lang
nl of en. Bepaalt de taal van de toelichtingen; de identifiers blijven gelijk.
entity_id
Geef alleen de correcties terug die dit graph-object raakten, op stabiele identifier.
Aanroep
curl -s "https://www.praxikon.com/api/v1/corrections?lang=en"
Respons (ingekort)
{
  "meta": {
    "register_id": "praxikon:sys:registry:register:corrections",
    "dataset_id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "lang": "en",
    "register_started_at": "2026-08-14T00:00:00.000Z",
    "count": 0,
    "complete": true,
    "filters": { "id": null, "entity_id": null }
  },
  "data": [],
  "links": {
    "self": "https://www.praxikon.com/api/v1/corrections?lang=en",
    "licence": "https://www.praxikon.com/nl/legal/terms",
    "human_page": "https://www.praxikon.com/en/correcties",
    "methodology": "https://www.praxikon.com/en/methodologie"
  }
}

GET/api/v1/diff

Wat er tussen twee ijkpunten aan de kennislaag veranderde, per object: het identifier, of het is toegevoegd, gewijzigd of vervallen, welke velden bewogen, de payloadhash aan beide kanten, en het change-event, de correctie of de bron waaraan het hangt. Materiele wijzigingen (status, deadline, voorwaarden, uitzonderingen, plichtdrager, officieel feit) staan los van redactionele. Twee ijkpunten zijn verplicht: een niet-gepinde diff is niet reproduceerbaar.

Parameters

from_dataset_version, to_dataset_version
Twee vastgelegde releases vergelijken, bijvoorbeeld 1.1.0 en 2.1.0. Een release zonder vastgelegde momentopname geeft een 400 die noemt welke releases wel zijn vastgelegd.
from, to
Twee kennisdata vergelijken tegen de huidige release. Gebruik dit paar of het releasepaar, nooit allebei.
from_effective_at, to_effective_at
De juridische tijdas meebewegen. Staat die stil, dan kan een object niet vervallen: de kennisas vooruit zetten voegt alleen kandidaten toe.
materiality
material, editorial of all. Filtert de uitkomst; de klasse per veld blijft altijd zichtbaar.
id, type, lang, limit, offset
Dezelfde selectie als op de graph-endpoints, plus paginering. limit staat standaard op 50 en meta.has_more zegt of er meer is.
Aanroep
curl -s "https://www.praxikon.com/api/v1/diff?from=2026-08-08&to=2026-08-08&from_effective_at=2026-03-01&to_effective_at=2026-08-01&id=praxikon:eu:ai-act:obligation:article-4-ai-literacy&lang=en"
Respons (ingekort)
{
  "meta": {
    "mode": "known_at",
    "diff_engine_version": "1.1.0",
    "snapshot_format_version": "1.0.0",
    "axes_moved": ["effective_at"],
    "coverage": {
      "recorded_dataset_versions": ["1.1.0", "2.1.0"],
      "sufficient": false,
      "limits": [{ "code": "knowledge_axis_has_one_publication_instant", "detail": "..." }]
    },
    "count": 1, "total": 1, "has_more": false
  },
  "data": {
    "summary": { "status": "changes_found", "objects_compared": 155, "changed": 1, "material_change_present": true },
    "objects": [
      {
        "id": "praxikon:eu:ai-act:obligation:article-4-ai-literacy",
        "change_type": "modified",
        "materiality": "material",
        "version_from": "1.0.0",
        "version_to": "2.0.0",
        "payload_hash_sha256_from": "deadc6d9...",
        "payload_hash_sha256_to": "7a9516670dfca5dd7dcc96ae019e5714f843e20235abd3e9d92b71eb42445ff1",
        "changed_fields": [
          { "field": "conditions", "basis": "applicability", "materiality": "material" },
          { "field": "duty_holder_ids", "basis": "addressee", "materiality": "material" }
        ],
        "attribution": {
          "basis": "change_event",
          "change_events": [{ "id": "praxikon:eu:ai-act:change:2026-07-27-article-4-amended" }],
          "source_ids": ["praxikon:eu:ai-act:source:reg-eu-2026-1744"]
        }
      }
    ],
    "integrity_warnings": []
  }
}

POST/api/v1/impact

Een manifest in en een venster erbij, en het antwoord op één vraag: raakt wat er in dat venster in de kennislaag bewoog, dit dossier. De uitkomst is een van drie statussen, met per geraakt object de grond waarop het u bereikt, wat er bewoog, de bron en de vereiste actie. Er komt een tweede ingang bij die niet op de graph loopt: een uitspraak verzet geen payload, maar kan wel verschuiven wat wij weten dat een bepaling betekent. Staatloos: er wordt geen abonnement aangelegd en geen dossier bewaard, dus opnieuw vragen is uw eigen werk.

Parameters

manifest
In de body, verplicht. Het volledige manifest, in JSON of JSON-LD. Haalt het het gepubliceerde schema niet, dan volgt 400 invalid_manifest met de bevindingen en wordt er niets half beoordeeld. Een kaal manifest als body geeft 400 missing_manifest.
reference_point
In de body, optioneel. Het venster: from_dataset_version en to_dataset_version, of from en to op de kennis-as, plus eventueel effective_at, from_effective_at en to_effective_at. Laat u het weg, dan loopt het venster van de release waartegen het manifest is berekend tot de huidige. Beide paren tegelijk geeft 400 conflicting_reference_points, een half paar 400 incomplete_reference_points.
lang, emitted_at, max_objects
In de body, optioneel. lang is "nl" of "en". emitted_at is het moment dat in de gebeurtenis komt te staan; laat u het weg, dan stempelt de server de klok en zegt meta.emitted_at_basis welke van de twee het was. max_objects is een geheel getal van 1 tot en met 200, standaard 50; wat er niet in past verdwijnt niet uit beeld, want de teller blijft volledig en de afkapping staat als vlag in het antwoord.
Aanroep
# impact-request.json:
# {"lang":"en",
#  "reference_point":{"from_dataset_version":"1.1.0","to_dataset_version":"2.1.0"},
#  "manifest": <het volledige manifest uit POST /api/v1/manifest>}

curl -s -X POST "https://www.praxikon.com/api/v1/impact" \
  -H "Content-Type: application/json" \
  -d @impact-request.json
Respons (ingekort)
{
  "meta": {
    "impact_engine_version": "1.1.0",
    "event_format_version": "1.1.0",
    "diff_engine_version": "1.1.0",
    "manifest_version": "1.1.0",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "mode": "dataset_version",
    "reference_basis": "caller_supplied",
    "coverage": { "recorded_dataset_versions": ["1.1.0", "2.1.0"], "sufficient": true, "limits": [] },
    "interpretation_window": { "rulings_recorded_in_window": 0, "rulings_in_register": 7, "note": "Rulings move on the knowledge axis and not on the legal axis: ..." },
    "manifest_integrity": { "checked": true, "payload_hash_matches": true, "manifest_id_matches": true },
    "privacy": { "processing": "stateless", "server_persistence": "none", "subscriptions": "none", "archiving": "caller" },
    "signature": { "header": "X-RAIP-Signature", "scheme": "v1", "algorithm": "hmac-sha256", "signed_string": "v1:<timestamp>:<body>", "tolerance_seconds": 300 }
  },
  "data": {
    "impact": "review_recommended",
    "required_action": "review_change",
    "reason": "264 of the 408 objects that moved touch this manifest, none of them on a field that decides whether, when or by whom a duty must be met. ...",
    "summary": {
      "changed_objects_in_window": 408,
      "impacted_objects": 264,
      "rulings_in_window": 0,
      "impacting_rulings": 0,
      "by_impact": { "no_impact": 0, "review_recommended": 264, "reassessment_required": 0 },
      "by_match_basis": { "obligation_carried": 98, "required_action": 2, "required_evidence": 2, "reassessment_trigger": 2, "obligation_evaluated": 83, "obligation_of_manifest_role": 83, "topic_of_carried_obligation": 0 },
      "material_change_present": false
    },
    "objects": [
      {
        "id": "praxikon:eu:ai-act:action:annex-iii-article-6-3-justification",
        "type": "action",
        "change_type": "modified",
        "materiality": "editorial",
        "resolution": "graph",
        "impact": "review_recommended",
        "required_action": "review_change",
        "match_bases": ["obligation_carried"],
        "matched_obligation_ids": ["praxikon:eu:ai-act:obligation:annex-iii-high-risk"],
        "changed_fields": ["actor_ids", "obligation_ids"],
        "material_fields": [],
        "attribution": { "basis": "unattributed", "change_events": [], "corrections": [], "source_ids": [] }
      }
    ],
    "objects_total": 264,
    "objects_truncated": true,
    "interpretations": [],
    "max_objects": 50,
    "manifest_features": { "carried_obligation_ids": [ ... ], "role_ids": ["praxikon:eu:ai-act:actor:deployer"], "topics": ["ai-literacy", "high-risk"] },
    "event": { "event": "impact.review_recommended", "event_format_version": "1.1.0", ... }
  },
  "links": { "self": "...", "diff": "...", "rulings": "https://www.praxikon.com/api/v1/enforcement", "manifest": "...", "openapi": "..." }
}

GET/api/v1/naleving-index

De Staat van AI Act-naleving NL: de maandelijkse meting op het Nederlandse algoritmeregister. Per meetronde vijf indicatoren (impacttoets, wettelijke basis, proportionaliteit, menselijk toezicht, actualiteit), apart geteld voor alle entries en voor de zelfverklaarde hoog-risicosystemen, plus de samengestelde index. Wij meten het register, niet de organisatie: een leeg veld betekent dat het register geen bewijs toont.

Parameters

round
Id van een meetronde, bijvoorbeeld nl-2026-08. Geeft alleen die ronde terug. Een onbekende ronde geeft 200 met alle ronden; meta.unrecognised_filters en meta.rounds_available zeggen dan wat er wel bestaat.
Aanroep
curl -s "https://www.praxikon.com/api/v1/naleving-index"
Respons (ingekort)
{
  "meta": {
    "verified_at": "2026-08-20",
    "version": "1.0.0",
    "cadence": "monthly",
    "source": {
      "url": "https://www.praxikon.com/nl/staat-van-naleving",
      "register_url": "https://algoritmes.overheid.nl",
      "register_name": "Algoritmeregister van de Nederlandse overheid"
    },
    "definitions": [ { "key": "impact_assessment", "label": { "nl": "Impacttoets vermeld", ... }, "counts": { ... } } ],
    "index_formula": "unweighted mean of the five indicator shares, expressed 0 to 100",
    "delta_with_previous": { "index_all": null, "index_high_risk": null, "total_entries": null },
    "rounds_available": ["nl-2026-08"],
    "filters": { "round": null },
    "unrecognised_filters": [],
    "empty_result_note": null
  },
  "measurements": [
    {
      "id": "nl-2026-08",
      "measured_at": "2026-08-20",
      "total_entries": 1536,
      "index_all": 71.9,
      "index_high_risk": 67.3,
      "all": { "entries": 1536, "impact_assessment": { "count": 655, "share": 42.6 }, ... },
      "high_risk": { "entries": 41, "impact_assessment": { "count": 17, "share": 41.5 }, ... },
      "top_organisations": [ { "organisation": "Gemeente Amsterdam", "entries": 71 } ]
    }
  ],
  "observations": [ { "id": "nl-2026-06", "total_entries": 1462, "high_risk_entries": 41, ... } ]
}

POST/api/v1/implementation-map

De volledige beoordeling: gecodeerde antwoorden in, een ondertekend dossier uit. Per plicht komt terug of die geldt, wanneer, waarom, en welk regelspoor daaronder ligt. Staatloos: er wordt geen profiel bewaard.

Parameters

lang
In de body. "nl" of "en".
profile
In de body. De gecodeerde antwoorden: rol, objecttype, EU-aanknoping en de routevragen. Een onbekende, ontbrekende of tegenstrijdige code geeft 400 invalid_profile.
previous_snapshot
In de body, optioneel. Een eerder dossier waartegen de uitkomst wordt vergeleken. Faalt de integriteitscontrole, dan volgt 400 invalid_previous_snapshot.
Aanroep
curl -s -X POST "https://www.praxikon.com/api/v1/implementation-map" \
  -H "Content-Type: application/json" \
  -d '{
    "lang": "en",
    "profile": {
      "actor_role": "deployer",
      "object_type": "ai_system",
      "eu_nexus": "offered_or_used_in_eu",
      "article_5_signal": "none_known",
      "annex_iii_domain": "employment",
      "annex_iii_use_case": "emp-4a",
      "decision_influence": "materially_influences",
      "article_50_scenarios": ["none"],
      "article_50_market_date": "not_relevant",
      "direct_interaction_obvious": "not_relevant",
      "public_interest_editorial_control": "not_relevant",
      "fria_context": "none",
      "gpai_union_market": "not_relevant",
      "gpai_market_date": "not_relevant",
      "gpai_open_source_status": "not_relevant"
    }
  }'
Respons (ingekort)
{
  "snapshot_schema_version": "1.0.0",
  "decision_engine_version": "1.0.0",
  "language": "en",
  "dataset": {
    "id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "version": "2.1.0",
    "schema_version": "1.4.0",
    "effective_at": "2026-08-08T00:00:00.000Z",
    "known_at": "2026-08-14T00:00:00.000Z",
    "last_reviewed_at": "2026-08-08T00:00:00.000Z"
  },
  "profile": { ... },
  "summary": { "applies": 2, "possibly_applies": 0, "not_indicated": 3, "insufficient_context": 0 },
  "results": [
    {
      "obligation_id": "praxikon:eu:ai-act:obligation:article-4-ai-literacy",
      "slug": "article-4-ai-literacy",
      "applicability": "applies",
      "timing": "current",
      "effective_on": "2025-02-02T00:00:00.000Z",
      "legal_status": "applicable",
      "deadline_at": "2025-02-02T00:00:00.000Z",
      "why": [ ... ],
      "rule_trace": [
        { "rule_id": "scope.eu-nexus", "outcome": "met", "explanation": "..." },
        { "rule_id": "article-4.actor-role", "outcome": "met", "explanation": "..." },
        { "rule_id": "article-4.ai-system", "outcome": "met", "explanation": "..." }
      ],
      "assumptions": [ ... ],
      "actions": [ ... ],
      "evidence": [ ... ],
      "controls": [ ... ],
      "sources": [ ... ],
      "entity_version": "2.0.0",
      "entity_payload_hash_sha256": "7a9516670dfca5dd7dcc96ae019e5714f843e20235abd3e9d92b71eb42445ff1",
      "result_payload_hash_sha256": "ab3d561e..."
    }
  ],
  "source_fingerprints": [ ... ],
  "snapshot_id": "praxikon:sys:assessment:implementation-snapshot:281d68208ff578821847c141",
  "payload_hash_sha256": "281d68208ff578821847c14127233cd3b52b4a700bb6662eefcc1df969db05b0",
  "generated_at": "2026-08-13T19:40:02.859Z",
  "source_fingerprint_basis": "canonical_url|source_version|verified_at",
  "source_fingerprint_scope": "...",
  "privacy": { "processing": "stateless", "server_persistence": "none", "profile_contains_free_text": false },
  "disclaimer": "...",
  "revalidation": { "status": "first_assessment", "compared_snapshot_id": null, "changed_results": [] }
}

POST/api/v1/manifest

De systeembeschrijving in, een volledig Regulatory Manifest uit: aangewezen plichten met hun eigen status, het regelspoor eronder, wat er open staat, en een source_snapshot met datasetversie, schemaversie en een vingerafdruk per bronrecord. Staatloos: er wordt niets bewaard, dus archiveren is uw eigen werk.

Parameters

lang
In de body. "nl" of "en". Bepaalt de taal van de labels en toelichtingen; in het manifest heet dit veld language.
system_version
In de body, verplicht. De versie van het beoordeelde systeem zoals u die noemt: een release-tag, een semantische versie of een gedateerd buildlabel.
assessed_at
In de body, optioneel. Het moment van beoordelen, in UTC met een Z. Geeft u het mee, dan is het antwoord byte voor byte herhaalbaar tegen dezelfde datasetversie. Laat u het weg, dan stempelt de server de klok en bewegen assessed_at, manifest_id en payload_hash_sha256 bij elke aanroep mee; meta.assessed_at_basis zegt welke van de twee het was.
intended_purpose
In de body, optioneel. Het bedoelde doel in vrije tekst. Wordt onveranderd meegedragen en nooit ontleed; de gecodeerde antwoorden bepalen de route.
profile
In de body, verplicht. Dezelfde gecodeerde antwoorden als bij /api/v1/implementation-map. Een onbekende, ontbrekende of tegenstrijdige code geeft 400 invalid_manifest_request met de velden erbij, nooit een half manifest.
format
Als queryparameter. "json" (standaard) of "jsonld". Met jsonld krijgt u het manifest zelf onder zijn gepubliceerde context, zonder envelop. Een Accept-header met application/ld+json doet hetzelfde.
Aanroep
curl -s -X POST "https://www.praxikon.com/api/v1/manifest" \
  -H "Content-Type: application/json" \
  -d '{
    "lang": "en",
    "system_version": "4.2.0",
    "assessed_at": "2026-08-12T09:00:00.000Z",
    "intended_purpose": "Ranking job applicants in the first selection round.",
    "profile": {
      "actor_role": "deployer",
      "object_type": "ai_system",
      "eu_nexus": "offered_or_used_in_eu",
      "article_5_signal": "none_known",
      "annex_iii_domain": "employment",
      "annex_iii_use_case": "emp-4a",
      "decision_influence": "materially_influences",
      "article_50_scenarios": ["none"],
      "article_50_market_date": "not_relevant",
      "direct_interaction_obvious": "not_relevant",
      "public_interest_editorial_control": "not_relevant",
      "fria_context": "none",
      "gpai_union_market": "not_relevant",
      "gpai_market_date": "not_relevant",
      "gpai_open_source_status": "not_relevant"
    }
  }'
Respons (ingekort)
{
  "meta": {
    "manifest_version": "1.1.0",
    "manifest_engine_version": "1.0.0",
    "decision_engine_version": "1.0.0",
    "dataset_id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "lang": "en",
    "effective_at": "2026-08-08T00:00:00.000Z",
    "known_at": "2026-08-14T00:00:00.000Z",
    "assessed_at": "2026-08-12T09:00:00.000Z",
    "assessed_at_basis": "caller_supplied",
    "determinism": "The same input against the same dataset_version reproduces this manifest byte for byte, including manifest_id and payload_hash_sha256.",
    "privacy": {
      "processing": "stateless",
      "server_persistence": "none",
      "archiving": "caller",
      "note": "This manifest is not stored. There is no account, no server-side storage and no copy of your answers; archiving this document is your own responsibility."
    },
    "schema": "https://www.praxikon.com/schemas/regulatory-manifest-v1.schema.json"
  },
  "data": {
    "manifest_id": "praxikon:sys:assessment:manifest:c839fbce0cd03fd4c2c4296a",
    "manifest_version": "1.1.0",
    "system_version": "4.2.0",
    "language": "en",
    "assessed_at": "2026-08-12T09:00:00.000Z",
    "effective_at": "2026-08-08T00:00:00.000Z",
    "known_at": "2026-08-14T00:00:00.000Z",
    "roles": ["praxikon:eu:ai-act:actor:deployer"],
    "classification": { "result": "high_risk_annex_iii", "basis": [ ... ], "open_questions": [], "reassessment_triggers": [ ... ] },
    "obligations": [
      { "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk", "applicability": "applies", "uncertainty_status": "determined", "timing": "future", "deadline_at": "2027-12-02T00:00:00.000Z", ... },
      { "obligation_id": "praxikon:eu:ai-act:obligation:article-4-ai-literacy", "applicability": "applies", "uncertainty_status": "determined", "timing": "current", "deadline_at": "2025-02-02T00:00:00.000Z", ... }
    ],
    "uncertainty_status": "determined",
    "required_actions": [ ... ],
    "required_evidence": [ ... ],
    "assessment_input": { ... },
    "derived_from": { "snapshot_id": "praxikon:sys:assessment:implementation-snapshot:...", ... },
    "source_snapshot": { "dataset_version": "2.1.0", "schema_version": "1.4.0", "source_fingerprint_basis": "canonical_url|source_version|verified_at", "source_hashes": [ ... ] },
    "payload_hash_sha256": "c839fbce0cd03fd4c2c4296a25f766b11383680b6dfddbb0e4382d2ea8362645"
  },
  "links": { "self": "...", "alternate": "...", "schema": "...", "context": "...", ... }
}

POST/api/v1/manifest/validate

Toetst een manifest dat u al heeft aan het gepubliceerde schema en geeft leesbare bevindingen terug: het pad, de machineleesbare code en een zin in uw taal. Haalt het manifest het schema, dan wordt ook de payload-hash nagerekend en gemeld of de datasetversie nog de gepubliceerde is. Wat dit niet doet: opnieuw beoordelen, de inhoud aan de wet toetsen of het ingestuurde manifest bewaren.

Parameters

lang
In de body. "nl" of "en". Bepaalt de taal van de bevindingen; de code blijft taalonafhankelijk.
manifest
In de body, verplicht. Het te toetsen manifest, in JSON of in JSON-LD. Een kaal manifest als body wordt geweigerd met 400 invalid_request, zodat een toetsverzoek nooit met een manifest kan worden verward. Bij JSON-LD worden @context en het manifesttype opzijgezet voordat het schema erover loopt.
Aanroep
# validate-request.json:
# {"lang":"en","manifest": <het manifest dat u wilt toetsen>}

curl -s -X POST "https://www.praxikon.com/api/v1/manifest/validate" \
  -H "Content-Type: application/json" \
  -d @validate-request.json
Respons (ingekort)
{
  "meta": {
    "schema_id": "https://www.praxikon.com/schemas/regulatory-manifest-v1.schema.json",
    "manifest_version": "1.1.0",
    "manifest_engine_version": "1.0.0",
    "lang": "en",
    "input_serialization": "json",
    "scope": "This endpoint checks shape and internal consistency: the manifest schema, the payload hash and the dataset release it was computed against. It does not reassess, it does not test the content against the law, and it is not a legal opinion.",
    "privacy": { "processing": "stateless", "server_persistence": "none", "archiving": "caller", ... }
  },
  "data": {
    "valid": false,
    "issue_count": 3,
    "issues": [
      { "path": "#/assessed_at", "code": "invalid_date_time", "message": "This must be a full ISO 8601 instant including a time zone, for example 2026-08-12T09:00:00.000Z. A bare date is not enough." },
      { "path": "#/assessed_at", "code": "shorter_than_20", "message": "This string is shorter than the required 20 characters." },
      { "path": "#/verdict", "code": "additional_property_not_allowed", "message": "This field is not part of the manifest schema. The schema allows no extra fields, so a reader never has to guess what an unknown field means." }
    ],
    "issues_truncated": false,
    "integrity": { "checked": false, "payload_hash_matches": null, "manifest_id_matches": null, "scope": "The hash was not recomputed, because the document does not satisfy the schema. Repair the shape first." },
    "dataset_alignment": null
  },
  "links": { "self": "...", "schema": "...", "context": "...", ... }
}

GET/api/v1/dataset

De datasetbeschrijving als DCAT-3 JSON-LD: uitgever, licentie, versie, taalgebied, distributies en de endpoints die deze dataset bedienen. Bedoeld voor catalogi en crawlers, niet voor de dagelijkse aanroep.

Parameters

Geen parameters.

Aanroep
curl -s -H "Accept: application/ld+json" "https://www.praxikon.com/api/v1/dataset"
Respons (ingekort)
{
  "@context": [ "https://www.praxikon.com/contexts/praxikon-v1.jsonld", { ... } ],
  "@id": "urn:praxikon:sys:registry:dataset:ai-act-implementation-graph",
  "@type": ["dcat:Dataset", "schema:Dataset", "prov:Entity"],
  "dct:identifier": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
  "dcat:version": "2.1.0",
  "raipv:schemaVersion": "1.4.0",
  "raipv:appendOnly": true,
  "raipv:defaultEffectiveAt": "2026-08-08T00:00:00.000Z",
  "raipv:defaultKnownAt": "2026-08-14T00:00:00.000Z",
  "raipv:sourceCount": 13,
  "raipv:entityCount": 424,
  "dcat:accessService": { "dcat:endpointDescription": { "@id": "https://www.praxikon.com/api/v1/openapi" }, ... },
  "dcat:distribution": [ ... ]
}

GET/api/v1/openapi

Het OpenAPI 3.1-contract van deze API, machineleesbaar. Dit is de vorm die geldt; deze pagina is de leesbare toelichting erop.

Parameters

Geen parameters.

Aanroep
curl -s "https://www.praxikon.com/api/v1/openapi"
Respons (ingekort)
{
  "openapi": "3.1.1",
  "info": {
    "title": "Praxikon public API",
    "version": "1.11.0-beta.1",
    "summary": "Versioned, source-traceable EU AI Act implementation data for people and AI agents."
  },
  "servers": [{ "url": "https://www.praxikon.com", "description": "Public production endpoint" }],
  "paths": {
    "/api/v1/obligations": { ... },
    "/api/v1/changes": { ... },
    "/api/v1/entities": { ... },
    "/api/v1/answer": { ... },
    "/api/v1/enforcement": { ... },
    "/api/v1/dataset": { ... },
    "/api/v1/openapi": { ... },
    "/api/v1/status": { ... },
    "/changelog.json": { ... },
    "/api/v1/corrections": { ... },
    "/api/v1/diff": { ... },
    "/api/v1/search": { ... },
    "/api/v1/implementation-map": { ... },
    "/api/v1/manifest": { ... },
    "/api/v1/manifest/validate": { ... },
    "/api/v1/impact": { ... }
  }
}

GET/api/v1/status

De stand van de release, in feiten die ergens vandaan komen: welke dataset-, schema- en documentversie wordt uitgeserveerd, tot welke kennisdatum die reikt, hoeveel objecten en objectversies erin zitten, of de releasecontroles over precies deze inhoud zijn gedraaid, en wat er wel en niet aan verzoeklimieten geldt. Dit is het goedkoopste adres om op te pollen: stuur de ETag terug als If-None-Match en u krijgt 304 zonder body. Geen beschikbaarheidscijfer, want wij meten het niet en dat staat er dan ook zo.

Parameters

format
Alleen "json". Iets anders geeft 400 unsupported_format in plaats van een document dat geen context definieert.
Aanroep
curl -s "https://www.praxikon.com/api/v1/status"
Respons (ingekort)
{
  "meta": {
    "dataset_id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "openapi_version": "1.11.0-beta.1"
  },
  "data": {
    "release": {
      "known_at": "2026-08-14T00:00:00.000Z",
      "append_only": true,
      "graph_fingerprint_sha256": "{{graph_fingerprint_sha256}}",
      "fingerprint_basis": "sha256 over the canonical JSON of the whole dataset, including its metadata. ..."
    },
    "objects": {
      "entities": 424,
      "entity_versions": 425,
      "sources": 13,
      "by_type": { "obligation": 27, "example": 121, "definition": 64, ... }
    },
    "release_guards": {
      "status": "passed",
      "command": "npm run lint:content",
      "guard_count": 79,
      "basis": "The recorded run covers this exact dataset: the fingerprint written when the guard chain completed equals the fingerprint of the dataset served here. ..."
    },
    "service_level": { "committed": false, "uptime_measured": false, "latency_measured": false },
    "rate_limit": {
      "committed_limit": false,
      "enforced": [
        { "path": "/api/v1/answer", "max_requests": 60, "window_seconds": 60, "shared_across_instances": false },
        { "path": "/api/v1/enforcement", "max_requests": 60, "window_seconds": 60, "shared_across_instances": false }
      ],
      "unlimited": [ { "path": "/api/v1/obligations", "enforced": false }, ... ]
    },
    "registers": { "corrections": { ... }, "graph_snapshots": { ... }, "changelog": { ... } }
  }
}

GET/changelog.json

De releasehistorie, nieuwste eerst. Per uitgave staat er welke van de drie tellers bewoog: de inhoud, de vorm van die inhoud, of het oppervlak van de API eromheen. Een release die alleen het oppervlak verbreedde, raakte geen enkele citatie, en dan hoeft u niets na te lopen. Waar beide kanten een vastgelegde momentopname hebben, staat er een link naar de vergelijking per object; waar die ontbreekt, staat de reden erbij in plaats van een lege plek.

Parameters

Geen parameters.

Aanroep
curl -s "https://www.praxikon.com/changelog.json"
Respons (ingekort)
{
  "changelog_id": "praxikon:sys:registry:register:dataset-releases",
  "changelog_format_version": "1.0.0",
  "register_started_at": "2026-08-08",
  "current": { "dataset_version": "2.1.0", "schema_version": "1.4.0", "openapi_version": "1.11.0-beta.1" },
  "coverage": {
    "recorded_releases": 3,
    "recorded_dataset_versions": ["1.1.0", "2.0.0", "2.1.0"],
    "limits": [ { "code": "content_releases_without_a_snapshot", "detail": { "nl": "...", "en": "..." } } ]
  },
  "releases": [
    {
      "release_id": "praxikon:sys:registry:release:2026-08-13-ruling-register",
      "sequence": 9,
      "released_at": "2026-08-13",
      "dataset_version": "2.1.0",
      "schema_version": "1.4.0",
      "moved": ["api_surface"],
      "headline": { "en": "What we know a provision means" },
      "summary": { "en": "..." }
    }
  ]
}

Fouten en limieten

De vorm van een fout

Elk publiek v1-endpoint geeft een fout terug als een object met een machineleesbare code, een leesbare toelichting en een verwijzing naar het contract. Eén vorm, ook op de POST-endpoints, zodat u er één keer op hoeft te programmeren.

Code
{
  "error": {
    "code": "invalid_lang",
    "detail": "Invalid graph request: invalid_lang",
    "documentation": "https://www.praxikon.com/api/v1/openapi"
  }
}

Foutcodes

400
invalid_lang
lang was niet "nl" of "en".
400
invalid_format
format was niet "json" of "jsonld".
400
unsupported_format
Er is om een projectie gevraagd die dit endpoint niet kent. De statusopgave bestaat alleen als JSON.
400
invalid_type
type stond niet in de lijst met objecttypen.
400
invalid_limit
limit was geen geheel getal van 1 tot en met 50.
400
missing_q
De zoekopdracht of de vraag kwam zonder q binnen.
400
invalid_effective_at, invalid_known_at
De datum was niet te lezen als ISO-datum of timestamp.
400
id_too_long, role_too_long, topic_too_long
De filterwaarde was langer dan toegestaan (200 tekens voor id, 128 voor role en topic).
400
invalid_json
De body van een POST-endpoint bevatte geen geldige JSON.
400
invalid_request
De body droeg een veld dat het endpoint niet kent. De melding noemt welke velden er wel in mogen.
400
invalid_profile, invalid_manifest_request
Het profiel bevatte een onbekende, ontbrekende of tegenstrijdige antwoordcode. De manifestvariant noemt de velden erbij en geeft nooit een half manifest.
400
invalid_previous_snapshot
Het meegestuurde eerdere dossier kwam niet door zijn integriteitscontrole.
400
missing_manifest
De impactvraag kwam zonder manifest-veld binnen. Een kaal manifest als body wordt geweigerd, zodat een vraag nooit met een document kan worden verward.
400
invalid_manifest
Het meegestuurde manifest haalt het gepubliceerde schema niet. De bevindingen komen mee; er wordt niets half beoordeeld.
400
invalid_reference_point, conflicting_reference_points, incomplete_reference_points
Het venster klopte niet: een onbekend veld, twee soorten ijkpunten tegelijk, of een half paar. Een niet-gepinde vergelijking is niet reproduceerbaar.
400
unknown_from_dataset_version, unknown_to_dataset_version
Van die release is geen momentopname vastgelegd, dus die kant van het venster valt niet te reconstrueren. De melding noemt welke releases wel zijn vastgelegd.
400
invalid_max_objects
max_objects was geen geheel getal van 1 tot en met 200.
413
payload_too_large
De body van een POST-endpoint was groter dan 128 KiB.
429
rate_limited
Een van de twee begrensde endpoints kreeg te veel verzoeken. Retry-After staat in seconden in de header.

Verzoeklimieten

Twee endpoints hebben een limiet die echt wordt afgedwongen. Daarboven volgt 429 met een Retry-After-header in seconden en hetzelfde foutobject als hierboven, met code rate_limited. De lijst hieronder komt uit dezelfde tabel die de routes afdwingen en die GET /api/v1/status uitserveert, dus zij kan niet iets anders beweren dan er gebeurt.

Afgedwongen

/api/v1/answer
60 verzoeken per 60 seconden per client-adres, per serverproces
/api/v1/enforcement
60 verzoeken per 60 seconden per client-adres, per serverproces
/api/v1/naleving-index
60 verzoeken per 60 seconden per client-adres, per serverproces

Vandaag zonder limiet

/api/v1/obligations, /api/v1/changes, /api/v1/entities, /api/v1/search, /api/v1/corrections, /api/v1/diff, /api/v1/dataset, /api/v1/openapi, /api/v1/status, /api/v1/implementation-map, /api/v1/manifest, /api/v1/manifest/validate, /api/v1/impact

Op de rest is vandaag geen limiet actief. Dat is een beschrijving en geen toezegging: als het verkeer erom vraagt komt er een limiet, en die wordt in het OpenAPI-document aangekondigd voordat zij gaat gelden. Andersom is "zonder limiet" ook geen quotum waarop u kunt sturen. De teller die er wel is, leeft in het geheugen van één serverproces en begint bij een herstart opnieuw: hij remt een losgeslagen script af en garandeert niemand iets.

Code
HTTP/1.1 429 Too Many Requests
Retry-After: 60

{
  "error": {
    "code": "rate_limited",
    "detail": "This endpoint accepts 60 requests per 60 seconds per client address on one server instance. ...",
    "documentation": "https://www.praxikon.com/api/v1/openapi"
  }
}

Caching

De graph-endpoints sturen een ETag over de payload, een Last-Modified gelijk aan de laatste releasecontrole, en Cache-Control: public, max-age=300, s-maxage=3600, stale-while-revalidate=86400. Stuur de ETag terug in If-None-Match en u krijgt 304. De implementatiekaart, de twee manifest-endpoints en de impactvraag doen het omgekeerde en antwoorden met no-store, omdat er niets bewaard hoort te blijven.

De documenten eronder

Zes documenten in de repository leggen vast wat deze API doet, wat het agentoppervlak erbovenop doet, en wat er niet zomaar mag veranderen. Zij zijn nog niet op een publieke URL gepubliceerd; wie de repository heeft, leest ze daar.

docs-public/ONTOLOGY.md
De objecttypen van de graph: waar elk type voor is, welke velden verplicht zijn, hoe de identifier eruitziet, hoe versies en hashes werken, en welke relaties een type draagt.
docs-public/LEGAL-MODEL.md
De relatiepreciezie (wie draagt de plicht, wie wordt geraakt, wie levert wat aan wie) en onzekerheid als status: nooit een percentage, altijd een status met een voorgeschreven volgende stap.
docs-public/VERSIONING.md
Het stabiliteitscontract: identifierbeleid, semver-regels, de twee tijdassen, deprecatietermijnen en het citatieformaat. Waar dit document en de ontologie elkaar raken, gaat dit document voor.
docs-public/IMPACT-FEED.md
Wat de impactvraag wel en niet beweert: de drie statussen, de gronden waarop een gewijzigd object een dossier bereikt, en de vorm en ondertekening van een gebeurtenis.
docs-public/MCP.md
Het agentoppervlak: welke tools de MCP-server aanbiedt, wat elke tool belooft over zijn uitvoer, hoe u hem installeert en wat er getest wordt. De HTTP-API blijft het contract; die laag voegt geen data en geen regels toe.
docs-public/AGENT-CONFORMANCE.md
De keten van zeven vragen die een agent kan stellen, en de conformiteitsproef die vaststelt dat de antwoorden op elkaar aansluiten.

Het Regulatory Manifest

Het manifest is de draagbare projectie van één beoordeling: welke plichten zijn aangewezen, waarop dat rust, wat er nog open staat, en tegen welke datasetversie en bronvingerafdrukken dat is berekend. Het is bedoeld om te overhandigen: aan een toezichthouder, een auditor, een klant of uw eigen archief. Twee identieke invoeren geven hetzelfde manifest_id, want dat id is de eerste 24 tekens van de payload-hash.

Het schema is normatief en staat in schemas/regulatory-manifest-v1.schema.json (JSON Schema draft 2020-12), met een JSON-LD-context ernaast in schemas/regulatory-manifest-v1.context.jsonld. De TypeScript-spiegel is lib/manifest/types.ts en mag daar niet van afwijken. Genereren gebeurt met generateRegulatoryManifest uit lib/manifest/generate.ts, valideren met lib/manifest/validate.ts, en npm run test:manifest bewaakt beide.

Drie endpoints, allemaal stateloos

POST /api/v1/manifest neemt de systeembeschrijving aan en geeft een volledig manifest terug. POST /api/v1/manifest/validate toetst een manifest dat u al heeft aan het schema en geeft leesbare fouten terug. POST /api/v1/impact zegt of wat er sindsdien in de kennislaag bewoog dit dossier raakt. Er wordt niets bewaard: geen account, geen abonnement, geen serverkopie van uw antwoorden en geen manier om dit manifest later op te halen, dus bewaar het zelf. Geeft u assessed_at mee, dan is het antwoord byte voor byte herhaalbaar tegen dezelfde datasetversie. Met format=jsonld krijgt u hetzelfde document onder de gepubliceerde context op /schemas/regulatory-manifest-v1.context.jsonld.

Voorbeeldmanifest (ingekort)

Onderstaand manifest komt uit het geval dat ook in tests/manifest/regulatory-manifest.test.cjs staat: een gebruiksverantwoordelijke die sollicitanten rangschikt, oftewel Bijlage III punt 4(a).

Code
{
  "manifest_id": "praxikon:sys:assessment:manifest:825b9fec37d73d1f4def230d",
  "manifest_version": "1.1.0",
  "manifest_engine_version": "1.0.0",
  "decision_engine_version": "1.0.0",
  "system_version": "4.2.0",
  "language": "nl",
  "assessed_at": "2026-08-12T09:00:00.000Z",
  "effective_at": "2026-08-08T00:00:00.000Z",
  "known_at": "2026-08-14T00:00:00.000Z",
  "roles": ["praxikon:eu:ai-act:actor:deployer"],
  "intended_purpose": {
    "description": "Sollicitanten rangschikken in de eerste selectieronde.",
    "annex_iii_domain": "employment",
    "annex_iii_use_case": "emp-4a"
  },
  "eu_nexus": "offered_or_used_in_eu",
  "classification": {
    "result": "high_risk_annex_iii",
    "basis": [
      {
        "rule_id": "annex-iii.listed-purpose",
        "outcome": "met",
        "explanation": "Het bedoelde doel moet aan een concrete usecase in Bijlage III worden gekoppeld. Alleen een sector of domein kiezen is niet genoeg.",
        "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk"
      },
      {
        "rule_id": "annex-iii.article-6-3-filter",
        "outcome": "not_met",
        "explanation": "Artikel 6 lid 3 kan alleen via een gedocumenteerde, strikte toets uitkomst bieden. Profiling houdt het systeem hoog-risico.",
        "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk"
      }
    ],
    "open_questions": [],
    "reassessment_triggers": [
      {
        "kind": "control",
        "id": "praxikon:eu:ai-act:control:annex-iii-change-trigger",
        "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk",
        "label": "Herclassificatie bij doel- of contextwijziging",
        "at": null
      },
      {
        "kind": "deadline",
        "id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk",
        "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk",
        "label": "Bijlage III: hoog-risico AI",
        "at": "2027-12-02T00:00:00.000Z"
      }
    ]
  },
  "evaluated_obligation_ids": [
    "praxikon:eu:ai-act:obligation:annex-iii-high-risk",
    "praxikon:eu:ai-act:obligation:article-27-fria",
    "praxikon:eu:ai-act:obligation:article-4-ai-literacy",
    "praxikon:eu:ai-act:obligation:article-50-transparency",
    "praxikon:eu:ai-act:obligation:article-53-gpai"
  ],
  "obligations": [
    {
      "obligation_id": "praxikon:eu:ai-act:obligation:annex-iii-high-risk",
      "slug": "annex-iii-high-risk",
      "applicability": "applies",
      "uncertainty_status": "determined",
      "timing": "future",
      "effective_on": "2027-12-02T00:00:00.000Z",
      "deadline_at": "2027-12-02T00:00:00.000Z",
      "legal_status": "upcoming",
      "blocking_flags": [],
      "human_page": "https://www.praxikon.com/nl/verplichtingen/annex-iii-high-risk",
      "entity_version": "1.0.0",
      "entity_payload_hash_sha256": "c0afd1789ed393ba3f9ce04205bd74b4831ff0fd58146108fdd8dd08d2f4f6c9"
    }
  ],
  "required_actions": [ ... ],
  "required_evidence": [ ... ],
  "uncertainty_status": "determined",
  "assessment_input": { ... },
  "derived_from": {
    "snapshot_id": "praxikon:sys:assessment:implementation-snapshot:...",
    "snapshot_payload_hash_sha256": "..."
  },
  "source_snapshot": {
    "dataset_id": "praxikon:sys:registry:dataset:ai-act-implementation-graph",
    "dataset_version": "2.1.0",
    "schema_version": "1.4.0",
    "last_reviewed_at": "2026-08-08T00:00:00.000Z",
    "source_fingerprint_basis": "canonical_url|source_version|verified_at",
    "source_fingerprint_scope": "De bronhash dekt onze registratie van de bron (URL, uitgaveversie, controledatum) en is geen archiefkopie of inhoudshash van het externe document.",
    "source_hashes": [
      {
        "source_id": "praxikon:eu:ai-act:source:reg-eu-2024-1689",
        "source_version": "original-oj-2024-07-12",
        "verified_at": "2026-08-14T00:00:00.000Z",
        "source_record_hash_sha256": "bf0fca3e..."
      }
    ]
  },
  "payload_hash_sha256": "825b9fec37d73d1f4def230d0d8d807d9eb17c7801cc0ea2d996d56ca0803824"
}

MCP-server

De REST-API is machineleesbaar, maar stelt zich niet voor: een agent moet zelf weten dat /api/v1/answer bestaat en welke parameters die kent. De MCP-server draait dat om. De agent vraagt eenmalig tools/list en krijgt getypeerde tools terug: elk met een beschrijving die zegt wanneer je hem pakt, een JSON Schema voor de invoer en een JSON Schema voor de uitvoer. Het protocol is JSON-RPC 2.0 over stdin en stdout, de server heeft geen afhankelijkheden en raakt alleen publieke endpoints. Alles is alleen-lezen en er zijn geen credentials nodig.

Wat dit bewust niet is: een gespreksvenster op de AI Act. Er zit geen taalmodel in en er wordt niets geformuleerd. Elke tool is een dunne projectie van een of twee gepubliceerde endpoints, en een afleiding die de API al doet wordt hier niet nog eens nagebouwd, want dan ontstaat er een tweede waarheid die stil uit elkaar kan lopen. Elke uitvoer draagt drie vaste blokken: provenance met elke backend-aanroep en zijn status, pin met de release en de twee tijdassen, en op elk graph-object een citation met identifier, versie en payload-hash. Foutieve invoer strandt op het schema voordat er een verzoek uitgaat; een fout van de API reist door met haar eigen code.

Het verschil met een model dat gokt

explain_applicability geeft niet alleen een uitkomst maar het juridische pad: de voorwaarden waaronder de regel over een situatie gaat, de uitzonderingen waaronder hij er weer uit valt, en per officieel feit de bron, de vindplaats daarbinnen en het bronrecord erachter. Geeft u een profiel mee, dan komt de rule trace van de beslismotor erbij: welke regel is voldaan, niet voldaan of onbekend. Beoordeelt de motor die plicht niet, dan komt er geen oordeel en staat de reden erbij, want een leeg veld leest als "er geldt niets".

Tools

Een systeem beoordelen

classify_system
Welke routes van de verordening in beeld komen voor een concreet systeem.
get_applicable_obligations
De aangewezen plichten zelf, met status, timing en de redenen van de motor.
explain_applicability
Het juridische pad: voorwaarde, uitzondering, bron en vindplaats, plus de rule trace bij een profiel.
get_required_actions
Wat er gedaan moet worden, uit de graphrelaties of uit de beoordeling.
get_required_evidence
Wat vastgelegd en overlegbaar moet zijn.
get_source_provenance
Statements met soort, bron, vindplaats en het bronrecord erachter.

Het draagbare dossier

create_regulatory_manifest
Het Regulatory Manifest voor een beoordeeld systeem.
validate_manifest
Een manifest dat u al heeft toetsen aan het gepubliceerde schema.
get_regulatory_diff
Wat er tussen twee ijkpunten bewoog, per object en per veld.
analyse_change_impact
Of wat er in de kennislaag bewoog dit dossier raakt.

De graph lezen

get_obligations
De catalogus van plichten, te filteren op rol, plichtdrager of onderwerp.
get_graph_entities
Entiteiten per type: guidance, standard, example, action, definition, actor.
search_implementation_graph
Zoeken als nog niet duidelijk is welk object relevant is.
list_regulatory_changes
Tijdlijn: wat ging wanneer gelden, wat verschoof.
get_national_enforcement
Toezichthouder, uitvoeringswet, signalen en opgenomen uitspraken per lidstaat.
list_corrections
Wat wij fout hadden en hebben hersteld, met de geraakte identifiers.
answer_ai_act_question
Deterministische opzoeking van een herkend praktijkscenario.
get_dataset_status
Welke release wordt uitgeserveerd, en waar die eerlijk over is.
Registreren
claude mcp add praxikon -- node /path/to/EUAIACT/mcp/praxikon-mcp.mjs
Of via een JSON-configuratie
{
  "mcpServers": {
    "praxikon": {
      "command": "node",
      "args": ["/path/to/EUAIACT/mcp/praxikon-mcp.mjs"]
    }
  }
}
Tegen een lokale build
PRAXIKON_API=http://localhost:3031 node mcp/praxikon-mcp.mjs
Handmatig testen zonder client
printf '%s\n%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | node mcp/praxikon-mcp.mjs

De server spreekt de protocolversies 2025-06-18, 2025-03-26 en 2024-11-05, en antwoordt zowel met structuredContent als met hetzelfde object als tekstblok, zodat een oudere client niets mist. Het serverbestand is mcp/praxikon-mcp.mjs, het volledige contract staat in docs-public/MCP.md, en npm run test:mcp draait de echte server tegen de routehandlers uit deze repository.

Waar dit op uitkomt

De belofte is smal en daarom houdbaar: dezelfde vraag op dezelfde release geeft hetzelfde antwoord, elk antwoord wijst naar zijn officiële bron, en wat verandert krijgt een nieuwe versie in plaats van een stille overschrijving. Dit blijft algemene duiding en geen juridisch advies; de officiële bron gaat voor op onze samenvatting.