nu:legal Deutsches Recht
德國法律供代理使用:聯邦與各州法規,以及 640,000 份附引註的法院判決。免金鑰、唯讀。
託管 MCP 伺服器
npx add-mcp 'https://recht.nulegal.eu/v1/mcp'可安裝到 Claude Code、Codex、Cursor 等客戶端
文件
Quick start
Every endpoint is a plain GET that returns JSON. Try it in your terminal:
curl "https://recht.nulegal.eu/v1/search?q=k%C3%BCndigung&limit=3"
Basics
| Base URL | https://recht.nulegal.eu |
|---|---|
| Auth | None. No key or token required. |
| Format | JSON (UTF-8). Query strings must be URL-encoded. |
| CORS | Open (*) for GET, POST, OPTIONS. Call it directly from the browser. |
| Caching | Responses send Cache-Control: public, max-age=3600. Please cache on your side. Every /v1 GET also carries a weak ETag over its content: send it back as If-None-Match and an unchanged response costs a 304 with no body, which is how to re-check a daily-updated corpus cheaply. There is deliberately no Last-Modified — half the stored version dates are the original import date rather than a date anything changed, so a timestamp validator here would be wrong. |
| Personal data | Not permitted. Do not include names, case facts or other personal data in queries or request bodies, including /v1/resolve. Requests are logged. See the Terms of Use. |
Full-text search
GET/v1/search
Search across all federal statutes. Ranks by relevance, pins curated matches for common terms and returns a plain-text snippet for each hit.
| Parameter | Type | Description |
|---|---|---|
q | string, required | Search term. Minimum 2 characters. Accepts a keyword (kündigung), a citation (§ 823 BGB) or a natural-language question. |
limit | integer | Number of results, 1 to 100. Default 20. |
repealed | boolean | Include norms of repealed statutes, matched against their last known text. Default false: search returns law in force. Results are additive — everything the default search returns is still there, ranked among the repealed matches. Repealed provisions stay addressable at their own URL regardless of this parameter, and /v1/norm resolves them (and ?asof= versions) unconditionally. |
m | string | Search mode: auto (default), fast or deep. |
This endpoint searches statutes. Decisions are at /v1/case-search — and every response says how many of them match the same query: cases_available (a capped count; null means it could not be measured, which is not zero) and cases_url, the call that returns them. A term of art such as Verzugspauschale can return no statute at all and still have hundreds of decisions behind it, because the word is in the case law and not in the statute’s own text. An empty results additionally carries suggestions.
An unknown query parameter is a 400 here and on /v1/case-search, with the valid parameter names in the body. A filter that is silently ignored returns a well-formed, plausible, wrong answer.
Example
curl "https://recht.nulegal.eu/v1/search?q=k%C3%BCndigung&limit=2"
const r = await fetch(
"https://recht.nulegal.eu/v1/search?q=" + encodeURIComponent("kündigung") + "&limit=2"
);
const { results } = await r.json();
console.log(results[0].ref, results[0].jurabk, results[0].url);
{
"query": "kündigung",
"results": [
{
"jurabk": "KSchG",
"slug": "kschg",
"ref": "§ 1",
"ref_norm": "1",
"heading": "Sozial ungerechtfertigte Kündigungen",
"rank": 0.48,
"snippet": "Kündigung des Arbeitsverhältnisses gegenüber einem …",
"law_url": "KSchG",
"url": "https://recht.nulegal.eu/gesetze/KSchG/1"
}
]
}
jurabk ist der Schlüssel, mit dem /v1/law/{abbrev} und /v1/norm/{abbrev}/{ref} arbeiten; er bleibt unverändert. Wo dieser Schlüssel nicht die Zitierform ist, liefert die Antwort zusätzlich display_abk: die Bezeichnung, die auch auf den Seiten dieser Site steht. Das betrifft zwei Fälle: Fundstellennachweis-Kennungen des Bundesrechts ("jurabk": "AO 1977" → "display_abk": "AO", "SGB 2" → "SGB II") und 144 Dokumente des Landesrechts Brandenburg, für die keine Abkürzung vorliegt; der Schlüssel ist dann eine interne Kennung ("jurabk": "VT-ID242586" → "display_abk": "Vertrag zwischen dem Heiligen Stuhl und dem Land Brandenburg"). Das Feld fehlt, wenn beide gleich wären, bei den meisten Treffern also. Für Anzeigezwecke: r.display_abk ?? r.jurabk.
Curated pages
Some questions no single statute answers. “Wie viel Schmerzensgeld nach einem Unfall?” is one: § 253 BGB grants a “billige Entschädigung in Geld” and names no amount. For those queries the response carries an extra pages array next to results — curated pages on this site that do answer the question, each with the figures it shows, so you can answer without a second request. results is unaffected, and pages is absent for the vast majority of queries, so existing clients need no change. Every entry carries "type": "page", which is how you tell one apart from a norm hit if you merge the two lists.
{
"query": "schmerzensgeld nach unfall wie viel",
"results": [ … ],
"pages": [
{
"type": "page",
"kind": "schmerzensgeldtabelle",
"title": "Schmerzensgeldtabelle: Verkehrsunfall",
"url": "https://recht.nulegal.eu/schmerzensgeldtabelle?kontext=verkehrsunfall",
"description": "199 Entscheidungen deutscher Gerichte mit zugesprochenem Schmerzensgeld (Verkehrsunfall): Median 4.500 €, Spanne …",
"stats": { "n": 199, "median_eur": 4500.0, "min_eur": 100.0, "max_eur": 500000.0 },
"updated": "2026-07-27"
}
]
}
| Field | Type | Description |
|---|---|---|
type | string | Always page. |
kind | string | Stable identifier of the page family, e.g. schmerzensgeldtabelle. New kinds may be added over time; treat an unknown kind as a generic page. |
title | string | Display title, German, including the selected facet. |
url | string | Absolute URL, same convention as results[].url. |
description | string | One paragraph answering the query, with the figures the page shows. |
stats | object, optional | Machine-readable version of those figures. Keys depend on kind. |
updated | string, optional | ISO date the underlying data was last built. |
The same match drives the hint shown above the results on /suche, so the website and the API never disagree about which page answers a query.
Case-law search
GET/v1/case-search
Semantic search over court decisions. A natural-language question in, decisions out. Hits carry the best-matching paragraph number (rn) and a snippet.
| Parameter | Type | Description |
|---|---|---|
q | string, required | Question or keyword. Minimum 2 characters. |
limit | integer | Number of results, 1 to 20. Default 10. |
land | string | Narrow to the courts of one Bundesland: the hub slug (sachsen) or its code (SN), plus bund and eu. An unknown value is a 400 listing the valid ones, never a silently unfiltered list. |
court | string | Narrow to one court, by the slug its decision pages use (bgh, bverwg, olg-koeln, ovg-sachsen). Combines with land; a combination no court satisfies returns an empty list, which is a true answer. |
sort | string | relevance (default) or date_desc, newest first — the ordering that answers “recent case law on X”. If the date sort cannot be computed inside its time budget the response falls back to relevance and says so in ranking.sort. |
deep_force | flag | Set deep_force=1 to request the LLM re-ranking pass even when your traffic is classified as automated. The response's ranking.llm_rerank field says what happened: attempted (the extra LLM pass ran over the candidate pool), skipped-nonhuman-traffic or rate-capped; the field is absent when the query shape (short keyword, exact docket) never makes re-ranking applicable. |
Example
curl "https://recht.nulegal.eu/v1/case-search?q=wann%20darf%20mein%20chef%20mir%20k%C3%BCndigen&limit=2"
{
"query": "wann darf mein chef mir kündigen",
"results": [
{
"court": "BAG",
"decided": "2011-11-24",
"aktenzeichen": "2 AZR 429/10",
"doktyp": "Urteil",
"rn": null,
"snippet": "Kündigung noch nach Fristablauf wirksam …",
"source": "rii",
"url": "https://recht.nulegal.eu/rechtsprechung/bag/2011-11-24/2-azr-429-10"
}
]
}
When a result comes from an Open-Database-Licence source, the response adds an attribution array. If present, show it alongside the results.
More endpoints
The same API also resolves single norms and citations:
| Endpoint | Description |
|---|---|
GET /v1/norm/{law}/{ref} | One norm with full text and version metadata. Optional ?asof=YYYY-MM-DD for a historical version. |
GET /v1/preview/{law}/{ref} | One norm as a short snippet. Powers the citation badge preview. |
GET /v1/law/{law} | A law with its table of norms. |
GET /v1/case/{doknr|ecli} | One decision by juris document number or ECLI, with its cited norms. Add ?paragraphs=1 for the decision's Randnummern as data (see below). |
GET /v1/case?doknr= | The same decision, addressed by query parameter. Use this form for the 54.271 document numbers that contain a slash — every BGH, BPatG and NRWE doknr does (BGH-Zivilsenate/XI_ZS/2001/XI_ZR_338-01A). |
GET /v1/norm/{law}/{ref}/citing-cases | Decisions that cite a given norm, most significant first — every court, not only the Bundesgerichte. limit 1–100 (default 10) and offset page through the full total. The citation index links decisions to federal and EU provisions only, so a Land statute answers total: 0 with a coverage block naming the Land and pointing at the case search: “not linked”, never “not cited”. |
GET /v1/states | Coverage per German state (Land) as numbers: statutes and decisions held, whether the statutes are held in full text, and the binding gazette for the Länder where they are. Rows are under states; laender, fulltext_laender and each row’s land repeat states, fulltext_states and state and are deprecated. |
GET /v1/topics | The topic axis with each topic’s decision count and the URL of its hub. Rows are under topics; themen repeats them and is deprecated. |
GET /v1/stats | Corpus totals from the nightly snapshot: laws, norms, versions, decisions, courts, decision_to_norm_citations, decision_to_decision_citations, sources, years and the published ISO weeks, dated by as_of and built_at; missing_case_numbers (total, linked, with_fulltext) once computed. The German keys (stand, erstellt, gesetze, normen, fassungen, entscheidungen, gerichte, verweise_entscheidung_norm, verweise_entscheidung_entscheidung, quellen, jahre, wochen, vermisste_aktenzeichen) repeat the same values and are deprecated. |
GET /v1/stats/week/{iso} | One ISO week (2026-W30): week, week_start, week_end, built_at, new_decisions, backfilled_decisions, median_lag_days, then the week’s tables. woche, von, bis, erstellt, neu, altbestand_eingespielt and median_verzug_tage repeat the same values and are deprecated. |
POST /v1/report-missing | API key required. Report a decision that is real but not held here: aktenzeichen and source, optionally court, decided, evidence_urls (up to 10) and context. Answers accepted or duplicate, once per Aktenzeichen and source. The German field names (gericht, datum, beleg_urls, quelle, kontext) are still accepted and deprecated; if a body sends both spellings, the English one wins, even when its value is null. |
GET /v1/suggest?q= | Typeahead suggestions for laws and norms. |
POST /v1/resolve | Resolve up to 100 raw citation strings — norms and decisions (Aktenzeichen, ECLI, BVerfGE-Fundstelle). Each result carries citation_kind and one of resolved / ambiguous / attested / unknown / unsupported; a docket several decisions share comes back ambiguous with every candidate named, never one of them picked. A miss carries a machine-readable reason and a sentence saying why. attested is a miss with evidence: we do not hold that Aktenzeichen, and at least two decisions we do hold cite it, so the decision is real and its full text is what is missing — citers, court_hint, decided_hint and up to five citing decisions in attested_by come with it. See below for how much text a result carries. A full citation as a model writes one — BVerwG, Urteil vom 24.10.2023 – 2 C 9.22 — is read end to end: the court and date in front of the docket are parsed, the date disambiguates a docket several decisions share, and a disagreement comes back as citation_check (date_matches, court_matches, the decision’s actual date) rather than as a rejection. A citation with a real docket and a wrong date therefore gets corrected instead of refused. |
POST /v1/linkify | Send html (a fragment) or text; get the same content back with the citations it holds linked to their pages here, and nothing else changed. The contract, the rate limit and the embed script are documented in German at /vernetzung. |
How much text a resolve result carries
POST /v1/resolve truncates by default. A resolved norm’s text is the first 300 characters of the whole provision, cut on a word boundary and ending in …, and it is the same 300 characters whichever subsection you cited. A resolved decision’s preview is 300 characters of its Leitsatz. text_truncated says which you got. Do not verify a quotation against a truncated field. Three ways to get the real text:
| Field or parameter | What it gives you |
|---|---|
sub_text | Automatic, no opt-in. When the citation names an Absatz, the full text of exactly those Absätze, never truncated: {"abs": ["1","3"], "text": "(1) … (3) …"}. null when no Absatz was cited or the provision is not Absatz-numbered — never a guess about where a subsection starts. |
"include": ["text"] | Request field. The norm’s whole text in text instead of the stub; text_truncated becomes false. |
"include": ["leitsatz"] | Request field. A decision’s whole Leitsatz in a new leitsatz field. preview is unchanged next to it. null where the decision carries no Leitsatz — which is also when preview is showing the head of the text instead. |
Both include values are off by default, so a request that does not send the field gets exactly the payload it always got. An unknown value is a 422, not a silent no-op.
Citations with more than one subsection
A citation may name several subsections, a range of them, or several paragraphs sharing one law name — § 1374 Abs. 1 und 3 BGB, § 1376 Abs. 1–3 BGB, § 543 Abs. 1, Abs. 2 Satz 1 Nr. 1 und Abs. 3 BGB, §§ 4, 7 KSchG. All of these resolve, and two fields carry what was written:
| Field | Description |
|---|---|
sub | Unchanged. The flat form: abs, satz, nr, lit, one value each — the first, where the citation named several. |
subdivisions | The chain as written, in order, values as lists: [{"key":"abs","values":["1","3"]}]. Order matters — it is the only record of which Satz belongs to which Absatz. A written range is expanded to its members. Keys: abs, satz, nr, ziff, lit, halbs, alt, var, uabs, teil, anlage, anhang, abschnitt. |
norms + enumeration | On an enumeration (§§ 4, 7 KSchG): every member, each with its own sub_text. The top-level result stays the first member, so nothing you already read changes. A member the corpus does not hold is named in enumeration.unresolved rather than dropped. |
A §§ -range (§§ 305–310 BGB) keeps its existing shape: range plus every norm in between under norms.
curl -s -X POST "https://recht.nulegal.eu/v1/resolve" \
-H "content-type: application/json" \
-d '{"citations": ["§ 1374 Abs. 1 und 3 BGB", "ECLI:DE:BGH:2013:201113UXIIZR77.12.0"],
"include": ["leitsatz"]}'
A repealed statute, or a provision that was removed from one, has no text in force. /v1/norm, /v1/preview and /v1/resolve then answer with the last known text rather than an empty one, and label it: status is repealed or in_force (the law's own status, as /v1/law reports it), text_status is current or historical, and version.valid_to carries the date the text stopped being observed. Treat text_status: "historical" as "this is not the law in force today". ?asof= is unaffected: a date after the repeal still answers a 404, because nothing applied then.
An interactive reference with every parameter is at /docs (OpenAPI).
Citation check (preview)
Not yet enabled in production. This endpoint is built and tested but switched off on the live service; it is documented here so that anyone building against the API can see the contract before it goes live. It is the first operation of the agent API, a paid, keyed surface that is planned. Everything above it on this page stays free and unchanged.
| Endpoint | Description |
|---|---|
POST /agent/v1/quote/verify | Send a statement (the sentence that cites) and a citation (a norm citation, an Aktenzeichen, an ECLI, a Fundstelle). Get back supported, not_supported, not_found or undetermined, plus the passage it was decided on. Optional question adds a relevant verdict about the user's own question. |
Two layers answer it. An exact or near-exact quotation is settled by string matching, with no model involved — that answer carries basis: "containment". A paraphrase is settled by a verifier model reading the resolved source text, and carries basis: "model". The string-match verdict is reported either way under containment (verbatim / near / absent).
A citation with a subdivision is read as written: § 823 Abs. 2 BGB is verified against Absatz 2 and nothing else, and a subdivision the norm does not have answers not_found rather than a verdict about a different Absatz.
undetermined is a real answer and needs handling: it means the check could not be completed — not that the statement is unsupported. reason says which (model_rate_capped, model_unavailable, model_declined_source, source_text_unavailable, source_incomplete, historical_version_unsupported). Treating it as a failed check would report a correct citation as a fabrication.
Two of those are worth knowing about in advance. Some provisions are held with no text at all — a number of EU regulation articles among them — and a citation to one answers source_text_unavailable rather than a verdict about an empty string. And a citation that names another version (§ 306 BGB a.F.) is declined rather than checked against the text in force, which is a different provision: ask /v1/norm/{law}/{ref}?asof=YYYY-MM-DD for a Fassung.
curl -sX POST https://recht.nulegal.eu/agent/v1/quote/verify \
-H 'Content-Type: application/json' \
-d '{"statement":"Eine ohne Anhörung des Betriebsrats ausgesprochene Kündigung ist unwirksam.",
"citation":"§ 102 Abs. 1 BetrVG"}'
An Authorization: Bearer key is optional. Without one the call is served and graded on ordinary traffic classification; automated traffic gets the string-match answer and undetermined where a model would have been needed. Keys, quotas and pricing are not open for sign-up yet — write to kontakt@nulegal.de if you want to be told when they are.
Link to a decision (permalinks)
Want to link to a court decision from your site, newsletter or app without knowing our URLs? Build a link from what a citation already gives you — court, date, docket number (Aktenzeichen). A unique match answers with a 301 redirect to the decision page; if several decisions share the docket number you get a small picker page; if we do not have the decision you get a 404 with pointers to external sources.
| Endpoint | Description |
|---|---|
GET /finde?gericht=&datum=&az= | Resolver with three optional parts. gericht takes full names or common abbreviations (BGH, OLG Köln, VG Berlin, EuGH), any casing. datum takes 2023-06-26 or 26.06.2023. az is the docket number, any of the German or European formats. Give as much as you have — the docket number alone is often enough. Try it: a worked example. |
GET /az/{aktenzeichen} | Short form when the docket number is all you have, e.g. /az/VI ZR 496/15 or /az/C-311/18. |
GET /rechtsprechung/bverfge/{band}-{seite} | Resolve a BVerfGE citation from the court’s amtliche Sammlung: /rechtsprechung/bverfge/30-173 for BVerfGE 30, 173. The pin-cite form works too (/rechtsprechung/bverfge/30-173-177 for “BVerfGE 30, 173 (177)”) and redirects to the canonical address first. Where the Sammlung prints more than one decision at a page, the citation gets a picker page instead of a guessed redirect. |
Example
curl -I "https://recht.nulegal.eu/finde?gericht=BGH&datum=26.06.2023&az=VIa%20ZR%20335%2F21"
# HTTP/1.1 301 Moved Permanently
# location: /rechtsprechung/bgh/2023-06-26/via-zr-335-21
These are HTML endpoints meant for links, not JSON. All of them are stable: a link that resolves today keeps resolving.
Deep links to a Randnummer or Absatz
Decision pages carry a permanent anchor per printed Randnummer: append #rn-N to the decision URL. Where a decision has printed Randnummern, #rd_N also leads to that Randnummer. On texts without recognisable printed Randnummern, #rd_N counts the paragraphs of the text (see anchor_basis below). Norm pages carry one per numbered subsection (Absatz): append #abs-N to the norm URL. The page highlights the targeted passage and shows its permalink right there, ready to copy.
https://recht.nulegal.eu/rechtsprechung/bgh/2023-06-26/via-zr-335-21#rn-13
https://recht.nulegal.eu/rechtsprechung/bgh/2023-06-26/via-zr-335-21#rd_13
https://recht.nulegal.eu/gesetze/BGB/823#abs-2
Both fragment formats are permanent, under the same discipline as the resolver endpoints above. Decision texts are immutable, so a #rd_N link keeps pointing at the same passage forever. Norm texts follow the legislature: #abs-N always resolves to paragraph N of the current version, which an amendment may renumber or repeal, so cite the passage in text alongside the link where permanence matters. /v1/case-search already returns the best-matching paragraph per hit as a ready deep link in url, and its printed Randnummer in rn (null where the paragraph has none we can vouch for). The full stability promise, in German, is documented at /vernetzung.
Randnummern as data
A pinpoint citation names a paragraph — “BGH, VIII ZR 67/18 Rn. 27” — and recovering Rn. 27 from a 40.000-character text_plain by regex is how integrations end up citing the wrong one. So the endpoint hands you the paragraphs the decision page itself renders. GET /v1/case/{doknr}?paragraphs=1 adds two keys and changes nothing else; without the parameter the response is exactly what it always was.
curl "https://recht.nulegal.eu/v1/case/KORE601832026?paragraphs=1"
| Field | Meaning |
|---|---|
paragraphs[].text | The paragraph, exactly as the decision page shows it, in document order. |
paragraphs[].rn | The Randnummer the court printed for this paragraph, as a string — or null. Never inferred from position: null means this decision prints no number here, and you must not present the anchor as an “Rn.” instead. |
paragraphs[].anchor | The permalink fragment of this paragraph on the decision page (rd_27), or null where the page anchors it either. Permanent, under the promise above. |
paragraphs[].url | The permalink, already built: the decision URL plus the fragment. |
anchor_basis | native_numbering — the anchors are the printed Randnummern, so #rd_27 is Rn. 27. document_order — the anchors are our own 1-based index over the addressable paragraphs and nothing more. Measured per decision, not assumed per court. |
Read anchor_basis before citing. It is native_numbering for the juris decision-XML corpus, where both numbers come out of the same field — that is the BGH, BVerfG, BAG, BVerwG, BSG and BFH text served from rechtsprechung-im-internet.de. It is document_order elsewhere, and there the two numbers really do differ: in EuGH judgments our index runs one ahead of the printed number for the whole judgment, because the title block is a paragraph too. Where a decision prints no paragraph numbers at all — much of the older BGH text, which reaches us as extracted PDF — every rn is null and the paragraphs are still returned in document order, so you can quote a passage without being able to name a Randnummer for it.
MCP server (for agents)
The same corpus as a set of tools for an AI agent, over the Model Context Protocol. No key, no sign-up, read-only — the same access model as the JSON API above.
| Endpoint | https://recht.nulegal.eu/v1/mcp |
|---|---|
| Transport | Streamable HTTP. POST a JSON-RPC 2.0 message, get one JSON response. Stateless: no session id is issued, and there is no server-initiated SSE stream (a GET answers 405). |
| Auth | None. |
| Discovery | https://recht.nulegal.eu/.well-known/mcp.json |
Connect
Most clients take a remote MCP server as a URL. In a Claude Code or Claude Desktop configuration that is:
{
"mcpServers": {
"nulegal-recht": {
"type": "http",
"url": "https://recht.nulegal.eu/v1/mcp"
}
}
}
Or check it by hand:
curl -sX POST https://recht.nulegal.eu/v1/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Tools
| Tool | What it answers |
|---|---|
resolveIdentifiers | Ground up to 100 citations at once. Takes them in the form a model holds them — BVerwG, Urteil vom 24.10.2023 – 2 C 9.22 — and reports what it stripped. Never returns a near match. |
search | Statutes and case law in one query, each statute hit jurisdiction-labelled, with a by_jurisdiction roll-up for cross-Land comparison. |
getNorm | One provision, as Markdown by default, optionally as_of a date. |
listNormVersions | Which versions of a provision are stored, and which date is the archive floor rather than an amendment. |
listCitingDecisions | Decisions citing a provision, or citing a decision (with the citing court’s own Randnummer). |
listCitedAuthorities | The provisions and decisions one decision relies on, weighted. |
listCasePassages | A decision as numbered paragraphs, each with a permalink. |
getChanges | Provisions whose text changed recently; poll it with since. |
getCoverage | What the corpus holds — and, in the same payload, what it does not. |
What an answer does not mean
Three limits ride in the payloads rather than only in this page, because an agent reads the payload:
- Norm version dates are first-observed dates, not legal Inkrafttreten, and the version archive starts 2019-06-10. An
as_ofbefore that answersoutside_coveragewith the law’s amendment register attached — never a bare not-found, which would read as “the provision did not exist”. - The decision-to-norm citation graph is built over federal case law. A Land provision can report zero citing decisions because it is not indexed; the
coveragefield says which, and it is never left to be inferred from a0. - A decision we can prove exists but do not hold answers
known_missing, with the decisions that attest it — not a 404.not_in_corpus,outside_coverageandknown_missingare three different answers and are never collapsed into one.
A tool that ran and could not answer returns a result with isError: true and a machine-readable reason, not a JSON-RPC error — so the model sees why. The full reason vocabulary is in the discovery document, next to the list of specced operations this server deliberately does not expose and why.
Usage and fair use
- The API is free. There is no key and no hard rate limit today. Please stay reasonable and cache responses; heavy or automated bulk use may be throttled.
- Crawling, citation and use by AI assistants (including for answering queries) are expressly permitted. The only use reserved is bulk use for training AI systems (Section 44b(3) UrhG; see /license). The pages and the API are open to AI assistants: our robots.txt names the admitted AI agents and opens
/v1to them at the crawl delay it states, and /llms.txt documents the same rule for machine readers. - One condition: automated access must not present itself as a human visitor. Use an accurate user agent that identifies your operator or includes a contact route, and do not circumvent technical access restrictions. Details in the Terms of Use.
- Court decisions carry the licence of their source; where an
attributionfield is present, keep it with the data. - All texts are consolidated, non-official reading versions. The binding source is the Federal Law Gazette at recht.bund.de.
- Building something with it? We would like to hear about it: reach us via nu:legal.
Looking to embed citations on your own site instead? See the citation badge — or let Vernetzung link every legal citation in your pages automatically (API, WordPress plugin, or a one-line script tag).