API reference

v0.93.0

The REST API gives your own applications the operations of the MCP server: search, decision texts, the citation graph, datapackages and the citation check. Every endpoint is the twin of an MCP tool, with the same arguments, the same answer and the same price.

Getting started

Create an API token in Settings, API tokens. The token acts for the organization you have open when you create it, and every call is charged to that organization. It expires after 365 days unless you choose a shorter lifetime. The token is shown once. Keep it like a password, and revoke it at once if it leaks.

Open API tokens in settings

Send the token as a Bearer token with every request:

curl "https://klaracase.de/api/v1/decisions/search?query=Untreue%20Gesch%C3%A4ftsf%C3%BChrer" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Token abilities

A token does only what its abilities allow. Each endpoint names the ability it needs. A token without that ability gets a 403 with the code token_ability_missing, and nothing is charged.

  • search: search decisions, and statutes with decisions.
  • read: read decisions, corpus coverage and filter values.
  • graph: read the citation graph of a decision.
  • datapackage: assemble datapackages.
  • citation-check: check citations, upload documents and read the results.

Prices and credits

A call costs the same credits as the matching MCP tool. Each endpoint below names its price. A result your organization already paid for this month, on the API or over MCP, costs nothing more. The 30 free starter credits for new verified users apply to the API too. Every answer states its cost and the remaining balance in the field credits.

Rate limits and daily caps

Each token may make 60 requests per minute. Datapackages, citation checks and uploads have a further limit of 10 per minute. Each organization also has a daily cap, by plan, on the search rows and the full texts it receives. Above a limit you get a 429 with retry_after_seconds. Nothing was executed and nothing was charged.

PlanSearch rows and graph neighbours per dayFull texts per day
free1,00040
starter5,000200
professional20,000600
enterprise60,0002,000

Errors

Every error is an RFC 9457 problem in the format application/problem+json, with type, title, status, detail and a stable code. A 402 adds cost and balance. A 429 adds retry_after_seconds. A 422 adds errors, with the messages per argument. A 403 for a missing ability adds required_ability. If your organization requires two-factor sign-in of all members and the token's user has not set it up, every call gets a 403 with the code two_factor_required, and nothing is charged, until they set it up.

Versioning

The major version in the path, /api/v1, is the contract. Within v1 we only add: new fields, new optional parameters and new values. A removal or a change of meaning comes as /api/v2. We announce the end of an endpoint with the Deprecation and Sunset headers at least six months ahead. Every answer carries the X-Klaracase-Api-Release header with the release that served it.

OpenAPI spec (JSON)

Citation check

POST/api/v1/citation-checks
Ability: citation-checkFrom 2 credits, by length
Check the citations in a text
Verifies every court-decision and statute citation in a German legal text against the corpus and answers one verdict per citation, with offsets into your text: the REST twin of the MCP tool `check_citations`. Synchronous: the answer is the finished run. Send the text as `text`, or the `document_id` of an upload whose `status` is `ready`. Priced by length, from 2 credits; an upload's `quoted_credits` names the price before you check it. A text longer than the cap is refused before any charge, and the same text checked again this month costs nothing more.

Parameters

text
stringbody

The German legal text to verify (min 50 characters, max 20000; check longer documents in the Citation Check of the web app). The length is a floor, not the gate: the text must also show at least two of five independent legal-signal categories, so a lone statute sentence is rejected however long it is. Response offsets are Unicode codepoint offsets into THIS exact string.

reference_date
stringbody

OPTIONAL document date, ISO `YYYY-MM-DD`. It is applied to every statute citation whose own sentence names no date; a sentence that states its own date always wins. It gates the pre-reform-numbering advisory and changes no verdict. Each finding reports which date it used in `evidence.citation_date_source` (`sentence` | `reference_date` | `none`).

document_id
stringbody

The id of an upload whose `status` is `ready` (POST /citation-checks takes this or `text`, never both). The check consumes the upload.

Request

curl -X POST "https://klaracase.de/api/v1/citation-checks" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "id": "0193b0c5-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
  "status": "complete",
  "source": "api_v1",
  "progress": {
    "citations_total": 2,
    "citations_checked": 2,
    "unique_citations_total": 2
  },
  "verdict_counts": {
    "verified": 1,
    "not_found": 1
  },
  "partial": false,
  "unverified_count": 0,
  "reason_counts": [
    {
      "category": "statute_unknown",
      "count": 1
    }
  ],
  "unique_citations": [
    {
      "key_basis": "matched_decision",
      "target_artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
      "canonical": "BGH 1 StR 185/01",
      "spellings": [
        "BGH, Urt. v. 15.11.2001 – 1 StR 185/01"
      ],
      "occurrences": 1,
      "verdict": "verified",
      "reference_type": "case"
    },
    {
      "key_basis": "canonical",
      "target_artifact_id": null,
      "canonical": "§ 266a Abs. 9 StGB",
      "spellings": [
        "§ 266a Abs. 9 StGB"
      ],
      "occurrences": 1,
      "verdict": "not_found",
      "reference_type": "statute"
    }
  ],
  "extraction": {
    "detected": 2,
    "dropped": 0,
    "dropped_unreadable": 0,
    "dropped_truncation": 0,
    "dropped_trailing_noun": 0,
    "dropped_stacked_subdivision": 0,
    "dropped_refused_collision": 0,
    "dropped_by_token": [],
    "dropped_unreadable_texts": [],
    "refused_contract_collision": [],
    "not_verifiable": 0,
    "not_verifiable_by_type": [],
    "possible_citations_unparsed": 0,
    "possible_citations_unparsed_texts": []
  },
  "notes": [],
  "findings_unavailable_reason": null,
  "findings_purged_at": null,
  "findings": [
    {
      "id": "0193b0c5-2b3c-7d4e-9f50-6b7c8d9e0f1a",
      "raw_text": "BGH, Urt. v. 15.11.2001 – 1 StR 185/01",
      "canonical": "BGH 1 StR 185/01",
      "type": "case",
      "role": null,
      "verdict": "verified",
      "external_status": "skipped",
      "start_offset": 118,
      "end_offset": 157,
      "occurrence_index": 0,
      "confidence": null,
      "matched_decision": {
        "artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
        "ecli": "ECLI:DE:BGH:2001:151101U1STR185.01.0",
        "court": "BGH",
        "date": "2001-11-15"
      },
      "subdivision_check": "not_checked",
      "subdivision_advisory": null,
      "check_scope": {
        "subdivision": "not_applicable",
        "article_text_available": null,
        "article_text_read": false,
        "court": "checked"
      },
      "ambiguity_advisory": null,
      "coverage": null,
      "coverage_boundary": null,
      "coverage_advisory": null,
      "evidence": {
        "reason": "exact_match",
        "match_strength": "exact"
      },
      "disputed_at": null
    }
  ],
  "submitted_at": "2026-10-01T10:00:00+00:00",
  "completed_at": "2026-10-01T10:00:00+00:00",
  "created_at": "2026-10-01T10:00:00+00:00",
  "payload_truncated": false,
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 2,
    "credits_remaining": 18
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
402Out of credits
{
  "type": "https://klaracase.de/docs/api/errors#insufficient_credits",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits: this call costs 2 credit(s), but organization \"Kanzlei Beispiel\" has 0 remaining this month. Credits renew automatically at the start of each calendar month (UTC). Ask your organization admin to raise the allotment, or retry next month.",
  "code": "insufficient_credits",
  "cost": 2,
  "balance": 0
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `citation-check` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "citation-check"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected text is invalid.",
  "code": "validation_failed",
  "errors": {
    "text": [
      "The selected text is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}
GET/api/v1/citation-checks/{run}
Ability: citation-checkFree
Read a citation check run
A run made through the API by your organization, read back by its id. Free.

Request

curl "https://klaracase.de/api/v1/citation-checks/{run}" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "id": "0193b0c5-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
  "status": "complete",
  "source": "api_v1",
  "progress": {
    "citations_total": 2,
    "citations_checked": 2,
    "unique_citations_total": 2
  },
  "verdict_counts": {
    "verified": 1,
    "not_found": 1
  },
  "partial": false,
  "unverified_count": 0,
  "reason_counts": [
    {
      "category": "statute_unknown",
      "count": 1
    }
  ],
  "unique_citations": [
    {
      "key_basis": "matched_decision",
      "target_artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
      "canonical": "BGH 1 StR 185/01",
      "spellings": [
        "BGH, Urt. v. 15.11.2001 – 1 StR 185/01"
      ],
      "occurrences": 1,
      "verdict": "verified",
      "reference_type": "case"
    },
    {
      "key_basis": "canonical",
      "target_artifact_id": null,
      "canonical": "§ 266a Abs. 9 StGB",
      "spellings": [
        "§ 266a Abs. 9 StGB"
      ],
      "occurrences": 1,
      "verdict": "not_found",
      "reference_type": "statute"
    }
  ],
  "extraction": {
    "detected": 2,
    "dropped": 0,
    "dropped_unreadable": 0,
    "dropped_truncation": 0,
    "dropped_trailing_noun": 0,
    "dropped_stacked_subdivision": 0,
    "dropped_refused_collision": 0,
    "dropped_by_token": [],
    "dropped_unreadable_texts": [],
    "refused_contract_collision": [],
    "not_verifiable": 0,
    "not_verifiable_by_type": [],
    "possible_citations_unparsed": 0,
    "possible_citations_unparsed_texts": []
  },
  "notes": [],
  "findings_unavailable_reason": null,
  "findings_purged_at": null,
  "findings": [
    {
      "id": "0193b0c5-2b3c-7d4e-9f50-6b7c8d9e0f1a",
      "raw_text": "BGH, Urt. v. 15.11.2001 – 1 StR 185/01",
      "canonical": "BGH 1 StR 185/01",
      "type": "case",
      "role": null,
      "verdict": "verified",
      "external_status": "skipped",
      "start_offset": 118,
      "end_offset": 157,
      "occurrence_index": 0,
      "confidence": null,
      "matched_decision": {
        "artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
        "ecli": "ECLI:DE:BGH:2001:151101U1STR185.01.0",
        "court": "BGH",
        "date": "2001-11-15"
      },
      "subdivision_check": "not_checked",
      "subdivision_advisory": null,
      "check_scope": {
        "subdivision": "not_applicable",
        "article_text_available": null,
        "article_text_read": false,
        "court": "checked"
      },
      "ambiguity_advisory": null,
      "coverage": null,
      "coverage_boundary": null,
      "coverage_advisory": null,
      "evidence": {
        "reason": "exact_match",
        "match_strength": "exact"
      },
      "disputed_at": null
    }
  ],
  "submitted_at": "2026-10-01T10:00:00+00:00",
  "completed_at": "2026-10-01T10:00:00+00:00",
  "created_at": "2026-10-01T10:00:00+00:00",
  "payload_truncated": false,
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 0,
    "credits_remaining": 18
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `citation-check` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "citation-check"
}
404Not found
{
  "type": "https://klaracase.de/docs/api/errors#not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "The requested resource does not exist, or it belongs to another organization.",
  "code": "not_found"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected id is invalid.",
  "code": "validation_failed",
  "errors": {
    "id": [
      "The selected id is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
POST/api/v1/citation-check-documents
Ability: citation-checkFree
Upload a document to check
Uploads a PDF, DOCX, Markdown or text file (up to 25 MB) as `multipart/form-data` in the field `file`. Its text is extracted in the background: the answer is 202, and you poll the upload until `status` is `ready`, then check it with `POST /citation-checks` and its `document_id`. Free; your organization's upload quota applies.

Parameters

fileRequired
stringbody

The document: PDF, DOCX, Markdown or plain text, up to 25 MB, sent as multipart/form-data.

Request

curl -X POST "https://klaracase.de/api/v1/citation-check-documents" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

202Accepted
{
  "id": "0193b0c6-3c4d-7e5f-8a60-7c8d9e0f1a2b",
  "filename": "schriftsatz.pdf",
  "format": "pdf",
  "status": "uploaded",
  "char_count": null,
  "page_count": null,
  "pages_without_text_layer": null,
  "check_max_chars": 20000,
  "quoted_credits": null,
  "error_code": null,
  "expires_at": "2026-10-02T10:00:00+00:00",
  "created_at": "2026-10-01T10:00:00+00:00",
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 0,
    "credits_remaining": 18
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `citation-check` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "citation-check"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected file is invalid.",
  "code": "validation_failed",
  "errors": {
    "file": [
      "The selected file is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
GET/api/v1/citation-check-documents/{document}
Ability: citation-checkFree
Read an upload
The status of an upload by its id: `char_count` and `quoted_credits` once its text is extracted, an `error_code` if extraction failed. The extracted text itself is never served. Free.

Request

curl "https://klaracase.de/api/v1/citation-check-documents/{document}" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "id": "0193b0c6-3c4d-7e5f-8a60-7c8d9e0f1a2b",
  "filename": "schriftsatz.pdf",
  "format": "pdf",
  "status": "ready",
  "char_count": 14830,
  "page_count": 6,
  "pages_without_text_layer": 0,
  "check_max_chars": 20000,
  "quoted_credits": 2,
  "error_code": null,
  "expires_at": "2026-10-02T10:00:00+00:00",
  "created_at": "2026-10-01T10:00:00+00:00",
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 0,
    "credits_remaining": 18
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `citation-check` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "citation-check"
}
404Not found
{
  "type": "https://klaracase.de/docs/api/errors#not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "The requested resource does not exist, or it belongs to another organization.",
  "code": "not_found"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected id is invalid.",
  "code": "validation_failed",
  "errors": {
    "id": [
      "The selected id is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}

Citation graph

GET/api/v1/decisions/{id}/citations
Ability: graph2 credits
Citation graph of a decision
The decisions one decision cites and the decisions citing it, paged, the REST twin of the MCP tool `get_citation_graph`. Two credits per decision, direction and depth per month; paging is free.

Parameters

direction
outgoingincomingbothquery

"outgoing" = decisions this one cites (references), "incoming" = decisions citing this one (referenced_by), "both" (default) = both directions.

depth
12query

1 (default) = direct neighbours; 2 = neighbours of neighbours, capped at 50 distinct neighbour decisions besides the source and served as a bounded sample.

court
stringquery

Optional disambiguator for an Aktenzeichen `id`: the canonical court short form, e.g. "BVerfG" or "OLG Hamm". Ignored for UUID lookups.

date
stringquery

Optional disambiguator for an Aktenzeichen `id`: the decision date in YYYY-MM-DD.

page
integerquery

1-based page (default 1) over the SOURCE decision's neighbour lists, 25 distinct decisions per direction, up to page 20. Defined at depth 1 only.

Request

curl "https://klaracase.de/api/v1/decisions/{id}/citations" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "source": {
    "id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
    "aktenzeichen": "1 StR 185/01",
    "court": "BGH",
    "date": "2001-11-15"
  },
  "references": [
    {
      "reference_canonical": "BGH 1 StR 50/15",
      "reference_role": "leitentscheidung",
      "resolution_status": "resolved",
      "in_corpus": true,
      "corpus": {
        "artifact_id": "0193b0c4-6a2d-7c4e-8f10-2b3c4d5e6f70",
        "court": "BGH",
        "date": "2015-03-12",
        "az": "1 StR 50/15",
        "document_type": "Urteil",
        "ecli": null,
        "corpus_url": "https://klaracase.de/decisions/0193b0c4-6a2d-7c4e-8f10-2b3c4d5e6f70"
      },
      "from_artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
      "hop": 1
    }
  ],
  "referenced_by": [
    {
      "reference_canonical": "BGH 1 StR 185/01",
      "reference_role": null,
      "resolution_status": "resolved",
      "in_corpus": true,
      "corpus": {
        "artifact_id": "0193b0c4-7b3e-7d5f-9a21-3c4d5e6f7a81",
        "court": "BGH",
        "date": "2022-06-08",
        "az": "4 StR 200/22",
        "document_type": "Beschluss",
        "ecli": null,
        "corpus_url": "https://klaracase.de/decisions/0193b0c4-7b3e-7d5f-9a21-3c4d5e6f7a81"
      },
      "from_artifact_id": "0193b0c4-7b3e-7d5f-9a21-3c4d5e6f7a81",
      "hop": 1
    }
  ],
  "served_direction": "both",
  "served_references_total": 1,
  "served_referenced_by_total": 1,
  "references_total": 1,
  "references_resolved_total": 1,
  "referenced_by_total": 1,
  "references_unresolved_total": 0,
  "references_withheld_reasons": [],
  "totals_scope": "source_decision_hop_1",
  "per_direction_cap": 25,
  "unresolved_cap": 25,
  "node_cap": 50,
  "truncated": false,
  "nodes_omitted": 0,
  "payload_truncated": false,
  "pagination": {
    "page": 1,
    "page_size": 25,
    "max_page": 20,
    "reachable_distinct_max": 500,
    "references_pages": 1,
    "referenced_by_pages": 1,
    "has_more_references": false,
    "has_more_referenced_by": false,
    "applies_at_depth": 1
  },
  "fortgeltung_checked": false,
  "fortgeltung_note": "Rechtskraft/Fortgeltung (whether a decision is still good law) is NOT checked. A decision returned here may have been quashed or superseded on appeal, and the ABSENCE of any such note is not evidence that it still stands.",
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 2,
    "credits_remaining": 25
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
402Out of credits
{
  "type": "https://klaracase.de/docs/api/errors#insufficient_credits",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits: this call costs 2 credit(s), but organization \"Kanzlei Beispiel\" has 0 remaining this month. Credits renew automatically at the start of each calendar month (UTC). Ask your organization admin to raise the allotment, or retry next month.",
  "code": "insufficient_credits",
  "cost": 2,
  "balance": 0
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `graph` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "graph"
}
404Not found
{
  "type": "https://klaracase.de/docs/api/errors#not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "The requested resource does not exist, or it belongs to another organization.",
  "code": "not_found"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected direction is invalid.",
  "code": "validation_failed",
  "errors": {
    "direction": [
      "The selected direction is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}

Corpus

GET/api/v1/corpus/coverage
Ability: readFree
Corpus coverage
What the corpus holds: per Gerichtsbarkeit and per court, the number of decisions and the earliest and latest decision date, the REST twin of the MCP tool `corpus_coverage`. Free. The figures in the example are illustrative.

Parameters

branch
ordentlichverwaltungsozialarbeitfinanzverfassungpatentunbekanntquery

Scope the report to one Gerichtsbarkeit slug. A branch is a COURT JURISDICTION, never a legal subject area: "patent" is the Bundespatentgericht. Omit to report every branch.

top
integerquery

Cap on the per-court rows, busiest first (default 20, max 100). The branch rollup is never capped.

Request

curl "https://klaracase.de/api/v1/corpus/coverage" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "total_decisions": {
    "value": 100000,
    "is_floor": false
  },
  "branches": [
    {
      "branch": "ordentlich",
      "count": {
        "value": 60000,
        "is_floor": false
      },
      "earliest": "1950-10",
      "latest": "2026-09",
      "court_founding_year": 1950,
      "court_founding_basis": "branch_wide_weakest_court_floor",
      "has_dates_below_floor": false,
      "instance_mix": {
        "federal": {
          "value": 25000,
          "is_floor": false
        },
        "appellate": {
          "value": 20000,
          "is_floor": false
        },
        "first_instance_and_regional": {
          "value": 15000,
          "is_floor": false
        },
        "other": {
          "value": 0,
          "is_floor": false
        },
        "note": "Instanzmix: 42% Bundesgerichte, 33% Obergerichte, 25% Eingangs- und Landgerichte. …"
      },
      "top_courts": [
        {
          "court": "BGH",
          "count": {
            "value": 25000,
            "is_floor": false
          },
          "earliest": "1950-10",
          "latest": "2026-09"
        }
      ]
    }
  ],
  "courts": [
    {
      "court": "BGH",
      "branch": "ordentlich",
      "count": {
        "value": 25000,
        "is_floor": false
      },
      "earliest": "1950-10",
      "latest": "2026-09",
      "court_founding_year": 1950,
      "court_founding_basis": "court_floor",
      "has_dates_below_floor": false
    }
  ],
  "courts_returned": 20,
  "courts_total": 400,
  "corpus_floors": "Earliest decision we hold per Gerichtsbarkeit … ordentlich 1950+. …",
  "coverage_ranges": {
    "note": "The ingestion boundary every `out_of_coverage` verdict is decided against. …",
    "scope": "all",
    "verified_at": "2026-08-13",
    "ranges": [
      {
        "bucket": "BGH_STRAFRECHT",
        "court": "BGH",
        "label": "BGH Strafsachen",
        "from": "1950-10-02",
        "until": null,
        "sources": [
          "ris"
        ],
        "exhaustive": true,
        "ocr": true,
        "note": "Strafsenate ab 1950.",
        "holdings_earliest": null
      }
    ]
  },
  "as_of": "2026-10-01T09:58:12+00:00",
  "filter_coverage_caveats": "Three known blind spots, all on scanned decisions. …",
  "law_coverage": {
    "note": "The law texts behind the citation check are German federal statutes, plus the EU and international instruments listed beside this note. …",
    "eu": [
      "AEUV",
      "DSGVO"
    ],
    "international": [
      "EMRK"
    ]
  },
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 0,
    "credits_remaining": 30
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `read` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "read"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected branch is invalid.",
  "code": "validation_failed",
  "errors": {
    "branch": [
      "The selected branch is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}
GET/api/v1/corpus/facets/{field}
Ability: readFree
Filter values of a field
The values the index holds for a filterable field, with counts, so a search filter uses values that exist: the REST twin of the MCP tool `list_facets`. Free. The figures in the example are illustrative.

Parameters

type
decisionlawquery

Restrict the counts to one artifact type. Omit to count across both. Ignored for field="cited_norms".

norm
stringquery

Required with field="cited_norms", ignored otherwise: the norm whose family to list, e.g. "§ 543 BGB". Canonicalized before use and echoed back.

prefix
stringquery

Case-insensitive prefix filter on the facet value. A trailing space counts: prefix="AG " excludes "AGH Niedersachsen", prefix="AG" keeps it.

Request

curl "https://klaracase.de/api/v1/corpus/facets/{field}" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "field": "court_name",
  "applies_to": "DECISION",
  "values": {
    "BGH": {
      "value": 90000,
      "is_floor": false
    },
    "BVerfG": {
      "value": 20000,
      "is_floor": false
    },
    "BVerwG": {
      "value": 15000,
      "is_floor": false
    }
  },
  "total_values": 3,
  "truncated": false,
  "value_limit": 500,
  "count_basis": "indexed_passages",
  "as_of": "2026-10-01T09:40:00+00:00",
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 0,
    "credits_remaining": 30
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `read` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "read"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected type is invalid.",
  "code": "validation_failed",
  "errors": {
    "type": [
      "The selected type is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}

Datapackages

POST/api/v1/datapackages
Ability: datapackage5 credits
Assemble a datapackage
Up to ten decisions with their outgoing citation edges in one structured payload, as grounded context for a language model: the REST twin of the MCP tool `assemble_datapackage`. Five credits per set of decisions and options per month.

Parameters

idsRequired
arraybody

1-10 decision ids. ORDER MATTERS: the response budget drops decisions from the END. Duplicates collapse into one decision; `requested`, `included` and `deduped` report that.

include_citations
booleanbody

Include each decision's outgoing citation edges (default true).

full_text
booleanbody

Serve whole judgments instead of ~700-character excerpts (default false). Token-heavy: prefer excerpts plus targeted get_decision calls.

max_chars
integerbody

Per-decision text cap when `full_text` is true (default 60000, minimum 500, maximum 200000). A ceiling, not a guarantee: the response budget outranks it.

Request

curl -X POST "https://klaracase.de/api/v1/datapackages" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "decisions": [
    {
      "id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
      "aktenzeichen": "1 StR 185/01",
      "court": "BGH",
      "date": "2001-11-15",
      "document_type": "Urteil",
      "ecli": "ECLI:DE:BGH:2001:151101U1STR185.01.0",
      "jurisdiction": "DE",
      "excerpt": "Tenor … Gründe: I. Der Angeklagte war Geschäftsführer …",
      "excerpt_span": "document_start",
      "text_length": 48213,
      "truncated": true,
      "fortgeltung_checked": false,
      "fortgeltung_note": "Rechtskraft/Fortgeltung (whether a decision is still good law) is NOT checked. A decision returned here may have been quashed or superseded on appeal, and the ABSENCE of any such note is not evidence that it still stands."
    }
  ],
  "citation_edges": [
    {
      "reference_canonical": "BGH 1 StR 50/15",
      "reference_role": "leitentscheidung",
      "resolution_status": "resolved",
      "in_corpus": true,
      "corpus": {
        "artifact_id": "0193b0c4-6a2d-7c4e-8f10-2b3c4d5e6f70",
        "court": "BGH",
        "date": "2015-03-12",
        "az": "1 StR 50/15",
        "document_type": "Urteil",
        "ecli": null,
        "corpus_url": "https://klaracase.de/decisions/0193b0c4-6a2d-7c4e-8f10-2b3c4d5e6f70"
      },
      "from_artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d"
    }
  ],
  "edge_accounting": [
    {
      "from_artifact_id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
      "unit": "edge_rows",
      "edges_total": 1,
      "edges_included": 1,
      "edges_resolved_included": 1,
      "edges_unresolved_included": 0,
      "edges_resolved_total": 1,
      "edges_unresolved_total": 0,
      "targets_resolved_included": 1,
      "targets_resolved_total": 1
    }
  ],
  "per_source_resolved_target_cap": 25,
  "per_source_unresolved_edge_row_cap": 25,
  "requested": 1,
  "included": 1,
  "deduped": 0,
  "text_mode": "excerpt",
  "max_chars": 700,
  "truncated": false,
  "payload_truncated": false,
  "assembled_at": "2026-10-01T10:00:00+00:00",
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 5,
    "credits_remaining": 20
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
402Out of credits
{
  "type": "https://klaracase.de/docs/api/errors#insufficient_credits",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits: this call costs 5 credit(s), but organization \"Kanzlei Beispiel\" has 0 remaining this month. Credits renew automatically at the start of each calendar month (UTC). Ask your organization admin to raise the allotment, or retry next month.",
  "code": "insufficient_credits",
  "cost": 5,
  "balance": 0
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `datapackage` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "datapackage"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected ids is invalid.",
  "code": "validation_failed",
  "errors": {
    "ids": [
      "The selected ids is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}

Decisions

GET/api/v1/decisions/{id}
Ability: read1 credit
Read a decision
One decision's full text, or a named section or a Randnummer window of it, with its metadata: the REST twin of the MCP tool `get_decision`. One credit per decision per month; reading it again, in any slice, costs nothing more.

Parameters

max_chars
integerquery

Maximum characters of text to return (default 40000, minimum 500).

rn_from
integerquery

Optional range start: the first Randnummer to return. Whole chunks come back, so read the served span off `returned_range`.

rn_to
integerquery

Optional range end: the highest Randnummer to return (inclusive). Must be >= rn_from.

section
stringquery

Optional named section instead of the whole text. One of: Tenor, Leitsatz, Tatbestand, Gründe (case-insensitive). Check `available_sections` before asking.

court
stringquery

Optional disambiguator for an Aktenzeichen `id`: the court short form, e.g. "BGH". Matched as a whole-word prefix. Ignored for UUID lookups.

date
stringquery

Optional disambiguator for an Aktenzeichen `id`: the decision date in YYYY-MM-DD.

Request

curl "https://klaracase.de/api/v1/decisions/{id}" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Responses

200Success
{
  "id": "0193b0c4-5f1e-7a2b-9c3d-4e5f6a7b8c9d",
  "aktenzeichen": "1 StR 185/01",
  "court": "BGH",
  "date": "2001-11-15",
  "jurisdiction": "DE",
  "metadata": {
    "document_type": "Urteil",
    "ecli": "ECLI:DE:BGH:2001:151101U1STR185.01.0",
    "file_numbers": [
      "1 StR 185/01"
    ]
  },
  "fortgeltung_checked": false,
  "fortgeltung_note": "Rechtskraft/Fortgeltung (whether a decision is still good law) is NOT checked. A decision returned here may have been quashed or superseded on appeal, and the ABSENCE of any such note is not evidence that it still stands.",
  "full_text": "Tenor … Gründe: I. … 21 Die Revision ist unbegründet …",
  "text_length": 48213,
  "truncated": true,
  "rn_source": "printed",
  "rn_source_note": "The Randnummern are the court's own printed numbers.",
  "available_sections": [
    "Tenor",
    "Gründe"
  ],
  "available_range": {
    "rn_from": 1,
    "rn_to": 64,
    "rn_source": "printed"
  },
  "available_range_scope": "decision",
  "has_rn_anchors": true,
  "api_version": "0.93.0",
  "changelog_url": "https://klaracase.de/docs/mcp/changelog",
  "credits": {
    "metered": true,
    "cost": 1,
    "credits_remaining": 27
  }
}
401Unauthenticated
{
  "type": "https://klaracase.de/docs/api/errors#unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required. Send a Klaracase API token as a Bearer token.",
  "code": "unauthenticated"
}
402Out of credits
{
  "type": "https://klaracase.de/docs/api/errors#insufficient_credits",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits: this call costs 1 credit(s), but organization \"Kanzlei Beispiel\" has 0 remaining this month. Credits renew automatically at the start of each calendar month (UTC). Ask your organization admin to raise the allotment, or retry next month.",
  "code": "insufficient_credits",
  "cost": 1,
  "balance": 0
}
403Forbidden
{
  "type": "https://klaracase.de/docs/api/errors#token_ability_missing",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API token does not carry the `read` ability this endpoint needs. Nothing was executed and nothing was charged. Create a token with that ability in Settings, API tokens.",
  "code": "token_ability_missing",
  "required_ability": "read"
}
404Not found
{
  "type": "https://klaracase.de/docs/api/errors#not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "The requested resource does not exist, or it belongs to another organization.",
  "code": "not_found"
}
409Conflict
{
  "type": "https://klaracase.de/docs/api/errors#token_org_missing",
  "title": "Conflict",
  "status": 409,
  "detail": "This API token was created before tokens named an organization, so the API cannot tell which organization it acts for. Create a new token in Settings, API tokens; it acts for the organization you have open.",
  "code": "token_org_missing"
}
422Validation error
{
  "type": "https://klaracase.de/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "The selected max_chars is invalid.",
  "code": "validation_failed",
  "errors": {
    "max_chars": [
      "The selected max_chars is invalid."
    ]
  }
}
429Too many requests
{
  "type": "https://klaracase.de/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests for this token. Wait `retry_after_seconds` and retry. Nothing was executed and nothing was charged.",
  "code": "rate_limited",
  "retry_after_seconds": 42
}
503Service unavailable
{
  "type": "https://klaracase.de/docs/api/errors#backend_unavailable",
  "title": "Service Unavailable",
  "status": 503,
  "detail": "The backend could not complete this call, so nothing was charged. Retry in a few seconds.",
  "code": "backend_unavailable"
}