post_vouchers_by_id_reprint

Changes data · you confirm first

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

ArgumentTypeDescription
idpathstring (uuid)requiredVoucher id.
bodyJSONobjectThe request body, as a JSON object. Its fields are listed below.

Fields of body

FieldTypeDescription
reasonstringWhy 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.

json
{
  "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"
      }
    }
  }
}
Confirmation
The client shows the person the exact request and waits. Nothing runs until they tick Make this change. See Reading and changing.

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.

json
{
  "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

FieldTypeDescription
batchIdstring (uuid)
poolCommittedintegerCENTS the replaced VOIDED/EXPIRED vouchers re-committed from the voucher pool. 0 when none was dead.
printobject
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.errorstringCurated 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.jobIdintegerThe 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.vouchersintegerHow many vouchers the print covered. Absent when none was attempted.
replacedintegerVOIDED or EXPIRED vouchers replaced (now VOIDED_REPRINTED).
reprintsarray of objectEvery reprinted voucher and the voucher minted to take its place.
reprints[].replacementobject
reprints[].replacement.codestring
reprints[].replacement.expiresAtintegerEpoch MILLISECONDS.
reprints[].replacement.idstring (uuid)
reprints[].voucherobject
reprints[].voucher.codestring
reprints[].voucher.idstring (uuid)
voidedintegerLive 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.

400

The request was malformed or failed a guard.

403

Authenticated, but the caller holds none of the required permissions.

404

No such resource — or none this caller may see.

409

The 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.

json
{
  "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
  }
}