DocumentationBrowse
Retrieval and downloads
The grounding step of a chat completion, callable on its own. Two endpoints search the corpora DocketRouter holds and return the hits with no model in the loop; a third lists and streams the corpora that can be downloaded whole. The corpora themselves are described on Featured RAGs.
POST /rag/query
Hybrid vector plus keyword search over 615,391 Texas decisions, 122,681 Texas statute sections, 45,660 U.S. Supreme Court opinion documents and 370 county local rules.
| Field | Type | Default | Notes |
|---|---|---|---|
q | string | required | The question or phrase. 1 to 600 characters after trimming. |
k | integer | 5 | How many hits to return, 1 to 20. |
sources | string[] | all four | Which shards to search: tx, statutes, scotus, local. Anything else is a 400. |
min_score | number | index default | 0 to 1. The similarity floor the index applies before fusing; lower it for recall on unusual phrasing. |
{
"hits": [
{
"source": "tx",
"name": "King Ranch, Inc. v. Chapman",
"citation": ["118 S.W.3d 742"],
"court": "Tex.",
"date": "2003-08-28",
"snippet": "A no-evidence summary judgment is essentially a pretrial directed verdict …",
"score": 0.016
}
],
"took_ms": 412,
"sources_searched": ["tx", "statutes"],
"request_id": "req_2f9c1e7a4b8d0e3f5a61"
}| Field | Meaning |
|---|---|
hits[].source | The shard the hit came from. |
hits[].citation | Reporter or statute citations attached to the document. Empty when the index holds only the case name, which is common for Texas opinions and for a local rule. |
hits[].snippet | Up to 300 characters of the best-matching passage, whitespace collapsed. |
hits[].score | The index's fused rank score, three decimals. Higher is better; compare within one response, not across queries. |
took_ms | Wall time of the call as seen by this API, including the index round trip. |
sources_searched | The shards the index actually searched. |
If the index is not configured on the host or does not answer within 15 seconds, the response is {"error":{"message","type":"service_unavailable_error","request_id"}} with HTTP 503. An empty hits array with HTTP 200 means the index answered and nothing matched at that score, which is a different fact. Treat 503 as retryable.
POST /rag/rules
BM25 over 6,093 verbatim rule and statute sections with rule-number expansion, so a query that names a rule lands on it.
| Field | Type | Default | Notes |
|---|---|---|---|
q | string | required | 1 to 600 characters. References like Rule 12(b)(6), FRE 803 or TRCP 166a are recognised and boosted. |
k | integer | 5 | How many sections to return, 1 to 20. |
{
"hits": [
{
"cite": "Fed. R. Civ. P. 12",
"title": "Rule 12. Defenses and Objections: …",
"set": "frcp",
"source": "Federal Rules of Civil Procedure",
"url": "https://www.law.cornell.edu/rules/frcp/rule_12",
"text": "(a) Time to Serve a Responsive Pleading. …", // at most 1,200 characters
"truncated": true,
"score": 14.371
}
],
"took_ms": 9
}text is the section verbatim, cut at 1,200 characters with truncated set when it was longer. The full text of every section is in the rules-corpus download. score is a raw BM25 score, comparable within one response but not across queries.
GET /downloads and GET /downloads/:id
The listing is public and cached for five minutes. Fetching a file needs a key or a session and is limited to two downloads per minute per caller.
{
"data": [
{ "id": "rules-corpus", "name": "Verbatim rules corpus", "filename": "docketrouter-rules-corpus.json",
"content_type": "application/json", "bytes": 7185790, "approx_size": "about 7 MB", "available": true,
"licence": "Public domain source text …", "attribution": "Compiled by DocketRouter …",
"url": "https://docketrouter.ai/api/v1/downloads/rules-corpus", "auth": "key or session", "rate_limit": "2 per minute" },
{ "id": "citation-table", "name": "Citation table", "filename": "docketrouter-citations.sqlite",
"content_type": "application/vnd.sqlite3", "approx_size": "about 1 GB", "generated_on_request": false, … },
{ "id": "reporters", "name": "Reporter list", "filename": "docketrouter-reporters.json",
"content_type": "application/json", "approx_size": "under 100 KB", "generated_on_request": true, … }
]
}| Id | What | Licence |
|---|---|---|
rules-corpus | The 6,093 verbatim sections as one JSON array of { id, set, source, cite, title, url, text }. | Public domain source text; the compilation is provided without additional restriction. |
citation-table | SQLite, table cites (volume, reporter, page, type, cluster_id): 18,123,788 rows, 989 reporters. About 1 GB. | Public domain, derived from the Free Law Project bulk export. Attribution encouraged. |
reporters | JSON list of the 989 reporter abbreviations with a citation count for each. Generated from the table on first request, then cached. | Same as the citation table. |
Response headers
| Header | Value |
|---|---|
Content-Length | Exact byte count of the body, or of the range. |
Content-Disposition | attachment with the filename from the listing. |
ETag | Weak tag from id, size and mtime. Send it back as If-None-Match for a 304, or as If-Range so a resumed range is refused with a full 200 if the file changed underneath. |
Accept-Ranges | bytes. A Range: bytes=start-end request gets 206 with Content-Range; an unsatisfiable one gets 416. |
X-DocketRouter-Licence | The licence line from the listing, so a saved file is never separated from it. |
| Status | When |
|---|---|
| 401 | No key and no session. |
| 404 | Unknown id. |
| 429 | More than two downloads in a minute from one caller. |
| 503 | The file is not present on this host, or the reporters list could not be generated because the table is absent. |
Examples
# search the Texas law index
curl https://docketrouter.ai/api/v1/rag/query \
-H "Authorization: Bearer dr-…" -H "content-type: application/json" \
-d '{ "q": "no-evidence summary judgment standard", "k": 5, "sources": ["tx"] }' \
| jq '.hits[] | {name, citation, date, score}'
# quote the rule itself
curl https://docketrouter.ai/api/v1/rag/rules \
-H "Authorization: Bearer dr-…" -H "content-type: application/json" \
-d '{ "q": "TRCP 166a no-evidence motion", "k": 2 }' | jq '.hits[0] | {cite, title, text}'
# list downloads (no auth), then fetch one and resume the big one
curl https://docketrouter.ai/api/v1/downloads | jq '.data[] | {id, bytes, licence}'
curl -L -O -J https://docketrouter.ai/api/v1/downloads/rules-corpus -H "Authorization: Bearer dr-…"
curl -L -C - -o citations.sqlite https://docketrouter.ai/api/v1/downloads/citation-table -H "Authorization: Bearer dr-…"Limits
| Limit | Value | On breach |
|---|---|---|
q | 600 characters | 400 |
k | 1 to 20 | 400 |
sources | subset of tx, statutes, scotus, local | 400 |
| Request body | 64 KB | 413 |
| Search calls per key or session | 30 per minute, burst 10 | 429 with Retry-After |
| Search calls from the site demo | 10 per minute per IP, burst 3 | 429 with Retry-After |
| Downloads per key or session | 2 per minute | 429 with Retry-After |
| Index timeout | 15 seconds | 503 |
Search calls are metered at zero cost and appear in your usage log as model rag/query, so they can be reconciled like any other request. Rules searches are logged the same way; whole-corpus downloads are not offered.
Something here wrong or missing? Mail hello@docketrouter.ai with the request_id and we will fix the docs or the API, whichever is broken.