post_vouchers_batch_requests_by_id_decide
Calls POST /api/vouchers/batch-requests/{id}/decide as the signed-in person · REST reference
Approve or deny a voucher-batch request
PFF's ruling on a REQUESTED batch. Approving MINTS the vouchers into that batch and is gated on the voucher-pool balance at this moment, inside the DAL transaction — a request that was affordable when filed can be refused now with a 400. Denying mints nothing and returns quantity: 0. The path id is the BATCH id (the request is the batch), not a separate request id. Gated by the platform-staff middleware, not by a dedicated decide permission.
Arguments
| Argument | Type | Description | |
|---|---|---|---|
idpath | string (uuid) | required | Id of the batch held in REQUESTED status. |
bodyJSON | object | required | The request body, as a JSON object. Its fields are listed below. |
Fields of body
| Field | Type | Description | |
|---|---|---|---|
approvedQuantity | integer | Grant fewer than asked. Must be a positive integer; capped at the requested quantity by the DAL. Omitted approves the full request. | |
decision | "APPROVE" | "DENY" | required | Exact match, case-sensitive. Anything else answers 400. |
expiresAt | integer | string | Expiry for the minted vouchers, as epoch MILLISECONDS or a Date.parse-able string. Omitted leaves it to the DAL; an unparseable string becomes 180 days from now. | |
reason | string | Recorded with the decision; the denial rationale. |
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_batch_requests_by_id_decide",
"arguments": {
"id": "11111111-1111-4111-8111-111111111111",
"body": {
"decision": "APPROVE",
"approvedQuantity": 1,
"expiresAt": 1,
"reason": "string"
}
}
}
}Result
On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.
The decision was recorded (and, on APPROVE, the vouchers minted).
{
"batchId": "11111111-1111-4111-8111-111111111111",
"decision": "APPROVE",
"quantity": 1,
"status": "string",
"totalValue": 1,
"vouchers": [
{
"code": "string",
"currency": "string",
"expiresAt": 1,
"id": "11111111-1111-4111-8111-111111111111",
"state": "string",
"value": 1
}
]
}Fields
| Field | Type | Description |
|---|---|---|
batchId | string (uuid) | |
decision | "APPROVE" | "DENY" | |
quantity | integer | Vouchers ACTUALLY MINTED — the length of the DAL's voucher list, so 0 on a denial. Not the requested or approved quantity. |
status | string | The batch's new status, e.g. CREATED on approval or DENIED. |
totalValue | integer | Total face value minted, in CENTS. |
vouchers | array of object | The FIRST FIVE minted vouchers only — a preview, never the whole batch. |
vouchers[].code | string | |
vouchers[].currency | string | |
vouchers[].expiresAt | integer | Epoch MILLISECONDS. |
vouchers[].id | string (uuid) | |
vouchers[].state | string | |
vouchers[].value | integer | Face value in CENTS. |
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.
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_batch_requests_by_id_decide",
"description": "POST /api/vouchers/batch-requests/{id}/decide — PFF's ruling on a REQUESTED batch. Approving MINTS the vouchers into that batch and is gated on the voucher-pool balance at this moment, inside the DAL transaction — a request that was affordable when filed can be refused now with a 400. Denying mints nothing and returns `quantity: 0`. The path id is the BATCH id (the request is the batch), not a separate request id. Gated by the platform-staff middleware, not by a dedicated decide permission.\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": "Id of the batch held in REQUESTED status."
},
"body": {
"type": "string",
"description": "The JSON request body: { approvedQuantity: integer (Grant fewer than asked.); decision*: one of \"APPROVE\" | \"DENY\" (Exact match, case-sensitive.); expiresAt: integer or string (Expiry for the minted vouchers, as epoch MILLISECONDS or a Date.parse-able string.); reason: string (Recorded with the decision; the denial rationale.) }"
}
},
"required": [
"id",
"body"
]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": false,
"openWorldHint": false
}
}