API reference
Agent-friendly: this page as Markdown → /docs.md
Base URL https://lawapi.app/api/v1. Every response is an AFDATA v1 envelope: {"kind":"result","result":…,"trace":{}} on success, {"kind":"error","error":…} otherwise. Text comes back in the language the official source published it in; the API never translates or paraphrases the record.
Search
GET /api/v1/search
Full-text search over provisions in all 37 jurisdictions. Query in any language the sources use; results rank by relevance across works and sections.
| Parameter | Type | Notes |
|---|---|---|
q | string | Required. Words are ANDed; a multi-word query that finds nothing is widened to OR. Quote a phrase to keep it whole. |
jurisdiction | string | Optional. One of the codes below. Omit to search everything. |
limit | integer | Optional. 1–100, default 20. |
curl 'https://lawapi.app/api/v1/search' -G \
--data-urlencode 'q=解雇の予告' \
--data-urlencode 'jurisdiction=jp' \
--data-urlencode 'limit=1'
{
"kind": "result",
"result": {
"query": "解雇の予告",
"result_count": 1,
"results": [
{
"id": "wq_jp_5b89e4a20f42e4c9#article-20",
"jurisdiction": "jp",
"work": {
"title": "労働基準法",
"slug": "law-0091651e1f",
"legal_force": "in_force",
"source_urls": ["https://laws.e-gov.go.jp/law/322AC0000000049"]
},
"section": {
"ref": "article-20",
"num_label": "第二十条",
"heading_path": "第二章 労働契約",
"language": "ja",
"is_authoritative": false,
"untranscribed_graphic_count": 0,
"text": "使用者は、労働者を解雇しようとする場合においては、少くとも三十日前にその予告をしなければならない。…"
},
"url": "https://laws.e-gov.go.jp/law/322AC0000000049"
}
]
},
"trace": {}
}
Response contract
Each element of results is one provision. Identifiers are stable across calls; id is <work id>#<section ref>.
| Field | Meaning |
|---|---|
jurisdiction | Jurisdiction code, the same value you can pass as a filter. |
work.title | Title of the act or regulation as published. |
work.legal_force | in_force · repealed · expired · not_yet_in_force · unknown. Computed at query time from the dates the source states; unknown when it states none. |
work.source_urls | Official publication URLs for the work. url on the hit is the first of them. |
section.ref | Stable section reference inside the work. |
section.num_label | The label to cite, in the source's own convention. |
section.heading_path | Part / chapter / heading trail, joined with / . Empty when the act has no structure above the section. |
section.language | BCP 47 tag of section.text. |
section.is_authoritative | true when this text is the legally binding version; false for official translations and for sources that publish consolidated text without asserting authority. |
section.untranscribed_graphic_count | 0 for a verbatim-complete provision. Greater than zero means part of the provision is published only as a figure, formula or table and its content is not in section.text: the text carries an explicit in-place editorial marker (or the publisher's own "graphic only" wording) at that position. Go to work.source_urls for the graphic itself. |
section.text | The provision as published. Plain text for most sources; sources that publish rich gazette markup (UK, Canada, Australia, France) keep it as HTML with the publisher's own attributes, so render or strip it deliberately. |
Jurisdictions
GET /api/v1/jurisdictions
Every jurisdiction with its primary language and published-law count. Free; does not consume credits. Codes currently in the index:
{
"kind": "result",
"result": {
"jurisdictions": [
{ "code": "au", "name": "Australia", "primary_language": "en", "law_count": 23113 },
{ "code": "de", "name": "Germany", "primary_language": "de", "law_count": 5959 },
…
]
},
"trace": {}
}
Errors
Errors use kind: "error" with a machine-readable code, a human-readable message, a retryable flag and, where there is an obvious next step, a hint. HTTP status matches: 400 for a bad request, 401 for an invalid key, 429 when rate-limited, 5xx when it is our fault.
{
"kind": "error",
"error": {
"code": "unauthorized",
"message": "invalid API key",
"retryable": false,
"hint": "send Authorization: Bearer <api_key>; get a free key at https://lawapi.app/pricing"
},
"trace": {}
}
MCP
POST /mcp
A Model Context Protocol server over JSON-RPC 2.0 — initialize, tools/list, tools/call — exposing one search tool with the same parameters and result shape as the REST endpoint. Point any MCP client at it:
{
"mcpServers": {
"lawapi": {
"url": "https://lawapi.app/mcp",
"headers": { "Authorization": "Bearer lawapi_…" }
}
}
}
Auth
Send your key as a bearer token. During the beta, requests without a key are allowed at the anonymous rate limit; a request with an invalid key is always rejected with 401, so a typo never silently downgrades you.
curl 'https://lawapi.app/api/v1/search?q=redundancy&jurisdiction=ie' \
-H 'Authorization: Bearer lawapi_…'
Limits
Rate limits are per key, or per IP without one: 60 requests per minute on the free tier, 120 on pay as you go. limit caps at 100 results per call. There is no pagination yet; narrow with jurisdiction and a more specific q instead.