post_vouchers_by_id_reprint
Calls POST /api/vouchers/{id}/reprint as the signed-in person · REST reference
Reprint one physical voucher — a new code replaces it, and is printed
Paper again for a voucher, under a NEW code. In one DAL transaction the voucher becomes VOIDED_REPRINTED and a replacement is minted into its batch and linked to it (replacedByVoucherId / replacesVoucherId); the replacement is then sent to the office printer, and an accepted print issues it. Takes an UNUSED voucher: a live one (CREATED, ASSIGNED or ISSUED, printed or not — its code stops working), or a VOIDED or EXPIRED one that was never replaced (409 NO_EMPTY_SLOT when its batch already holds every voucher it owes). Refused with 409 ALREADY_REPLACED for a VOIDED_REPRINTED voucher or one already replaced (the message names the replacement to reprint instead — one voucher never has two), and 409 USED from VERIFIED on. The replacement keeps its predecessor's expiry, unless the predecessor is EXPIRED or its date has passed: then it gets a fresh 180-day term. Replacing a VOIDED or EXPIRED voucher re-commits its value from the voucher pool — 400 when the pool cannot cover it; a live voucher's budget simply passes to its replacement. Only PHYSICAL batches (400 otherwise), and only on a server with a printer (503 PRINTER_NOT_CONFIGURED, checked first — the old paper would stop working with no new paper coming). The reprint stands whatever the printer then does: print reports it, and a failed print leaves the replacement PRINT_FAILED for Retry print. Requires execute:CreateVoucherBatchCommand AND execute:RevokeVoucherCommand; platform staff are admitted as on every gate.
Arguments
| Argument | Type | Description | |
|---|---|---|---|
idpath | string (uuid) | required | Voucher id. |
bodyJSON | object | The request body, as a JSON object. Its fields are listed below. |
Fields of body
| Field | Type | Description | |
|---|---|---|---|
reason | string | Why it is reprinted — recorded as reprintReason on the old voucher. |
Example call
A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "post_vouchers_by_id_reprint",
"arguments": {
"id": "11111111-1111-4111-8111-111111111111",
"body": {
"reason": "string"
}
}
}
}Result
On success (HTTP 201) the tool returns one text item holding the API's JSON, pretty-printed.
Reprinted. print is what the printer did with the replacement.
{
"batchId": "11111111-1111-4111-8111-111111111111",
"poolCommitted": 1,
"print": {
"status": "SUBMITTED",
"code": "PRINTER_UNREACHABLE",
"error": "string",
"jobId": 1,
"vouchers": 1
},
"replaced": 1,
"reprints": [
{
"replacement": {},
"voucher": {}
}
],
"voided": 1
}Fields
| Field | Type | Description |
|---|---|---|
batchId | string (uuid) | |
poolCommitted | integer | CENTS the replaced VOIDED/EXPIRED vouchers re-committed from the voucher pool. 0 when none was dead. |
print | object | |
print.code | "PRINTER_UNREACHABLE" | "PRINTER_AUTH_REJECTED" | "PRINTER_TLS_UNVERIFIED" | "PRINTER_REJECTED_JOB" | "PRINTER_NOT_CONFIGURED" | "PRINT_FAILED" | … (7 values) | Machine-readable reason for error. |
print.error | string | Curated and safe to show. On FAILED and NOT_CONFIGURED; on SUBMITTED only when the job was accepted but could not be recorded — its vouchers were then neither marked as sent nor issued. |
print.jobId | integer | The printer's job id, on SUBMITTED. |
print.status | "SUBMITTED" | "FAILED" | "NOT_REQUESTED" | "NOT_CONFIGURED" | SUBMITTED: the printer ACCEPTED the job (accepted, not paper confirmed), and the vouchers it carried are ISSUED — unless code is PRINT_STATUS_NOT_RECORDED. FAILED: nothing was printed or issued. NOT_REQUESTED: no print was asked for, or the batch is DIGITAL. NOT_CONFIGURED: a print was asked for and this server has no printer. |
print.vouchers | integer | How many vouchers the print covered. Absent when none was attempted. |
replaced | integer | VOIDED or EXPIRED vouchers replaced (now VOIDED_REPRINTED). |
reprints | array of object | Every reprinted voucher and the voucher minted to take its place. |
reprints[].replacement | object | |
reprints[].replacement.code | string | |
reprints[].replacement.expiresAt | integer | Epoch MILLISECONDS. |
reprints[].replacement.id | string (uuid) | |
reprints[].voucher | object | |
reprints[].voucher.code | string | |
reprints[].voucher.id | string (uuid) | |
voided | integer | Live vouchers taken out of circulation (now VOIDED_REPRINTED). |
When it fails
A failed call returns isError: true with the API's message as text. A change the person declines, or lets time out, also comes back this way and nothing changes.
400The request was malformed or failed a guard.
403Authenticated, but the caller holds none of the required permissions.
404No such resource — or none this caller may see.
409The resource is not in a state that allows this operation.
What the model is shown
This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.
{
"name": "post_vouchers_by_id_reprint",
"description": "POST /api/vouchers/{id}/reprint — Paper again for a voucher, under a NEW code. In one DAL transaction the voucher becomes VOIDED_REPRINTED and a replacement is minted into its batch and linked to it (`replacedByVoucherId` / `replacesVoucherId`); the replacement is then sent to the office printer, and an accepted print issues it. Takes an UNUSED voucher: a live one (CREATED, ASSIGNED or ISSUED, printed or not — its code stops working), or a VOIDED or EXPIRED one that was never replaced (409 `NO_EMPTY_SLOT` when its batch already holds every voucher it owes). Refused with 409 `ALREADY_REPLACED` for a VOIDED_REPRINTED voucher or one already replaced (the message names the replacement to reprint instead — one voucher never has two), and 409 `USED` from VERIFIED on. The replacement keeps its predecessor's expiry, unless the predecessor is EXPIRED or its date has passed: then it gets a fresh 180-day term. Replacing a VOIDED or EXPIRED voucher re-commits its value from the voucher pool — 400 when the pool cannot cover it; a live voucher's budget simply passes to its replacement. Only PHYSICAL batches (400 otherwise), and only on a server with a printer (503 `PRINTER_NOT_CONFIGURED`, checked first — the old paper would stop working with no new paper coming). The reprint stands whatever the printer then does: `print` reports it, and a failed print leaves the replacement PRINT_FAILED for Retry print. Requires `execute:CreateVoucherBatchCommand` AND `execute:RevokeVoucherCommand`; platform staff are admitted as on every gate.\n\nThis changes data. The person is asked to confirm it before it runs, and nothing happens if they decline.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Voucher id."
},
"body": {
"type": "string",
"description": "The JSON request body: { reason: string (Why it is reprinted — recorded as `reprintReason` on the old voucher.) }"
}
},
"required": [
"id"
]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": false,
"openWorldHint": false
}
}