post_vouchers_batch_requests_by_id_decide

Changes data · you confirm first

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

ArgumentTypeDescription
idpathstring (uuid)requiredId of the batch held in REQUESTED status.
bodyJSONobjectrequiredThe request body, as a JSON object. Its fields are listed below.

Fields of body

FieldTypeDescription
approvedQuantityintegerGrant fewer than asked. Must be a positive integer; capped at the requested quantity by the DAL. Omitted approves the full request.
decision"APPROVE" | "DENY"requiredExact match, case-sensitive. Anything else answers 400.
expiresAtinteger | stringExpiry 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.
reasonstringRecorded 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.

json
{
  "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"
      }
    }
  }
}
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 200) the tool returns one text item holding the API's JSON, pretty-printed.

The decision was recorded (and, on APPROVE, the vouchers minted).

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

FieldTypeDescription
batchIdstring (uuid)
decision"APPROVE" | "DENY"
quantityintegerVouchers ACTUALLY MINTED — the length of the DAL's voucher list, so 0 on a denial. Not the requested or approved quantity.
statusstringThe batch's new status, e.g. CREATED on approval or DENIED.
totalValueintegerTotal face value minted, in CENTS.
vouchersarray of objectThe FIRST FIVE minted vouchers only — a preview, never the whole batch.
vouchers[].codestring
vouchers[].currencystring
vouchers[].expiresAtintegerEpoch MILLISECONDS.
vouchers[].idstring (uuid)
vouchers[].statestring
vouchers[].valueintegerFace 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.

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.

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_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
  }
}