Developer guide
Reads the text of decisions, official letters, decrees and circulars — straight from your OCR, or typed without accents — and pulls out who issued each one, its number, date, who signed it and which laws it relies on. It also shows how documents connect: which one cites, replaces or cancels another. It is small enough to run on your own servers, so your documents never leave your organisation.
Address for your software (API)
https://api2.belumind.com/clausaAddress for AI assistants (MCP)
https://mcp2.belumind.com/clausa- Accuracy (details / links)
- 90.0 / 81.2
- Fast server (A100 GPU)
- 0.20 s / page
- Regular server (Xeon CPU)
- 5.09 s / page
- Size
- < 0.5 billion parameters
Access keys
Every request sends two things: an API key for this product, made in the dashboard under API keys, and the access token of the signed-in user who owns it. The token lasts 15 minutes, so refresh it and send the new one. A key made for another product gets a 403 error. That means you can give an AI assistant a key that reaches exactly one tool and nothing else.
AI assistants send the same two headers when they connect to the address above.
clausa:extractX-API-Key: bm_live_7f3c… Authorization: Bearer eyJhbGciOi… Content-Type: application/json
/v1/extract/schemaclausa:extractRead a document's key details
Send the text of an official document — Clausa does not open PDFs or images, so run OCR first — and get back its number, issuing body, issue date (as `YYYY-MM-DD`), signer, the signer's position and the documents it is based on. The built-in `administrative_document` schema covers these; `GET /v1/schemas` (MCP: `list_schemas`) lists it with every field. A field Clausa cannot find comes back empty rather than guessed, and `warnings` names any required field that is missing. Texts over 20,000 characters go to `POST /v1/jobs/schema` instead.
extract_document_fieldsWhat to send
textstringrequired- The document's text, UTF-8 — for example the output of your OCR.
schema_namestringoptional- A built-in schema from `GET /v1/schemas`, such as `administrative_document`. Send this or `schema` — the REST API has no default, so a request with neither gets error 422. (The MCP tool defaults to `administrative_document`.)
schemaobjectoptional- Your own fields instead of a built-in schema: each names a label and, optionally, a relation it must have. `GET /v1/examples` shows four. Send this or `schema_name`.
postprocessbooleanoptional- Clean up OCR text before reading it — drop digital-signature stamps, logos and repeated lines, fix QD to QĐ, pair the signer with their position. On by default; every change is listed in `postprocess.edits`.
detailbooleanoptional- Also return the candidates, raw entities and relations behind each field, and the cleaned text. For debugging.
What you get back
200 OKIt worked. You get back what the example shows.400 Bad RequestSomething in what you sent was wrong or missing. The answer says which part.401 UnauthorizedThe API key or access token is missing, mistyped or no longer valid. Access tokens expire after 15 minutes — refresh it and send the new one.403 ForbiddenThe key works, but it was made for another product.402 Payment RequiredThe account is out of credits. Buy more in the dashboard, or turn on automatic top-up.429 Too Many RequestsToo many requests in a short time, or the key has reached the monthly limit set on it. Wait the number of seconds given in `Retry-After`, then try again.500 Internal Server ErrorSomething went wrong on our side. It is safe to send the same request again.503 Service UnavailableThe queue is full, or the dashboard that checks keys could not be reached. Try again a little later.
What you send
curl -X POST https://api2.belumind.com/clausa/v1/extract/schema \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "ỦY BAN NHÂN DÂN TỈNH THANH VÂN\nSố: 1482/QD-UBND\nThanh Vân, ngày 18 tháng 3 năm 2026\nQUYẾT ĐỊNH\nVề việc ban hành Quy chế lưu trữ hồ sơ điện tử\nCăn cứ Luật Lưu trữ ngày 21 tháng 6 năm 2024;\nCăn cứ Nghị định số 118/2024/NĐ-CP;\n…\nKT. CHỦ TỊCH\nPHÓ CHỦ TỊCH\nTrần Minh Khải", "schema_name": "administrative_document" }'
What you get back
{
"result": {
"document_number": "1482/QĐ-UBND",
"issuing_authority": "ỦY BAN NHÂN DÂN TỈNH THANH VÂN",
"issue_date": "2026-03-18",
"signer": "Trần Minh Khải",
"signer_title": "Phó Chủ tịch",
"legal_bases": [
"Luật Lưu trữ",
"Nghị định số 118/2024/NĐ-CP"
]
},
"warnings": [],
"device": "mps",
"seconds": 0.59,
"postprocess": {
"lines_removed": 0,
"edits": [
{
"field": "document_number",
"before": "1482/QD-UBND",
"after": "1482/QĐ-UBND",
"reason": "document_type_code"
},
{
"field": "signer_title",
"before": "Phó chủ tịch",
"after": "Phó Chủ tịch",
"reason": "dictionary"
}
]
}
}Try it
Try it
Example modePOST https://api2.belumind.com/clausa/v1/extract/schemaThe platform is in early access, so this box shows the example answer instead of contacting the live service. Ask us for a key and the same box will send real requests.
/v1/extractclausa:extractFind names, dates and the links between them
Ask for the kinds of thing you want — people, positions, organisations, dates, documents — and the links between them, such as who holds which position or which decision replaces which. Each entity comes back with its place in the text and a confidence score; each link points to two entities by id. Clausa was trained on the labels from `GET /v1/labels`; other labels work too, less accurately. Add `?download=true` to get the result as a JSON file. `POST /v1/extract/batch` takes several of these requests at once, as `items`, and reads them one after another.
extract_entitiesWhat to send
textstringrequired- The text to read, UTF-8. Long texts are split into chunks automatically.
entitiesstring[]required- Labels to find, in Vietnamese with diacritics — for example `người`, `chức vụ`, `tổ chức`, `ngày`.
relationsstring[]optional- Links to find between entities, such as `giữ chức` (holds position) or `thay thế` (replaces). May be empty.
thresholdnumberoptional- Lowest confidence, 0–1, for an entity to be kept. Defaults to each label's own threshold (0.5).
relation_thresholdnumberoptional- Lowest confidence, 0–1, for a link to be kept. Defaults to 0.5.
max_words_per_chunkintegeroptional- Largest piece, in words, that a long text is split into before reading, 10–200. Defaults to 40, which measured best.
What you get back
200 OKIt worked. You get back what the example shows.400 Bad RequestSomething in what you sent was wrong or missing. The answer says which part.401 UnauthorizedThe API key or access token is missing, mistyped or no longer valid. Access tokens expire after 15 minutes — refresh it and send the new one.403 ForbiddenThe key works, but it was made for another product.402 Payment RequiredThe account is out of credits. Buy more in the dashboard, or turn on automatic top-up.429 Too Many RequestsToo many requests in a short time, or the key has reached the monthly limit set on it. Wait the number of seconds given in `Retry-After`, then try again.500 Internal Server ErrorSomething went wrong on our side. It is safe to send the same request again.503 Service UnavailableThe queue is full, or the dashboard that checks keys could not be reached. Try again a little later.
What you send
curl -X POST https://api2.belumind.com/clausa/v1/extract \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "Bổ nhiệm ông Nguyễn Văn An, Phó Giám đốc Sở Tài chính tỉnh Nghệ An, giữ chức Giám đốc Sở Tài chính tỉnh Nghệ An kể từ ngày 01 tháng 3 năm 2024.", "entities": [ "người", "chức vụ", "tổ chức", "ngày" ], "relations": [ "giữ chức", "thuộc tổ chức" ] }'
What you get back
{
"entities": [
{
"id": "e1",
"text": "Nguyễn Văn An",
"label": "người",
"start": 13,
"end": 26,
"score": 0.9629
},
{
"id": "e2",
"text": "Phó Giám đốc",
"label": "chức vụ",
"start": 28,
"end": 40,
"score": 0.875
},
{
"id": "e3",
"text": "Sở Tài chính tỉnh Nghệ An",
"label": "tổ chức",
"start": 41,
"end": 66,
"score": 0.7334
},
{
"id": "e4",
"text": "Giám đốc",
"label": "chức vụ",
"start": 77,
"end": 85,
"score": 0.7603
},
{
"id": "e5",
"text": "Sở Tài chính tỉnh Nghệ An",
"label": "tổ chức",
"start": 86,
"end": 111,
"score": 0.7329
},
{
"id": "e6",
"text": "ngày 01 tháng 3 năm 2024",
"label": "ngày",
"start": 118,
"end": 142,
"score": 0.9536
}
],
"relations": [
{
"head": "e1",
"relation": "giữ chức",
"tail": "e2",
"score": 0.6558,
"head_text": "Nguyễn Văn An",
"tail_text": "Phó Giám đốc"
},
{
"head": "e1",
"relation": "thuộc tổ chức",
"tail": "e3",
"score": 0.8726,
"head_text": "Nguyễn Văn An",
"tail_text": "Sở Tài chính tỉnh Nghệ An"
},
{
"head": "e1",
"relation": "giữ chức",
"tail": "e4",
"score": 0.8149,
"head_text": "Nguyễn Văn An",
"tail_text": "Giám đốc"
}
],
"meta": {
"device": "mps",
"chunks": 1,
"max_words_per_chunk": 40,
"entity_labels_queried": [
"người",
"chức vụ",
"tổ chức",
"ngày"
],
"relation_labels_queried": [
"giữ chức",
"thuộc tổ chức"
],
"seconds": 0.687,
"warnings": []
}
}Try it
Try it
Example modePOST https://api2.belumind.com/clausa/v1/extractThe platform is in early access, so this box shows the example answer instead of contacting the live service. Ask us for a key and the same box will send real requests.
/v1/jobs/schemaclausa:extractSend a long document to read in the background
For texts over 20,000 characters, up to 1,000,000. Takes the same body as `POST /v1/extract/schema` and answers at once with a job id; check `GET /v1/jobs/{job_id}` until `status` is `done`. `POST /v1/jobs/extract` does the same for `POST /v1/extract`.
submit_jobWhat to send
textstringrequired- The document's text, UTF-8, up to 1,000,000 characters.
schema_namestringoptional- A built-in schema, such as `administrative_document`. The other fields of `POST /v1/extract/schema` work here too.
What you get back
202 AcceptedReceived — it is in line to be processed.400 Bad RequestSomething in what you sent was wrong or missing. The answer says which part.401 UnauthorizedThe API key or access token is missing, mistyped or no longer valid. Access tokens expire after 15 minutes — refresh it and send the new one.403 ForbiddenThe key works, but it was made for another product.402 Payment RequiredThe account is out of credits. Buy more in the dashboard, or turn on automatic top-up.429 Too Many RequestsToo many requests in a short time, or the key has reached the monthly limit set on it. Wait the number of seconds given in `Retry-After`, then try again.500 Internal Server ErrorSomething went wrong on our side. It is safe to send the same request again.503 Service UnavailableThe queue is full, or the dashboard that checks keys could not be reached. Try again a little later.
What you send
curl -X POST https://api2.belumind.com/clausa/v1/jobs/schema \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "ỦY BAN NHÂN DÂN TỈNH THANH VÂN\nSố: 1482/QD-UBND\n…", "schema_name": "administrative_document" }'
What you get back
{
"id": "8c41f2a0d3b94e6f9a1c5b7e2d40f318",
"kind": "schema",
"status": "queued",
"queue_position": 1,
"created_at": 1774512000.5,
"started_at": null,
"finished_at": null,
"progress": {
"chunks_done": 0,
"chunks_total": null
},
"error": null,
"result": null
}Try it
Try it
Example modePOST https://api2.belumind.com/clausa/v1/jobs/schemaThe platform is in early access, so this box shows the example answer instead of contacting the live service. Ask us for a key and the same box will send real requests.
/v1/jobs/{job_id}clausa:extractCheck a background job
Shows where a job is — `queued`, `running`, `done`, `failed` or `cancelled` — and how many chunks are read so far. Once it is `done`, `result` holds the same JSON the synchronous endpoint would have returned. `DELETE /v1/jobs/{job_id}` cancels a job that is still queued.
get_jobSettings in the address
job_idstringrequired- The `id` returned by `POST /v1/jobs/schema` or `POST /v1/jobs/extract`.
What you get back
200 OKIt worked. You get back what the example shows.400 Bad RequestSomething in what you sent was wrong or missing. The answer says which part.401 UnauthorizedThe API key or access token is missing, mistyped or no longer valid. Access tokens expire after 15 minutes — refresh it and send the new one.403 ForbiddenThe key works, but it was made for another product.402 Payment RequiredThe account is out of credits. Buy more in the dashboard, or turn on automatic top-up.429 Too Many RequestsToo many requests in a short time, or the key has reached the monthly limit set on it. Wait the number of seconds given in `Retry-After`, then try again.500 Internal Server ErrorSomething went wrong on our side. It is safe to send the same request again.503 Service UnavailableThe queue is full, or the dashboard that checks keys could not be reached. Try again a little later.
What you send
curl -X GET https://api2.belumind.com/clausa/v1/jobs/{job_id} \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN"
What you get back
{
"id": "8c41f2a0d3b94e6f9a1c5b7e2d40f318",
"kind": "schema",
"status": "done",
"queue_position": null,
"created_at": 1774512000.5,
"started_at": 1774512001.1,
"finished_at": 1774512019.8,
"progress": {
"chunks_done": 212,
"chunks_total": 212
},
"error": null,
"result": {
"result": {
"document_number": "1482/QĐ-UBND",
"issuing_authority": "ỦY BAN NHÂN DÂN TỈNH THANH VÂN",
"issue_date": "2026-03-18",
"signer": "Trần Minh Khải",
"signer_title": "Phó Chủ tịch",
"legal_bases": [
"Luật Lưu trữ",
"Nghị định số 118/2024/NĐ-CP"
]
},
"warnings": [],
"device": "mps",
"seconds": 18.7
}
}Try it
Try it
Example modeGET https://api2.belumind.com/clausa/v1/jobs/The platform is in early access, so this box shows the example answer instead of contacting the live service. Ask us for a key and the same box will send real requests.
/v1/labelsclausa:extractList the labels Clausa knows best
The entity and link labels Clausa was trained on — use them in `POST /v1/extract` for the best accuracy. When you ask for a link, Clausa also looks for the labels in its `tail_default`. Needs no key, like `GET /v1/schemas` and `GET /v1/examples`.
list_labelsWhat you get back
200 OKIt worked. You get back what the example shows.400 Bad RequestSomething in what you sent was wrong or missing. The answer says which part.401 UnauthorizedThe API key or access token is missing, mistyped or no longer valid. Access tokens expire after 15 minutes — refresh it and send the new one.403 ForbiddenThe key works, but it was made for another product.402 Payment RequiredThe account is out of credits. Buy more in the dashboard, or turn on automatic top-up.429 Too Many RequestsToo many requests in a short time, or the key has reached the monthly limit set on it. Wait the number of seconds given in `Retry-After`, then try again.500 Internal Server ErrorSomething went wrong on our side. It is safe to send the same request again.503 Service UnavailableThe queue is full, or the dashboard that checks keys could not be reached. Try again a little later.
What you send
curl -X GET https://api2.belumind.com/clausa/v1/labels \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN"
What you get back
{
"entity_labels": [
"văn bản",
"số hiệu văn bản",
"tổ chức",
"người",
"chức vụ",
"ngày",
"địa điểm",
"điều khoản",
"đối tượng áp dụng",
"số lượng",
"thời hạn",
"giấy tờ"
],
"relation_labels": [
{
"name": "ban hành bởi",
"tail_default": [
"tổ chức"
]
},
{
"name": "ban hành ngày",
"tail_default": [
"ngày"
]
},
{
"name": "giữ chức",
"tail_default": [
"chức vụ"
]
},
{
"name": "thuộc tổ chức",
"tail_default": [
"tổ chức"
]
},
{
"name": "thay thế",
"tail_default": [
"văn bản"
]
},
{
"name": "bãi bỏ",
"tail_default": [
"văn bản"
]
},
{
"name": "ký",
"tail_default": [
"văn bản",
"số hiệu văn bản"
]
}
]
}Try it
Try it
Example modeGET https://api2.belumind.com/clausa/v1/labelsThe platform is in early access, so this box shows the example answer instead of contacting the live service. Ask us for a key and the same box will send real requests.
Use with an AI assistant
Connected to an AI assistant, Clausa lets it read a stack of official documents and answer questions about how they relate — which decision replaced which, who signed it, which law it is based on — quoting the exact details instead of retelling the text. Because Clausa runs on your own servers, the documents stay inside your organisation.
You ask
“Which of these decisions are still in force, and what did 1482/QĐ-UBND replace?”
The assistant
- 01Sends the text of each document to Clausa
- 02Follows which documents replace or cancel others
- 03Answers with document numbers and signers, and points out any detail Clausa was not sure about
{
"mcpServers": {
"clausa": {
"url": "https://mcp2.belumind.com/clausa",
"headers": {
"X-API-Key": "bm_live_7f3c…",
"Authorization": "Bearer eyJhbGciOi…"
}
}
}
}When something goes wrong
When a request fails, you get a standard error number and a short code that your software can act on, next to a plain message for people to read. Each request can carry an Idempotency-Key, so sending it again after a problem on our side is safe — it won't be done twice.
{
"error": {
"code": "invalid_parameter",
"message": "`url` must be a reachable http(s) URL.",
"param": "url",
"request_id": "req_4d91c0b7"
}
}Ready to use it for real?
While the platform is in early access, the "Try it" box shows example answers. Tell us what you are building and we will get you a key.