Developer guide
Send a Vietnamese contract — a PDF whose text can be selected, a Word file, a text file, or just paste the text — and get back the clauses to read carefully, where they are on the page, and what to ask the other side. Each clause is checked against nine common risks, penalties and interest are checked against legal limits, and blanks left unfilled are flagged. Results are suggestions — they do not replace a lawyer or make the decision for you.
Address for your software (API)
https://api.belumind.com/virgoAddress for AI assistants (MCP)
https://mcp.belumind.com/virgo- Input
- PDF, Word, text file or pasted text
- Speed
- ~300 ms / page
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.
contracts:analyzeX-API-Key: bm_live_7f3c… Authorization: Bearer eyJhbGciOi… Content-Type: application/json
/v1/analyzecontracts:analyzeReview a contract file
Splits the contract into clauses and returns the ones worth attention. Each one comes with its risk group (`code`), a level — `doc_ky` (read carefully) or `xem_xet` (worth a look) — the exact sentence behind it, its position on the page for highlighting, and advice: what to ask, what to note, and a clause you could add. Word and text files have no pages, so no positions are given; a scanned PDF whose text cannot be selected comes back empty, with a note in `document.warnings`. Sending the same file again soon gets an instant answer (`cached: true`). `POST /v1/analyze/stream` takes the same file and sends results page by page as they are ready, ending with this same result. Through MCP, `analyze_contract` gives each clause an id such as `c3`; `get_clause` returns that clause's full text, explanation, legal basis and advice, using the `analysis_id` printed at the end of the analysis.
analyze_contractWhat to send
filefilerequired- The contract file: a PDF with selectable text, a Word .docx, or a .txt / .md text file. Old .doc files are not accepted (error 415).
include_allboolean · queryoptional- Also list clauses that have no suggestion. Off by default.
compactboolean · queryoptional- Send a shorter answer without the long explanations and legal references — you can look them up by `code` with `GET /v1/risk-types`. Between 20% and 65% smaller: the saving is largest on short contracts. Off by default.
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://api.belumind.com/virgo/v1/analyze \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN" \ -F "file=@hop_dong_lao_dong.pdf"
What you get back
{
"version": "1.11.0",
"model_version": "v1.11",
"document": {
"file_name": "hop_dong_lao_dong.pdf",
"pages": [
{
"index": 0,
"width": 595.3,
"height": 841.9,
"rotation": 0
}
],
"n_clauses": 2,
"n_chars": 132,
"is_credit_institution": false,
"is_labour_contract": false,
"warnings": [],
"domain": "dieu_kien_giao_dich"
},
"summary": {
"n_flagged_clauses": 1,
"n_blank_fields": 1,
"n_capped": 0,
"by_risk": {
"DON_PHUONG_CHAM_DUT": {
"doc_ky": 1,
"xem_xet": 0
},
"CHUA_DIEN": {
"doc_ky": 0,
"xem_xet": 1
}
},
"levels": {
"doc_ky": "Nên đọc kỹ",
"xem_xet": "Nên xem xét"
}
},
"clauses": [
{
"id": "c0",
"index": 0,
"heading": "Điều 3. Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"text": "Điều 3. Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"page_start": 0,
"page_end": 0,
"max_level": "doc_ky",
"risks": [
{
"code": "DON_PHUONG_CHAM_DUT",
"label": "Một bên được đơn phương chấm dứt",
"level": "doc_ky",
"score": 0.9035,
"source": "model",
"evidence": {
"text": "Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"boxes": [
{
"page": 0,
"x0": 72,
"y0": 96.4,
"x1": 523.3,
"y1": 110.2
}
]
}
}
],
"advice": {
"code": "DON_PHUONG_CHAM_DUT",
"label": "Một bên được đơn phương chấm dứt",
"level": "doc_ky",
"card_id": "dpcd_tuy_y",
"title": "Chấm dứt tuỳ ý, không cần lý do",
"ask": [
"Bên kia được chấm dứt trong những trường hợp cụ thể nào? \"Khi có nhu cầu / khi xét thấy cần thiết\" nghĩa là gì?",
"Phải báo trước bao nhiêu ngày, bằng văn bản hay chỉ thông báo?",
"Khi bị chấm dứt sớm, bạn được hoàn lại / bồi thường những khoản nào?"
],
"notes": [
"Quyền chấm dứt không cần căn cứ khiến thời hạn hợp đồng gần như không có giá trị bảo đảm cho bạn.",
"Kiểm tra bạn có quyền chấm dứt tương đương không; nếu chỉ một bên có quyền thì hợp đồng đang lệch."
],
"add_clause": "\"Mỗi bên chỉ được đơn phương chấm dứt Hợp đồng khi bên kia vi phạm nghĩa vụ [liệt kê] và không khắc phục trong [15] ngày kể từ ngày nhận thông báo; trường hợp chấm dứt không do lỗi của bên kia, bên chấm dứt phải báo trước [30] ngày và bồi thường thiệt hại thực tế phát sinh.\"",
"legal_basis": "Điều 428 Bộ luật Dân sự 2015 (đơn phương chấm dứt thực hiện hợp đồng); Điều 25 Luật Bảo vệ quyền lợi người tiêu dùng 2023 (hợp đồng theo mẫu)",
"similarity": 0.9103,
"safe_margin": -0.0315
}
}
],
"disclaimer": "Đây là GỢI Ý các điều khoản nên đọc kỹ, do mô hình máy học tự động đề xuất; không phải tư vấn pháp lý…"
}Try it
Try it
Example modePOST https://api.belumind.com/virgo/v1/analyzeThe 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/analyze/textcontracts:analyzeReview contract text
The same review for text you already have — for example, copied from Word or an email, or read from a scan. The answer looks the same as `/v1/analyze`, except there are no pages: instead, `char_start` / `char_end` say where each part sits in your text. Takes the same `include_all` and `compact` options; the example below uses `compact=true`.
analyze_contractWhat to send
textstringrequired- The full contract text. Text that is too long gives error 413 (`text_too_large`); empty text gives error 422 (`empty_text`).
file_namestringoptional- A name shown back in the result (`document.file_name`). Defaults to `contract.txt`.
include_allboolean · queryoptional- Also list clauses that have no suggestion. Off by default.
compactboolean · queryoptional- Send a shorter answer without the long explanations and legal references — you can look them up by `code` with `GET /v1/risk-types`. Off by default.
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://api.belumind.com/virgo/v1/analyze/text \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "Điều 3. Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.\nĐiều 4. Mức lương: ........ đồng/tháng.", "file_name": "hop_dong_lao_dong.txt" }'
What you get back
{
"version": "1.11.0",
"model_version": "v1.11",
"compact": true,
"document": {
"format": "text",
"file_name": "hop_dong_lao_dong.txt",
"pages": [],
"n_clauses": 2,
"n_chars": 132,
"is_credit_institution": false,
"is_labour_contract": false,
"warnings": [],
"domain": "dieu_kien_giao_dich"
},
"summary": {
"n_flagged_clauses": 1,
"n_blank_fields": 1,
"n_capped": 0,
"by_risk": {
"DON_PHUONG_CHAM_DUT": {
"doc_ky": 1,
"xem_xet": 0
},
"CHUA_DIEN": {
"doc_ky": 0,
"xem_xet": 1
}
},
"levels": {
"doc_ky": "Nên đọc kỹ",
"xem_xet": "Nên xem xét"
}
},
"clauses": [
{
"id": "c0",
"index": 0,
"heading": "Điều 3. Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"text": "Điều 3. Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"char_start": 0,
"char_end": 93,
"boxes": [],
"max_level": "doc_ky",
"risks": [
{
"code": "DON_PHUONG_CHAM_DUT",
"level": "doc_ky",
"score": 0.9035,
"source": "model",
"evidence": {
"text": "Công ty có quyền đơn phương chấm dứt hợp đồng bất cứ lúc nào mà không cần báo trước.",
"char_start": 8,
"char_end": 92,
"boxes": []
}
}
]
},
{
"id": "c1",
"index": 1,
"heading": "Điều 4. Mức lương: ........ đồng/tháng.",
"text": "Điều 4. Mức lương: ........ đồng/tháng.",
"char_start": 93,
"char_end": 132,
"boxes": [],
"max_level": "xem_xet",
"risks": [
{
"code": "CHUA_DIEN",
"level": "xem_xet",
"score": 1,
"source": "rule",
"evidence": {
"text": "1 chỗ chưa điền: Điều 4. Mức lương: đồng/tháng.",
"char_start": 112,
"char_end": 120,
"boxes": []
}
}
]
}
],
"timing_ms": 82
}Try it
Try it
Example modePOST https://api.belumind.com/virgo/v1/analyze/textThe 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/risk-typescontracts:analyzeSee all risk groups
Every risk Virgo checks for, by `code`: its name, what it means, what to check, the law to look at, and whether it is currently switched on. Use it to fill in the details of a shorter (`compact`) answer. It needs both credentials but uses no credits. The example shows three of the thirteen groups.
list_risk_typesWhat 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://api.belumind.com/virgo/v1/risk-types \ -H "X-API-Key: $BELUMIND_API_KEY" \ -H "Authorization: Bearer $BELUMIND_ACCESS_TOKEN"
What you get back
{
"PHAT_VUOT_TRAN_8": {
"label": "Mức phạt vi phạm có thể vượt 8%",
"explanation": "Mức phạt vi phạm được nêu cao hơn 8% giá trị phần nghĩa vụ bị vi phạm. Trần 8% chỉ áp dụng cho hợp đồng thương mại; hợp đồng dân sự do các bên tự thoả thuận.",
"suggestion": "Kiểm tra hợp đồng là thương mại hay dân sự, mức phạt tính trên giá trị nào, và bên kia có chịu mức phạt tương tự không.",
"legal_basis": "Điều 301 Luật Thương mại 2005; Điều 418 Bộ luật Dân sự 2015",
"enabled": true
},
"DON_PHUONG_CHAM_DUT": {
"label": "Một bên được đơn phương chấm dứt",
"explanation": "Một bên được chấm dứt/huỷ hợp đồng, khoá tài khoản hoặc ngừng dịch vụ TUỲ Ý: không cần căn cứ, căn cứ do chính bên đó tự quyết định, hoặc không báo trước/không bồi thường dù bên kia không có lỗi.",
"suggestion": "Hỏi rõ bên kia được chấm dứt trong trường hợp nào, có báo trước bao lâu, và bạn được hoàn tiền / bồi thường gì nếu bị chấm dứt.",
"legal_basis": "Điều 428 Bộ luật Dân sự 2015; Điều 25 Luật Bảo vệ quyền lợi người tiêu dùng 2023",
"enabled": true
},
"CHUA_DIEN": {
"label": "Chưa điền",
"explanation": "Chỗ trống (dòng chấm, \"…\", \"____\") chưa điền thông tin — thường gặp ở mẫu hợp đồng. Đây là nhắc điền thông tin, không phải đánh giá rủi ro của điều khoản.",
"suggestion": "Điền đầy đủ và kiểm tra lại các chỗ trống trước khi ký; không để trống để bên kia tự điền sau.",
"legal_basis": "Điều 398 Bộ luật Dân sự 2015 (nội dung của hợp đồng)",
"enabled": true
}
}Try it
Try it
Example modeGET https://api.belumind.com/virgo/v1/risk-typesThe 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, Virgo becomes a first check on any contract a user shares in the chat: the assistant explains the flagged clauses in plain language and drafts the questions to send. It never says a clause is unlawful — it points at what deserves a closer look. Virgo cannot open files on the user's computer, so the assistant sends it the file itself or the pasted text.
You ask
“Review this employment contract before I sign — what should I ask HR about?”
The assistant
- 01Sends the PDF to Virgo for review
- 02Groups flagged clauses by level: read carefully first, then worth a look
- 03Asks Virgo for the advice on each clause, then drafts follow-up questions with page numbers
{
"mcpServers": {
"virgo": {
"url": "https://mcp.belumind.com/virgo",
"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.