Exam version mixer API
Shuffle questions and options into N exam versions with codes (mã đề) and answer keys, reproducible from a seed. JSON or a zip of .docx exams.
Send the questions returned by /v1/vn-quiz-parse (or the Word / text exam itself) and get versions exam versions, each with its code (mã đề: random 3-digit codes, code_start=101 for 101, 102… or your own codes), the questions and options in a new order, the mapping back to the original numbering and option letters, and the answer key. answer_table lists the answer of every question for every code, ready to print or to load into a grading app.
The rules teachers expect: questions move only inside their part (PHẦN I, II, III stay in order, numbering restarts in each part when the original does), questions of a reading passage stay together, options such as "Tất cả đều đúng" or "Không có đáp án nào" keep their place, and a question whose options refer to other letters ("Cả A và B") keeps its option order. True-false statements are not shuffled unless shuffle_statements=true. The same seed always gives the same versions, so a mix can be rebuilt later.
format=docx returns a zip with one .docx per code (header with school, title, subject, time and the code; images kept), dap_an.docx (answer table) and dap_an.csv.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
questions | body | array | no | questions from /v1/vn-quiz-parse (with sections, groups, images if any). | |
file | body | file | no | Or the exam as .docx / text (text), parsed like vn-quiz-parse. | |
versions | body | number | no | 4 | Number of exam versions (1–50). |
codes | body | array | no | Your exam codes, e.g. ["101","102"] (else random 3-digit codes or code_start). | |
code_start | body | number | no | Sequential codes from this number (101, 102…). | |
seed | body | string | no | Seed for a reproducible mix (random when omitted, returned). | |
shuffle_questions | body | boolean | no | true | Shuffle questions inside each part. |
shuffle_options | body | boolean | no | true | Shuffle options A–D. |
format | body|query | string | no | json | json, docx (zip of .docx exams + answer key) or docx_base64. |
header | body | object | no | Exam header for .docx: school, department, title, subject, time. |
Example
curl -X POST "https://apibox.io.vn/v1/vn-exam-mix" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Câu 1. Thủ đô của Việt Nam là\nA. TP. Hồ Chí Minh\t*B. Hà Nội\nC. Đà Nẵng\tD. Huế\nCâu 2. 2 + 2 = ?\nA. 3\nB. 4\nC. 5\nD. 6\nĐáp án: B\nLời giải: 2 + 2 = 4.","versions":2,"seed":"demo-2026","code_start":101}'const res = await fetch('https://apibox.io.vn/v1/vn-exam-mix', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Câu 1. Thủ đô của Việt Nam là\nA. TP. Hồ Chí Minh\t*B. Hà Nội\nC. Đà Nẵng\tD. Huế\nCâu 2. 2 + 2 = ?\nA. 3\nB. 4\nC. 5\nD. 6\nĐáp án: B\nLời giải: 2 + 2 = 4.",
"versions": 2,
"seed": "demo-2026",
"code_start": 101
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://apibox.io.vn/v1/vn-exam-mix",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"text": "Câu 1. Thủ đô của Việt Nam là\nA. TP. Hồ Chí Minh\t*B. Hà Nội\nC. Đà Nẵng\tD. Huế\nCâu 2. 2 + 2 = ?\nA. 3\nB. 4\nC. 5\nD. 6\nĐáp án: B\nLời giải: 2 + 2 = 4.", "versions": 2, "seed": "demo-2026", "code_start": 101},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/vn-exam-mix');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"text":"Câu 1. Thủ đô của Việt Nam là\\nA. TP. Hồ Chí Minh\\t*B. Hà Nội\\nC. Đà Nẵng\\tD. Huế\\nCâu 2. 2 + 2 = ?\\nA. 3\\nB. 4\\nC. 5\\nD. 6\\nĐáp án: B\\nLời giải: 2 + 2 = 4.","versions":2,"seed":"demo-2026","code_start":101}',
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"seed": "demo-2026",
"version_count": 2,
"codes": [
"101",
"102"
],
"question_count": 2,
"settings": {
"shuffle_questions": true,
"shuffle_options": true,
"shuffle_statements": false,
"numbering_restarts_per_part": false
},
"answer_table": [
[
"Câu",
"101",
"102"
],
[
"1",
"D",
"A"
],
[
"2",
"D",
"B"
]
],
"versions": [
{
"code": "101",
"questions": [
{
"number": 1,
"original_number": 1,
"section": 0,
"type": "multiple_choice",
"points": null,
"stem": "Thủ đô của Việt Nam là",
"options": [
{
"label": "A",
"text": "TP. Hồ Chí Minh",
"original_label": "A"
},
{
"label": "B",
"text": "Huế",
"original_label": "D"
},
{
"label": "C",
"text": "Đà Nẵng",
"original_label": "C"
},
{
"label": "D",
"text": "Hà Nội",
"original_label": "B"
}
],
"answer": [
"D"
],
"answer_text": null,
"group": null
},
{
"…": "…"
}
],
"answer_key": "1.D 2.D"
},
{
"code": "102",
"questions": [
{
"…": "…"
}
],
"answer_key": "1.A 2.B"
}
],
"note": "Same seed + same questions + same codes = same versions. Options such as \"Tất cả đều đúng\" keep their position; questions whose options refer to other letters (\"Cả A và B\") keep their option order; reading groups stay together."
}
Use cases
- Print several exam codes for a class without desktop mixers
- Generate answer keys for an optical-mark or app grader
- Run online tests where each student gets a shuffled version
- Rebuild a past mix from its seed when a key is lost
FAQ
Can I rebuild the same versions later?
Yes. Keep the seed returned with the result: the same seed, questions and codes always give the same versions.
Which options are never moved?
Options like "Tất cả đều đúng", "Cả A và B", "Không có phương án nào" stay at their position; when an option names other letters, the whole question keeps its order.
Does the .docx keep formulas?
Text, images and the question structure are kept; Word equations become plain text. Edit the generated files if you need special formatting.
Related APIs
Image Metadata & EXIF
Read image dimensions, format, EXIF camera data, capture settings and GPS location from JPEG, PNG, WebP, HEIC, AVIF, GIF and more – upload or URL.
PDFPDF Metadata
Read PDF metadata: page count, title, author, creator, producer, dates, PDF version, encryption, form fields and the size of each page (A4, Letter…).
PDF₫Quote & Receipt PDF
Generate clean PDF quotations, receipts, orders and simple invoices from JSON, with Vietnamese text, VAT, totals in words and a VietQR code for payment.