Reference

Citations API

Legal citation networks, case metadata, and legal reference extraction across Dutch, ECHR, and CJEU case law. Every endpoint returns JSON; POST endpoints take a JSON body, GET endpoints take query parameters.

API root
/api
Every endpoint lives under one prefix.
Endpoints
14
Across search, documents, analysis, and references.
Schema
cle_v2
One Postgres schema for all three corpora.
Hard limit
10,000
Matched result nodes per search query.

Authentication

The Case Law Explorer apps send the signed-in user's token; everything else sends a scoped API key minted for this project in the access console. Both are validated by the same access check, so either may be sent as a bearer token.

Authorization: Bearer <token or API key>

A key carries the endpoint scopes it was minted with. A call to a route outside them is refused even though the key itself is valid.

Pagination

The search endpoints use opt-in cursor pagination. Omit pageSize and cursor and you get a bounded full graph; ask for a page and the response carries an opaque nextCursor until there are no more.

FieldDescription
pageSizeOptional. Matched result nodes per page, 1 to 1000.
cursorOpaque token from a previous response's nextCursor.
nextCursorPresent while more pages exist, null at the end.
limitsQuery result limit 10000, response node limit 5000, response edge limit 30000.
graphCompleteness metadata. Check graph.statisticsSafe before calling /api/statistics.

Cursor tokens encode the query state, so changing any argument invalidates them. Paging through everything client-side still means checking graph.partialReasons on each page — a graph can be truncated for reasons other than paging.

Errors

Failures come back as JSON with an error field.

CodeMeaning
200Success.
400Validation error — missing required fields, invalid values, or a bad cursor.
401No credential, or one the access service rejected.
403Valid credential, but the endpoint is outside its scopes.
410Endpoint retired on the current schema.
429Rate limit exhausted. Retry-After says when to try again.
500Internal server error.
{
  "error": "Missing required field: degreesSource",
  "type": "ValidationError",
  "details": "degreesSource must be an integer 0-5"
}