post_vouchers_by_id_verify
Calls POST /api/vouchers/{id}/verify as the signed-in person · REST reference
Claim step 1 — take a scanned voucher for the caller's clinic
Transitions ISSUED → VERIFIED and records claimedByOrgId, which binds the voucher to the clinic that took it: from here on only that clinic may take the remaining claim steps, and approval pays it. ANY clinic may take ANY issued voucher — it is a bearer instrument, and the distributor or platform holding it has no say — so the clinic is the CALLER's own: an org in which the caller holds execute:TransitionVoucherCommand (hospital.vouchers.transition; a clinic's owner holds it, a member once the owner delegates it). A caller who holds it in one clinic sends no body; one who holds it in several names the clinic in orgId, which must be one of them. ONLY a clinic's own staff claim: platform staff are refused (403) — PFF approves and pays claims, it does not make them — and the DAL decides the same (platform authority does not stand in on the claim path). The write runs as the caller (their bearer is forwarded) in a compare-and-set, so the DAL's command gate pins the permission to that clinic and, of two clinics racing for one voucher, exactly one wins.
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 | |
|---|---|---|---|
orgId | string (uuid) | The clinic taking the voucher. Needed only when the caller verifies for more than one clinic; it must be a clinic the caller may verify for. |
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_verify",
"arguments": {
"id": "11111111-1111-4111-8111-111111111111",
"body": {
"orgId": "11111111-1111-4111-8111-111111111111"
}
}
}
}Result
On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.
The voucher after the transition, as the DAL's TransitionVoucher selection returns it — WITHOUT claimedByOrgId, the very field this call just wrote.
{
"code": "string",
"currency": "string",
"expiresAt": 1,
"id": "11111111-1111-4111-8111-111111111111",
"state": "ACTIVE",
"value": 1,
"assignedToOrgId": "11111111-1111-4111-8111-111111111111",
"batchId": "11111111-1111-4111-8111-111111111111",
"issuedAt": 1,
"issuedToEmail": "string",
"issuedToPhone": "string",
"maxPayout": 1,
"procedure": "string",
"replacedByVoucherId": "11111111-1111-4111-8111-111111111111"
}Fields
| Field | Type | Description |
|---|---|---|
assignedToOrgId | string (uuid) | null | |
batchId | string (uuid) | null | |
code | string | |
currency | string | |
expiresAt | integer | Epoch MILLISECONDS. |
id | string (uuid) | |
issuedAt | integer | null | Epoch MILLISECONDS. |
issuedToEmail | string | null | |
issuedToPhone | string | null | |
maxPayout | integer | null | Catalog face-value cap in CENTS. |
procedure | string | null | |
replacedByVoucherId | string (uuid) | null | The voucher the DAL minted to replace this one in its batch, if any. |
serviceType | string | null | |
species | string | null | |
state | "ACTIVE" | "APPROVED" | "ASSIGNED" | "AVAILABLE" | "CLAIMED" | "CREATED" | … (17 values) | A voucher's lifecycle state, as the DAL's VoucherState enum names it. |
value | integer | Face value in CENTS. |
voidReason | string | null |
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 caller verifies for more than one clinic and named none in
orgId.403The caller may verify vouchers for no clinic, or for none named
orgId, or belongs to the clinic without the permission to verify vouchers for it, or is platform staff — who approve claims and never make them (the message says which).404No such resource — or none this caller may see.
409Another clinic has already accepted this voucher (including one that won a race for it a moment earlier), or its state cannot move to VERIFIED — it is not ISSUED.
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_verify",
"description": "POST /api/vouchers/{id}/verify — Transitions ISSUED → VERIFIED and records `claimedByOrgId`, which binds the voucher to the clinic that took it: from here on only that clinic may take the remaining claim steps, and approval pays it. ANY clinic may take ANY issued voucher — it is a bearer instrument, and the distributor or platform holding it has no say — so the clinic is the CALLER's own: an org in which the caller holds `execute:TransitionVoucherCommand` (`hospital.vouchers.transition`; a clinic's owner holds it, a member once the owner delegates it). A caller who holds it in one clinic sends no body; one who holds it in several names the clinic in `orgId`, which must be one of them. ONLY a clinic's own staff claim: platform staff are refused (403) — PFF approves and pays claims, it does not make them — and the DAL decides the same (platform authority does not stand in on the claim path). The write runs as the caller (their bearer is forwarded) in a compare-and-set, so the DAL's command gate pins the permission to that clinic and, of two clinics racing for one voucher, exactly one wins.\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: { orgId: string (The clinic taking the voucher.) }"
}
},
"required": [
"id"
]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": false,
"openWorldHint": false
}
}