get_vouchers_scan
Calls GET /api/vouchers/scan as the signed-in person · REST reference
Look a voucher up by its scanned code
Resolves a QR/barcode value to a voucher projection and checks it has not expired. The code is read from code, falling back to qr. Declared before /{id} so the literal path is not captured as a voucher id. WHO SEES WHAT. Any clinic may take any issued voucher, so a caller holding the verify permission (hospital.vouchers.transition) in one of its orgs finds an ISSUED voucher that no clinic has taken yet by its exact code — the voucher it is about to accept. Once a clinic takes it, the code answers only that clinic (and the org holding the voucher, and platform staff); every other code answers 404 exactly like one that does not exist. The projection names the clinic that took the voucher (claimedByOrgId, null while untaken), never the org holding it, and not the beneficiary. This is a lookup by exact code only: GET /api/vouchers lists nothing a clinic has not taken. THE CODE IS READ HOWEVER IT WAS TYPED. A phrase (four words, two digits, two symbols) or a legacy UUID is looked up in its stored form, so capitals, spaces and dash styles do not matter; any other code is looked up as given. When nothing is found and the code is a phrase with a word that is not a voucher word, the answer is a 400 with code VOUCHER_CODE_MISTYPED naming that word and offering the near ones (details.word, details.suggestions as a comma-separated list, possibly empty), so a clinic holding the paper can fix the word. A phrase of valid words that no voucher carries is a 404. A failed lookup is a 4xx only when the input or the caller is refused (a code the DAL cannot read 400, the caller refused 403); anything else is a 500, or a 503 when the DAL cannot be reached, and no upstream text reaches the body.
Arguments
| Argument | Type | Description | |
|---|---|---|---|
codequery | string | The voucher code: a phrase such as otter-lantern42kettle_pebble (symbols -, _, +, =, !; percent-encode it in the query), a legacy UUID, or a custom-format code. Required unless qr is supplied. | |
qrquery | string | Alias for code, used only when code is absent. |
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": "get_vouchers_scan",
"arguments": {}
}
}Result
On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.
The scanned voucher, projected to the fields a scanner needs.
{
"code": "string",
"currency": "string",
"expiresAt": 1,
"id": "11111111-1111-4111-8111-111111111111",
"state": "string",
"value": 1,
"claimedByOrgId": "11111111-1111-4111-8111-111111111111",
"serviceType": "string"
}Fields
| Field | Type | Description |
|---|---|---|
claimedByOrgId | string (uuid) | null | The clinic that took the voucher at verify; null while no clinic has. Only that clinic may take the remaining claim steps. |
code | string | |
currency | string | |
expiresAt | integer | Epoch MILLISECONDS, passed through from the DAL unconverted. |
id | string (uuid) | |
serviceType | string | null | |
state | string | |
value | integer | Face value in CENTS. |
When it fails
A failed call returns isError: true with the API's message as text.
400Neither
codenorqrwas supplied, the voucher has expired, the DAL could not read the code (the generic malformed-input message), or a phrase carries a word that is not a voucher word —codeis thenVOUCHER_CODE_MISTYPEDanddetailsholdswordandsuggestions(comma-separated, possibly empty).403The caller is not platform staff and holds a voucher feature in no organization, or the DAL refused the caller.
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": "get_vouchers_scan",
"description": "GET /api/vouchers/scan — Resolves a QR/barcode value to a voucher projection and checks it has not expired. The code is read from `code`, falling back to `qr`. Declared before `/{id}` so the literal path is not captured as a voucher id. WHO SEES WHAT. Any clinic may take any issued voucher, so a caller holding the verify permission (`hospital.vouchers.transition`) in one of its orgs finds an ISSUED voucher that no clinic has taken yet by its exact code — the voucher it is about to accept. Once a clinic takes it, the code answers only that clinic (and the org holding the voucher, and platform staff); every other code answers 404 exactly like one that does not exist. The projection names the clinic that took the voucher (`claimedByOrgId`, null while untaken), never the org holding it, and not the beneficiary. This is a lookup by exact code only: `GET /api/vouchers` lists nothing a clinic has not taken. THE CODE IS READ HOWEVER IT WAS TYPED. A phrase (four words, two digits, two symbols) or a legacy UUID is looked up in its stored form, so capitals, spaces and dash styles do not matter; any other code is looked up as given. When nothing is found and the code is a phrase with a word that is not a voucher word, the answer is a 400 with code `VOUCHER_CODE_MISTYPED` naming that word and offering the near ones (`details.word`, `details.suggestions` as a comma-separated list, possibly empty), so a clinic holding the paper can fix the word. A phrase of valid words that no voucher carries is a 404. A failed lookup is a 4xx only when the input or the caller is refused (a code the DAL cannot read 400, the caller refused 403); anything else is a 500, or a 503 when the DAL cannot be reached, and no upstream text reaches the body.",
"inputSchema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The voucher code: a phrase such as `otter-lantern42kettle_pebble` (symbols `-`, `_`, `+`, `=`, `!`; percent-encode it in the query), a legacy UUID, or a custom-format code. Required unless `qr` is supplied."
},
"qr": {
"type": "string",
"description": "Alias for `code`, used only when `code` is absent."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false
}
}