---
title: "Case Search"
method: GET
path: "/v1/case-search"
---

# Case Search

`GET /v1/case-search`

## Request

- Base URL: `https://recht.nulegal.eu` (the document declares no server; this is the origin it was published from)
- URL: `https://recht.nulegal.eu/v1/case-search`
- Auth: none declared

Semantic case-law search (product integration): natural-language
question in, decisions out — same hybrid pipeline as the /suche
Rechtsprechung tab (dense-first for NL questions, FTS-first for keywords).
Dense hits carry the best-matching Randnummer + snippet.

**Filters and ordering** (agent-sim 15.09.2026 — all three existed on `/suche` and
none of them on this endpoint, and `&land=SN` was answered with a byte-identical
unfiltered list rather than an error):

  land   a Bundesland: the hub slug (`sachsen`) or its code (`SN`), plus `bund`
         and `eu`. Narrows to the courts of that Land, the same expansion
         `/suche?land=` makes.
  court  one court, by the slug its pages use (`ovg-sachsen`, `bgh`, `olg-koeln`).
         ANDs with `land`; a combination no court satisfies returns an empty list,
         which is a true answer and not a dropped filter.
  sort   `relevance` (default, the hybrid ranking) or `date_desc`, newest first.
         `date_desc` runs the lexical leg only — there is no dense/rerank pass to
         re-order — and it answers "aktuelle Rechtsprechung zu X", which relevance
         ranking could not: the simulated query for recent Befristung case law led
         with decisions from 2003 and 2004.

An unknown parameter, an unknown Land or an unknown court slug is a **400** naming
the valid values. A filter that is silently ignored produces a well-formed,
plausible, wrong answer, which is the worst failure shape this API can have.

If the date sort cannot be computed inside its budget the response falls back to
relevance and SAYS SO in `ranking.sort` — it never serves a relevance list under a
label that claims recency. `ranking.sort` appears only when an ordering was asked
for: a default request is byte-identical to what it was before the parameter
existed.

**`doknr` on every row** ( item 5). Purely additive — no field is removed
or renamed. A row used to be reachable only by its `url`, so a caller chaining
search into `/v1/case` had to parse our URL back into a key; `doknr` is that key
directly. Null where the leg that produced the row cannot supply one, never
invented.

## Query parameters

- `q` string, required
- `limit` integer
- `land` string
- `court` string
- `sort` string

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/nulegal/apis/nu-legal-deutsches-recht-api.md) · [All operations](https://skmtc.dev/nulegal/apis/nu-legal-deutsches-recht-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nulegal/apis/nu-legal-deutsches-recht-api/revisions/b4695d8006b1?raw)
