Skip to main content
Glama

Server Details

Passport, ID and MRZ recognition via doc.cheap – Free: 100 documents every month, then $0.01 each

Ownership verified
Status
Healthy
Uptime
99.7% over 23 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

A4.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: check_balance (account credits), delete_scan (remove a specific scan), get_scan (retrieve one scan), list_scans (enumerate scans), scan_document (perform recognition), search_docs (documentation lookup). The descriptions reinforce the boundaries without overlap.

Naming Consistency5/5

All names follow a consistent verb_noun snake_case pattern: check_balance, delete_scan, get_scan, list_scans, scan_document, search_docs. The set is highly uniform and predictable.

Tool Count5/5

Six tools are well-scoped for an API focused on document scanning: one core action, three lifecycle operations (get/list/delete), one account tool, and one documentation tool. No tool feels redundant or missing.

Completeness5/5

The surface covers the full lifecycle: scanning a document (scan_document), retrieving results (get_scan), listing scans (list_scans), deleting scans (delete_scan), checking account usage (check_balance), and searching documentation (search_docs). No obvious gaps or dead ends for the stated domain.

Available Tools

6 tools
check_balanceCheck remaining creditsA
Read-only
Inspect

Return how many credits are left on the account and what the current period has used: the balance, split into this month's free credits (100 every month, drawn first) and the paid credits, the credits spent, and the scan counters broken down by status (recognized, unreadable, no document found, unsupported document, rejected). Takes no arguments and calls GET /v1/usage; under the public sandbox key it answers without calling anything. One recognised document draws one credit, at $0.01; scans that recognised nothing are counted and never charged. Needs a real API key – under the public sandbox key there is no account behind the call, and the answer says so instead of reporting zeros that read like a balance. Use it before working through a batch of documents, or when a scan is refused for lack of credit.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
scansYes
periodYesBounds of the current usage period (UTC calendar month).
credits_spentYesCredits charged within the period.
free_allowanceYesThis month's free credits, drawn before paid credits; null when the account may not draw free credits (its email address is not confirmed, or its free credits were withdrawn) and for a key with no account.
balance_creditsYesCredits currently available to the account: this month's free credits plus the paid credits; null for a key with no account (the public sandbox key).
paid_balance_creditsYesPaid credits: bought or granted to the account, drawn once this month's free credits are used up, and never reset; null only for a key with no account (the public sandbox key).
credits_spent_by_kindYesCredits charged within the period, by the kind that paid.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnlyHint and openWorldHint annotations. It discloses the sandbox behavior (no account, answer says so), the need for a real API key, and the credit/charge logic (one recognized doc costs $0.01, unrecognized scans free), providing rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but efficient; every sentence adds value, from the core result to pricing, sandbox notes, and usage guidance. It is front-loaded with the main purpose, though slightly long for a no-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description doesn't need to detail the return structure. It covers the essential semantics: credit split, spending, scan counters, costs, sandbox behavior, and when to call it. Nothing an agent needs to use it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the baseline is 4. The description adds meaning by explaining what the output represents, but since there are no parameters, there is nothing to elaborate on beyond the schema's empty object.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: returning credit balance and usage details. It names the specific resource (GET /v1/usage) and enumerates the data returned, making it unmistakable from siblings like scan_document and search_docs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it ('before working through a batch of documents, or when a scan is refused for lack of credit') and even covers the sandbox key exception, guiding the agent on appropriate invocation contexts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_scanDelete a stored scanA
DestructiveIdempotent
Inspect

Permanently delete one stored scan now, before its retention window would end. This cannot be undone: the stored result, its history row and its thumbnail are removed, and the scan can no longer be listed, fetched or replayed through its idempotency_key. The credit it drew is not refunded, and this period's usage counters still count it. Input: scan_id – meta.id of a scan_document result, or id of a list_scans row. Output: { id, deleted: true }. Calls DELETE /v1/scans/{id}. Only scans made with a live key under a non-zero retention window are stored, and only until that window ends (retain_hours on the scan, or the account's history-retention setting, one year by default); a scan made with retain_hours 0 was never stored. A key reaches its own account's scans and no other account's. Under a sandbox key – the public one or an account's own sk_sandbox_ key – nothing is stored. Errors: an id that is unknown, belongs to another account, has passed its window or was already deleted is refused as not_found, and nothing is deleted. Use it when someone asks for a document's data to be removed; confirm the id with list_scans or get_scan first, because the deletion is final.

ParametersJSON Schema
NameRequiredDescriptionDefault
scan_idYesThe scan's id: meta.id of the scan_document result, or id of a list_scans row (a lower-case UUID).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
deletedYesAlways true: the stored result is gone and cannot be read back.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the destructiveHint annotation by disclosing exact side effects (result, history row, thumbnail removed), non-refund of credit, continued usage-counter counting, and the not_found error semantics for refused ids. Retention-window and key-scoping rules add operational context the annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The irreversible consequence is front-loaded in the first sentence, and every clause carries operational value. It is long, but the retention and sandbox rules are genuinely non-obvious rather than filler, so trimming would lose meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description still usefully states the return shape ({ id, deleted: true }), and covers side effects, error conditions, retention/sandbox scoping, and pre-call confirmation. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds provenance beyond the schema by mapping scan_id to 'meta.id of a scan_document result, or id of a list_scans row' and noting the id can no longer be replayed via its idempotency_key. The UUID format itself is left to the schema pattern.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource ('Permanently delete one stored scan') and immediately frames it against siblings by describing the removal of the stored result, history row, and thumbnail. An agent can distinguish this from get_scan/list_scans/scan_document without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the triggering condition ('Use it when someone asks for a document's data to be removed') and names the confirmation alternatives ('confirm the id with list_scans or get_scan first'). It also gives the when-not boundary: unknown, other-account, expired, or already-deleted ids are refused.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_scanFetch a stored scan
Read-only
Inspect

Fetch the full result of one stored scan by its id, as it was returned when the document was recognised. Input: scan_id – meta.id of a scan_document result, or id of a list_scans row. Output: the same Scan object scan_document returns (meta, document, holder, fields, mrz and the rest) plus a one-line summary, with two differences: the image crops are never stored, so every images slot is null, and quality reads not_checked. Calls GET /v1/scans/{id}; it never re-runs recognition and never charges a credit. Only scans made with a live key under a non-zero retention window are stored, and only until that window ends (retain_hours on the scan, or the account's history-retention setting, one year by default); a scan made with retain_hours 0 was never stored. A key reaches its own account's scans and no other account's. Under a sandbox key – the public one or an account's own sk_sandbox_ key – nothing is stored. Errors: an id that is unknown, belongs to another account, was made with retain_hours 0 or has passed its window is refused as not_found – the cases are not told apart. Use it to read back a document recognised earlier instead of scanning the image again.

ParametersJSON Schema
NameRequiredDescriptionDefault
scan_idYesThe scan's id: meta.id of the scan_document result, or id of a list_scans row (a lower-case UUID).

Output Schema

ParametersJSON Schema
NameRequiredDescription
mrzYes
metaYes
fieldsYesEvery field the engine extracted off the printed document, re-keyed to our vocabulary – the open set. Always present; empty when nothing was extracted. A field read in more than one language appears once per language, so `name` repeats and only `id` is unique.
holderYes
imagesYes
qualityYes
documentYes
authenticityYes
list_scansList stored scansA
Read-only
Inspect

List the account's stored scans, most recent first, one page at a time. Inputs: the optional limit (1 to 100 rows, default 20) and cursor (the next_cursor of the previous page; omit it for the first page). Output: scans – one row per scan with id, status (recognized, unreadable, no_document_found, unsupported_document or rejected), billed, duration_ms, reference (your own string from the scan) and created_at – and next_cursor, which is null on the last page. A row holds no extracted data; call get_scan with its id for the full result. Calls GET /v1/scans; it never charges a credit. Only scans made with a live key under a non-zero retention window are stored, and only until that window ends (retain_hours on the scan, or the account's history-retention setting, one year by default); a scan made with retain_hours 0 was never stored. A key reaches its own account's scans and no other account's. Under a sandbox key – the public one or an account's own sk_sandbox_ key – nothing is stored. Under the public sandbox key the answer is an empty list, given without calling the API. Errors: a cursor this API did not issue is refused (validation_failed); a key the API does not know is refused (unauthorized). Use it to find a scan made earlier – by its reference or its time – before reading or deleting it.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoRows per page, 1 to 100 (default 20).
cursorNonext_cursor from the previous page; omit it for the first page.

Output Schema

ParametersJSON Schema
NameRequiredDescription
scansYesThe account's scans, most recent first.
next_cursorYesOpaque cursor for the next page: send it back as `cursor` to continue after the last row of this one. Null on the last page.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover read-only/open-world, but the description discloses what matters here: no credit charged, storage requires a live key under a non-zero retention window, retain_hours 0 means never stored, sandbox keys store nothing (public sandbox returns an empty list without an API call), key isolation per account, and the two error cases (validation_failed, unauthorized). This is far beyond what the annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and organized into clear Inputs/Output/Errors segments, so it scans well. It is long and packs retention and key-mode details into run-on sentences, but nearly every clause carries decision-relevant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite an output schema existing, the description covers the non-obvious completeness gaps for this tool: retention expiry, key scoping, sandbox behavior, and error semantics. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the description largely restates it (limit 1–100 default 20, cursor as previous next_cursor). It adds only the paging model, not new format or edge-case semantics beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the account's stored scans'), adds ordering and pagination scope, and explicitly distinguishes itself from get_scan for the full result. An agent can tell this apart from its siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('Use it to find a scan made earlier – by its reference or its time – before reading or deleting it') and names the alternative verb (call get_scan with its id). The routing condition is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_documentRecognise a passport or ID document
Idempotent
Inspect

Recognise a passport, national ID card or driver's licence from a photo or scan and return what is printed on it as structured JSON. Inputs: the image as image_base64 or image_url (https, on a public address); plus the optional expect_country, return_portrait, retain_hours, reference and idempotency_key. Output: a Scan object – meta (id, status, billed, confidence, timing), document (kind, issuing country, number, series, date of issue, date of expiry, whether it has expired and how many days are left), holder (given names, surname, date of birth, sex, nationality) – country codes are the document's own three-letter ICAO codes, each with a *_detail object giving the code as written, its ISO 3166-1 alpha-3 and alpha-2 and its category, fields (every field read off the printed page, each with its own confidence), mrz (whether the machine-readable zone checks out, why not when it does not, and its lines exactly as read), images, quality and authenticity – plus a one-line summary of the same result. Calls POST /v1/scans. Cost: it bills one credit ($0.01) only when a document is recognised; an unreadable image, an empty frame or an unsupported type costs nothing, and meta.billed says which happened. Without a key, the public sandbox key is used. It gives 10 free recognised documents per address in all, and at most 10 requests per address an hour, whatever their answer. Registering gives 100 free documents every month. Use it whenever someone hands over an identity document and wants it read, transcribed, or checked against what they claim – a name, a document number, a date of birth or an expiry date.

ParametersJSON Schema
NameRequiredDescriptionDefault
image_urlNohttps: URL of an image on a public internet address, which the server fetches (25 MB maximum).
referenceNoYour own correlation string, echoed back in the result.
image_base64NoThe document image as base64 (a data: URL is also accepted).
retain_hoursNoHours the result stays readable via GET /v1/scans/{id} (0 = store nothing). Omit it to use the account's own history-retention setting.
expect_countryNoISO 3166-1 alpha-3 country you expect, or omit for any.
idempotency_keyNoMakes a retried scan return the first result instead of charging again.
return_portraitNoWhether to include the holder photograph crop, images.main_photo (default true).

Output Schema

ParametersJSON Schema
NameRequiredDescription
mrzYes
metaYes
fieldsYesEvery field the engine extracted off the printed document, re-keyed to our vocabulary – the open set. Always present; empty when nothing was extracted. A field read in more than one language appears once per language, so `name` repeats and only `id` is unique.
holderYes
imagesYes
qualityYes
documentYes
authenticityYes
search_docsSearch the doc.cheap API documentationA
Read-only
Inspect

Full-text search over the doc.cheap API documentation – endpoints, request options, every response field, the error codes and what to do about each, MRZ rules, retention and pricing. Takes a query and an optional limit (1 to 20, default 5), and answers with the matching sections: title, a snippet, and a link to the page. It reads a copy of the documentation shipped beside this server, so it makes no network call and works offline. Use it before guessing at a field name, an error code or a scan option – what it returns is the published contract rather than a recollection of it.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of results (default 5).
queryYesWhat to search the documentation for.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultsYesMatching sections, best first; empty when nothing matched.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=false, and the description adds significant behavioral detail: it makes no network call, works offline, and returns matching sections (title, snippet, link). This goes beyond the annotations without contradicting them, fully informing the agent of the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is about three sentences but is information-dense with no fluff. It front-loads the purpose, then adds usage and behavior details, and every sentence contributes to the agent's understanding. It is well-structured and appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so return format is covered. The description additionally explains offline operation, usage guidance, and what the search covers. For a two-parameter search tool, everything an agent needs to call it correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the description repeats the limit range and default that the schema already documents. It adds the context of what the query searches over (endpoints, errors, etc.), but this is more about tool scope than parameter semantics. The baseline of 3 applies because the schema handles parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: full-text search over the doc.cheap API documentation, listing specific content types (endpoints, request options, response fields, error codes, MRZ rules, retention, pricing). This distinguishes it from siblings like check_balance and scan_document, which are unrelated operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: 'Use it before guessing at a field name, an error code or a scan option.' It also notes the tool reads a local copy and works offline, giving practical context for its use. While it doesn't explicitly list alternatives, the siblings are clearly different operations, so no confusion arises.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updates
    • Changedget_scan12 fields changed
      • addedOutput schema / definitions / CountryCodeCategory
        Added value: +{
        +  "description": "What a document's country code is. `iso`: an ISO 3166-1 alpha-3 code. `icao_variant`: an ICAO spelling of an ISO state (`D` for Germany). `british_nationality`: a British nationality class (`GBD`, `GBN`, `GBO`, `GBP`, `GBS`). `kosovo`: `RKS`, which ISO does not list. `united_nations`: `UNO`, `UNA`, `UNK`. `organization`: an issuing authority that is not a state (`EUE`, `XPO`, `IAO` and the other `X..` codes of ICAO Doc 9303). `stateless`: `XXA`. `refugee`: `XXB`, `XXC`. `unspecified`: `XXX`. `deprecated`: a code ISO has withdrawn (`ANT`, `NTZ`). `specimen`: `UTO`, the fictional state of specimen documents. `unknown`: a code in none of these lists.",
        +  "enum": [
        +    "iso",
        +    "icao_variant",
        +    "british_nationality",
        +    "kosovo",
        +    "united_nations",
        +    "organization",
        +    "stateless",
        +    "refugee",
        +    "unspecified",
        +    "deprecated",
        +    "specimen",
        +    "unknown"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / definitions / CountryCodeDetail
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "A document's country code resolved: the code as written, its ISO 3166-1 codes when ISO has them, and what kind of code it is.",
        +  "properties": {
        +    "alpha2": {
        +      "anyOf": [
        +        {
        +          "pattern": "^[A-Z]{2}$",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The ISO 3166-1 alpha-2 code of the same state, or null with `alpha3`.",
        +      "example": "DE"
        +    },
        +    "alpha3": {
        +      "anyOf": [
        +        {
        +          "pattern": "^[A-Z]{3}$",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The ISO 3166-1 alpha-3 code of the state the code stands for, or null when ISO has none (Kosovo, organisations, stateless persons, refugees, specimens, unknown codes).",
        +      "example": "DEU"
        +    },
        +    "category": {
        +      "$ref": "#/definitions/CountryCodeCategory"
        +    },
        +    "code": {
        +      "description": "The code as the document writes it, without the zone's `<` filler: `D` for Germany, `GBD` for a British Overseas Territories citizen.",
        +      "example": "D",
        +      "pattern": "^[A-Z]{1,3}$",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "alpha3",
        +    "alpha2",
        +    "category"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / definitions / ScanDocument / properties / country / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanDocument / properties / country / description
        Previous value: -"The state that issued the document, ISO 3166-1 alpha-3. The same reading as `issuing_state` under the name most callers filter on; null when nothing was read."New value: +"The state that issued the document, as its three-letter code. The same reading as `issuing_state` under the name most callers filter on; null when nothing was read."
      • changedOutput schema / definitions / ScanDocument / properties / issuing_state / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanDocument / properties / issuing_state / description
        Previous value: -"The issuing state, ISO 3166-1 alpha-3 – the same reading as `country`, under the name the machine-readable zone gives it."New value: +"The issuing state, the three-letter code the document writes – the same reading as `country`, under the name the machine-readable zone gives it."
      • addedOutput schema / definitions / ScanDocument / properties / issuing_state_detail
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/definitions/CountryCodeDetail"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The issuing state's code resolved: as written, as ISO 3166-1 alpha-3 and alpha-2, and its category. Null when no code was read."
        +}
      • changedOutput schema / definitions / ScanDocument / required
        Previous value: -[
        -  "kind",
        -  "country",
        -  "country_name",
        -  "issuing_state",
        -  "type_name",
        -  "type_confidence",
        -  "number",
        -  "series",
        -  "issue_date",
        -  "expiry_date",
        -  "is_expired",
        -  "days_remaining"
        -]New value: +[
        +  "kind",
        +  "country",
        +  "country_name",
        +  "issuing_state",
        +  "issuing_state_detail",
        +  "type_name",
        +  "type_confidence",
        +  "number",
        +  "series",
        +  "issue_date",
        +  "expiry_date",
        +  "is_expired",
        +  "days_remaining"
        +]
      • changedOutput schema / definitions / ScanHolder / properties / nationality / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanHolder / properties / nationality / description
        Previous value: -"The holder's nationality, ISO 3166-1 alpha-3. Null when none was read; it is not assumed from the issuing state."New value: +"The holder's nationality, the three-letter code the document writes. Null when none was read; it is not assumed from the issuing state."
      • addedOutput schema / definitions / ScanHolder / properties / nationality_detail
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/definitions/CountryCodeDetail"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The nationality code resolved: as written, as ISO 3166-1 alpha-3 and alpha-2, and its category – `stateless` or `refugee` for a holder without a nationality. Null when no code was read."
        +}
      • changedOutput schema / definitions / ScanHolder / required
        Previous value: -[
        -  "given_names",
        -  "surname",
        -  "full_name",
        -  "birth_date",
        -  "sex",
        -  "nationality"
        -]New value: +[
        +  "given_names",
        +  "surname",
        +  "full_name",
        +  "birth_date",
        +  "sex",
        +  "nationality",
        +  "nationality_detail"
        +]
    • Changedscan_document12 fields changed
      • addedOutput schema / definitions / CountryCodeCategory
        Added value: +{
        +  "description": "What a document's country code is. `iso`: an ISO 3166-1 alpha-3 code. `icao_variant`: an ICAO spelling of an ISO state (`D` for Germany). `british_nationality`: a British nationality class (`GBD`, `GBN`, `GBO`, `GBP`, `GBS`). `kosovo`: `RKS`, which ISO does not list. `united_nations`: `UNO`, `UNA`, `UNK`. `organization`: an issuing authority that is not a state (`EUE`, `XPO`, `IAO` and the other `X..` codes of ICAO Doc 9303). `stateless`: `XXA`. `refugee`: `XXB`, `XXC`. `unspecified`: `XXX`. `deprecated`: a code ISO has withdrawn (`ANT`, `NTZ`). `specimen`: `UTO`, the fictional state of specimen documents. `unknown`: a code in none of these lists.",
        +  "enum": [
        +    "iso",
        +    "icao_variant",
        +    "british_nationality",
        +    "kosovo",
        +    "united_nations",
        +    "organization",
        +    "stateless",
        +    "refugee",
        +    "unspecified",
        +    "deprecated",
        +    "specimen",
        +    "unknown"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / definitions / CountryCodeDetail
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "A document's country code resolved: the code as written, its ISO 3166-1 codes when ISO has them, and what kind of code it is.",
        +  "properties": {
        +    "alpha2": {
        +      "anyOf": [
        +        {
        +          "pattern": "^[A-Z]{2}$",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The ISO 3166-1 alpha-2 code of the same state, or null with `alpha3`.",
        +      "example": "DE"
        +    },
        +    "alpha3": {
        +      "anyOf": [
        +        {
        +          "pattern": "^[A-Z]{3}$",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The ISO 3166-1 alpha-3 code of the state the code stands for, or null when ISO has none (Kosovo, organisations, stateless persons, refugees, specimens, unknown codes).",
        +      "example": "DEU"
        +    },
        +    "category": {
        +      "$ref": "#/definitions/CountryCodeCategory"
        +    },
        +    "code": {
        +      "description": "The code as the document writes it, without the zone's `<` filler: `D` for Germany, `GBD` for a British Overseas Territories citizen.",
        +      "example": "D",
        +      "pattern": "^[A-Z]{1,3}$",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "alpha3",
        +    "alpha2",
        +    "category"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / definitions / ScanDocument / properties / country / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanDocument / properties / country / description
        Previous value: -"The state that issued the document, ISO 3166-1 alpha-3. The same reading as `issuing_state` under the name most callers filter on; null when nothing was read."New value: +"The state that issued the document, as its three-letter code. The same reading as `issuing_state` under the name most callers filter on; null when nothing was read."
      • changedOutput schema / definitions / ScanDocument / properties / issuing_state / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanDocument / properties / issuing_state / description
        Previous value: -"The issuing state, ISO 3166-1 alpha-3 – the same reading as `country`, under the name the machine-readable zone gives it."New value: +"The issuing state, the three-letter code the document writes – the same reading as `country`, under the name the machine-readable zone gives it."
      • addedOutput schema / definitions / ScanDocument / properties / issuing_state_detail
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/definitions/CountryCodeDetail"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The issuing state's code resolved: as written, as ISO 3166-1 alpha-3 and alpha-2, and its category. Null when no code was read."
        +}
      • changedOutput schema / definitions / ScanDocument / required
        Previous value: -[
        -  "kind",
        -  "country",
        -  "country_name",
        -  "issuing_state",
        -  "type_name",
        -  "type_confidence",
        -  "number",
        -  "series",
        -  "issue_date",
        -  "expiry_date",
        -  "is_expired",
        -  "days_remaining"
        -]New value: +[
        +  "kind",
        +  "country",
        +  "country_name",
        +  "issuing_state",
        +  "issuing_state_detail",
        +  "type_name",
        +  "type_confidence",
        +  "number",
        +  "series",
        +  "issue_date",
        +  "expiry_date",
        +  "is_expired",
        +  "days_remaining"
        +]
      • changedOutput schema / definitions / ScanHolder / properties / nationality / anyOf
        Previous value: -[
        -  {
        -    "description": "ISO 3166-1 alpha-3 country code.",
        -    "example": "GRC",
        -    "pattern": "^[A-Z]{3}$",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Three-letter country code as the document writes it (ICAO Doc 9303): the ISO 3166-1 alpha-3 code for almost every state, Germany's `D` given as `DEU`, and the ICAO codes ISO lacks (for example `GBD`, `RKS`, `XXA`) passed through as read. The matching `*_detail` object says which of these it is.",
        +    "example": "GRC",
        +    "pattern": "^[A-Z]{3}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / definitions / ScanHolder / properties / nationality / description
        Previous value: -"The holder's nationality, ISO 3166-1 alpha-3. Null when none was read; it is not assumed from the issuing state."New value: +"The holder's nationality, the three-letter code the document writes. Null when none was read; it is not assumed from the issuing state."
      • addedOutput schema / definitions / ScanHolder / properties / nationality_detail
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/definitions/CountryCodeDetail"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The nationality code resolved: as written, as ISO 3166-1 alpha-3 and alpha-2, and its category – `stateless` or `refugee` for a holder without a nationality. Null when no code was read."
        +}
      • changedOutput schema / definitions / ScanHolder / required
        Previous value: -[
        -  "given_names",
        -  "surname",
        -  "full_name",
        -  "birth_date",
        -  "sex",
        -  "nationality"
        -]New value: +[
        +  "given_names",
        +  "surname",
        +  "full_name",
        +  "birth_date",
        +  "sex",
        +  "nationality",
        +  "nationality_detail"
        +]
  2. 2 tool updates
    • Changedget_scan2 fields changed
      • changedOutput schema / definitions / ScanField / properties / language / description
        Previous value: -"The language this reading was made in, e.g. `Greek`; null for the neutral, transliterated Latin reading."New value: +"The language this reading was made in, e.g. `Greek`. The default Latin-script reading – the document's own Latin page and the machine-readable zone, `id` suffix `@0` – is `English`. Null only on `days_to_expire`, a number computed from the expiry date rather than text read in any language."
      • changedOutput schema / definitions / ScanField / properties / value / description
        Previous value: -"The value of this reading: the national-script spelling when `language` names one, the transliterated Latin value otherwise. Null when the field is empty."New value: +"The value of this reading: the national-script spelling on a national-script reading, the transliterated Latin value on the default reading (the one whose `id` carries the identifier `0`). Null when the field is empty."
    • Changedscan_document2 fields changed
      • changedOutput schema / definitions / ScanField / properties / language / description
        Previous value: -"The language this reading was made in, e.g. `Greek`; null for the neutral, transliterated Latin reading."New value: +"The language this reading was made in, e.g. `Greek`. The default Latin-script reading – the document's own Latin page and the machine-readable zone, `id` suffix `@0` – is `English`. Null only on `days_to_expire`, a number computed from the expiry date rather than text read in any language."
      • changedOutput schema / definitions / ScanField / properties / value / description
        Previous value: -"The value of this reading: the national-script spelling when `language` names one, the transliterated Latin value otherwise. Null when the field is empty."New value: +"The value of this reading: the national-script spelling on a national-script reading, the transliterated Latin value on the default reading (the one whose `id` carries the identifier `0`). Null when the field is empty."
  3. 3 tool updates
    • Addeddelete_scan
    • Addedget_scan
    • Addedlist_scans
  4. 1 tool update
    • Changedcheck_balance4 fields changed
      • changedOutput schema / properties / balance_credits / description
        Previous value: -"Credits currently available to the account; null for keys without a balance."New value: +"Credits currently available to the account: this month's free credits plus the paid credits; null for a key with no account (the public sandbox key)."
      • changedOutput schema / properties / free_allowance / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "monthly_credits": {
        -        "description": "Free credits the account receives each UTC calendar month.",
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "remaining_credits": {
        -        "description": "Free credits left this month.",
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "resets_at": {
        -        "anyOf": [
        -          {
        -            "format": "date-time",
        -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ],
        -        "description": "When the free credits are next set back to the monthly amount (00:00 UTC on the first of the next month); null when there is no next monthly amount."
        -      }
        -    },
        -    "required": [
        -      "monthly_credits",
        -      "remaining_credits",
        -      "resets_at"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "monthly_credits": {
        +        "description": "Free credits the account is set back to at the start of each UTC calendar month: 100 every month.",
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "remaining_credits": {
        +        "description": "Free credits left this month.",
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "resets_at": {
        +        "anyOf": [
        +          {
        +            "format": "date-time",
        +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "When the free credits are next set back to the monthly amount (00:00 UTC on the first of the next month); null when there is no next monthly amount."
        +      }
        +    },
        +    "required": [
        +      "monthly_credits",
        +      "remaining_credits",
        +      "resets_at"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / free_allowance / description
        Previous value: -"This month's free credits, drawn before paid credits; null when the key's account has no free credits this month."New value: +"This month's free credits, drawn before paid credits; null when the account may not draw free credits (its email address is not confirmed, or its free credits were withdrawn) and for a key with no account."
      • changedOutput schema / properties / paid_balance_credits / description
        Previous value: -"Credits bought or granted to the account, which never reset; null when the account's credits are not split into free and paid."New value: +"Paid credits: bought or granted to the account, drawn once this month's free credits are used up, and never reset; null only for a key with no account (the public sandbox key)."
  5. 1 tool update
    • Changedcheck_balance4 fields changed
      • addedOutput schema / properties / credits_spent_by_kind
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Credits charged within the period, by the kind that paid.",
        +  "properties": {
        +    "free": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "paid": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "free",
        +    "paid"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / free_allowance
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "monthly_credits": {
        +          "description": "Free credits the account receives each UTC calendar month.",
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "remaining_credits": {
        +          "description": "Free credits left this month.",
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "resets_at": {
        +          "anyOf": [
        +            {
        +              "format": "date-time",
        +              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "When the free credits are next set back to the monthly amount (00:00 UTC on the first of the next month); null when there is no next monthly amount."
        +        }
        +      },
        +      "required": [
        +        "monthly_credits",
        +        "remaining_credits",
        +        "resets_at"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "This month's free credits, drawn before paid credits; null when the key's account has no free credits this month."
        +}
      • addedOutput schema / properties / paid_balance_credits
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Credits bought or granted to the account, which never reset; null when the account's credits are not split into free and paid."
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "balance_credits",
        -  "period",
        -  "scans",
        -  "credits_spent"
        -]New value: +[
        +  "balance_credits",
        +  "period",
        +  "scans",
        +  "credits_spent",
        +  "free_allowance",
        +  "paid_balance_credits",
        +  "credits_spent_by_kind"
        +]
  6. 1 tool update
    • Changedscan_document12 fields changed
      • changedOutput schema / definitions / ScanDocument / properties / issuing_state / description
        Previous value: -"The issuing state, ISO 3166-1 alpha-3 — the same reading as `country`, under the name the machine-readable zone gives it."New value: +"The issuing state, ISO 3166-1 alpha-3 – the same reading as `country`, under the name the machine-readable zone gives it."
      • changedOutput schema / definitions / ScanField / properties / id / description
        Previous value: -"Identity of this entry, unique across `fields`: the key and the language identifier the value was read as, plus an occurrence counter when the same pair is reported twice. `name` is the semantic key and repeats — a document that carries a field in two scripts yields one entry per language — so use `id`, not `name`, to address or key a single entry."New value: +"Identity of this entry, unique across `fields`: the key and the language identifier the value was read as, plus an occurrence counter when the same pair is reported twice. `name` is the semantic key and repeats – a document that carries a field in two scripts yields one entry per language – so use `id`, not `name`, to address or key a single entry."
      • changedOutput schema / definitions / ScanHolder / properties / full_name / description
        Previous value: -"The holder's name as the document prints it in one combined field. Null when the document carries no such field — it is not composed from the two above."New value: +"The holder's name as the document prints it in one combined field. Null when the document carries no such field – it is not composed from the two above."
      • changedOutput schema / definitions / ScanId / description
        Previous value: -"Scan identifier: a UUID version 7 (RFC 9562), canonical lower-case `8-4-4-4-12`. Its leading 48 bits are the millisecond the scan was made, so ids sort in the order the scans happened — but treat the value as opaque: nothing else about it is part of the contract."New value: +"Scan identifier: a UUID version 7 (RFC 9562), canonical lower-case `8-4-4-4-12`. Its leading 48 bits are the millisecond the scan was made, so ids sort in the order the scans happened – but treat the value as opaque: nothing else about it is part of the contract."
      • changedOutput schema / definitions / ScanImages / properties / document_crop / description
        Previous value: -"The document itself, cropped out of the uploaded picture and deskewed — the front side of a card, the data page of a booklet."New value: +"The document itself, cropped out of the uploaded picture and deskewed – the front side of a card, the data page of a booklet."
      • changedOutput schema / definitions / ScanImages / properties / watermark_face / description
        Previous value: -"The faint second copy of the holder's face printed into the page as a security feature — a different image from `main_photo`, and the one a verifier compares against it. Null when the document carries none."New value: +"The faint second copy of the holder's face printed into the page as a security feature – a different image from `main_photo`, and the one a verifier compares against it. Null when the document carries none."
      • changedOutput schema / definitions / ScanMrz / properties / lines / description
        Previous value: -"The zone's lines in order, exactly as read — two for a TD3 passport, three for a TD1 card. The zone's alphabet is `A-Z`, `0-9` and the filler `<`, so a line carries no whitespace. Null when the document carries none."New value: +"The zone's lines in order, exactly as read – two for a TD3 passport, three for a TD1 card. The zone's alphabet is `A-Z`, `0-9` and the filler `<`, so a line carries no whitespace. Null when the document carries none."
      • changedOutput schema / definitions / ScanQuality / properties / overall / description
        Previous value: -"Whether the uploaded picture was good enough to recognize from. `not_checked` when nothing measured it — a scan read back from storage, which keeps no engine output."New value: +"Whether the uploaded picture was good enough to recognize from. `not_checked` when nothing measured it – a scan read back from storage, which keeps no engine output."
      • changedOutput schema / definitions / ScanTiming / properties / processing_ms / description
        Previous value: -"The recognition itself — the server-side engine call."New value: +"The recognition itself – the server-side engine call."
      • changedOutput schema / definitions / ScanTiming / properties / total_ms / description
        Previous value: -"From the request arriving to the result being complete. At least `upload_ms + processing_ms`; the remainder is the gates that run after `upload_ms` is taken — the allowance, the idempotency check and the credit hold — plus preparing the result images and mapping the engine's output into this body. It stops there: writing the history row and serializing the response happen after the number is fixed, so the same figure is stored and returned."New value: +"From the request arriving to the result being complete. At least `upload_ms + processing_ms`; the remainder is the gates that run after `upload_ms` is taken – the allowance, the idempotency check and the credit hold – plus preparing the result images and mapping the engine's output into this body. It stops there: writing the history row and serializing the response happen after the number is fixed, so the same figure is stored and returned."
      • changedOutput schema / definitions / ScanTiming / properties / upload_ms / description
        Previous value: -"From the request's headers reaching the server to its body being received and validated, with your key resolved and its rate limit checked. The allowance, idempotency and credit gates are claimed after this number is taken, so they are not in it. Dominated by your own connection and by how large the image is — this is the half you can shrink, by sending a smaller picture from closer by."New value: +"From the request's headers reaching the server to its body being received and validated, with your key resolved and its rate limit checked. The allowance, idempotency and credit gates are claimed after this number is taken, so they are not in it. Dominated by your own connection and by how large the image is – this is the half you can shrink, by sending a smaller picture from closer by."
      • changedOutput schema / properties / fields / description
        Previous value: -"Every field the engine extracted off the printed document, re-keyed to our vocabulary — the open set. Always present; empty when nothing was extracted. A field read in more than one language appears once per language, so `name` repeats and only `id` is unique."New value: +"Every field the engine extracted off the printed document, re-keyed to our vocabulary – the open set. Always present; empty when nothing was extracted. A field read in more than one language appears once per language, so `name` repeats and only `id` is unique."
  7. 3 tool updates
    • Changedcheck_balance1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "balance_credits": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Credits currently available to the account; null for keys without a balance."
        +    },
        +    "credits_spent": {
        +      "description": "Credits charged within the period.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "period": {
        +      "additionalProperties": false,
        +      "description": "Bounds of the current usage period (UTC calendar month).",
        +      "properties": {
        +        "end": {
        +          "format": "date-time",
        +          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        +          "type": "string"
        +        },
        +        "start": {
        +          "format": "date-time",
        +          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "start",
        +        "end"
        +      ],
        +      "type": "object"
        +    },
        +    "scans": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "billed": {
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "by_status": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "no_document_found": {
        +              "maximum": 9007199254740991,
        +              "minimum": 0,
        +              "type": "integer"
        +            },
        +            "recognized": {
        +              "maximum": 9007199254740991,
        +              "minimum": 0,
        +              "type": "integer"
        +            },
        +            "rejected": {
        +              "maximum": 9007199254740991,
        +              "minimum": 0,
        +              "type": "integer"
        +            },
        +            "unreadable": {
        +              "maximum": 9007199254740991,
        +              "minimum": 0,
        +              "type": "integer"
        +            },
        +            "unsupported_document": {
        +              "maximum": 9007199254740991,
        +              "minimum": 0,
        +              "type": "integer"
        +            }
        +          },
        +          "required": [
        +            "recognized",
        +            "no_document_found",
        +            "unreadable",
        +            "unsupported_document",
        +            "rejected"
        +          ],
        +          "type": "object"
        +        },
        +        "total": {
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "total",
        +        "billed",
        +        "by_status"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "balance_credits",
        +    "period",
        +    "scans",
        +    "credits_spent"
        +  ],
        +  "type": "object"
        +}
    • Changedscan_document1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "definitions": {
        +    "CheckResult": {
        +      "description": "Outcome of a single check.",
        +      "enum": [
        +        "pass",
        +        "warn",
        +        "fail"
        +      ],
        +      "type": "string"
        +    },
        +    "ConfidenceBand": {
        +      "description": "How strongly the recognition backs this value: `high`, `medium` or `low`. An unknown or missing probability reads as `low`.",
        +      "enum": [
        +        "low",
        +        "medium",
        +        "high"
        +      ],
        +      "type": "string"
        +    },
        +    "FieldCategory": {
        +      "description": "Which group of the report a field belongs to.",
        +      "enum": [
        +        "identity",
        +        "document",
        +        "dates",
        +        "address",
        +        "visa",
        +        "other"
        +      ],
        +      "type": "string"
        +    },
        +    "MrzStatus": {
        +      "description": "Verdict on the machine-readable zone: `passed` (present, every check digit valid and nothing contradicting the printed page), `failed` (present but something did not check out) or `absent` (the document carries none).",
        +      "enum": [
        +        "passed",
        +        "failed",
        +        "absent"
        +      ],
        +      "type": "string"
        +    },
        +    "ScanAuthenticity": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "checks": {
        +          "description": "One entry per authenticity check that ran. Always present; empty under the recognition-only scenario, where nothing ran.",
        +          "items": {
        +            "$ref": "#/definitions/ScanCheck"
        +          },
        +          "type": "array"
        +        },
        +        "overall": {
        +          "description": "`not_checked` under the recognition-only scenario; populated by authenticity verification later.",
        +          "enum": [
        +            "not_checked",
        +            "pass",
        +            "warn",
        +            "fail"
        +          ],
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "overall",
        +        "checks"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanCheck": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "detail": {
        +          "description": "One plain sentence about what this check saw, or null when it has nothing to add.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "label": {
        +          "description": "Our human label for this check.",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "name": {
        +          "description": "Our stable snake_case key for this check.",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "result": {
        +          "$ref": "#/definitions/CheckResult"
        +        }
        +      },
        +      "required": [
        +        "name",
        +        "label",
        +        "result",
        +        "detail"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanDocument": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "country": {
        +          "anyOf": [
        +            {
        +              "description": "ISO 3166-1 alpha-3 country code.",
        +              "example": "GRC",
        +              "pattern": "^[A-Z]{3}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The state that issued the document, ISO 3166-1 alpha-3. The same reading as `issuing_state` under the name most callers filter on; null when nothing was read."
        +        },
        +        "country_name": {
        +          "description": "The issuing state's name, as read from the document.",
        +          "example": "Greece",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "days_remaining": {
        +          "anyOf": [
        +            {
        +              "maximum": 9007199254740991,
        +              "minimum": -9007199254740991,
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Days until expiry at the time of the scan; negative once expired."
        +        },
        +        "expiry_date": {
        +          "anyOf": [
        +            {
        +              "description": "Calendar date, ISO-8601 (`YYYY-MM-DD`).",
        +              "format": "date",
        +              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The date the document expires, ISO-8601 (`YYYY-MM-DD`). Null when none was read; `is_expired` and `days_remaining` are computed from it."
        +        },
        +        "is_expired": {
        +          "description": "Whether the document had already expired when the scan was made. Null when no expiry date was read, which is a different answer from `false`.",
        +          "type": [
        +            "boolean",
        +            "null"
        +          ]
        +        },
        +        "issue_date": {
        +          "anyOf": [
        +            {
        +              "description": "Calendar date, ISO-8601 (`YYYY-MM-DD`).",
        +              "format": "date",
        +              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The date the document was issued, ISO-8601 (`YYYY-MM-DD`). Null when none was read."
        +        },
        +        "issuing_state": {
        +          "anyOf": [
        +            {
        +              "description": "ISO 3166-1 alpha-3 country code.",
        +              "example": "GRC",
        +              "pattern": "^[A-Z]{3}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The issuing state, ISO 3166-1 alpha-3 — the same reading as `country`, under the name the machine-readable zone gives it."
        +        },
        +        "kind": {
        +          "description": "Document type, e.g. `passport`.",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "number": {
        +          "description": "The document number, as printed. Null when none was read. A series the document prints separately is in `series`, never folded into this value.",
        +          "example": "AM7304518",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "series": {
        +          "description": "The document series, for a document that prints one as a field of its own. Null when the document carries none or none was read; it is never split out of `number`.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "type_confidence": {
        +          "allOf": [
        +            {
        +              "$ref": "#/definitions/ConfidenceBand"
        +            }
        +          ],
        +          "description": "How strongly the document-type match is backed."
        +        },
        +        "type_name": {
        +          "description": "The document type under its full name. Null on a scan read back from storage, which keeps no engine output.",
        +          "example": "Greece - Passport",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "kind",
        +        "country",
        +        "country_name",
        +        "issuing_state",
        +        "type_name",
        +        "type_confidence",
        +        "number",
        +        "series",
        +        "issue_date",
        +        "expiry_date",
        +        "is_expired",
        +        "days_remaining"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanField": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "category": {
        +          "$ref": "#/definitions/FieldCategory"
        +        },
        +        "confidence": {
        +          "$ref": "#/definitions/ConfidenceBand"
        +        },
        +        "id": {
        +          "description": "Identity of this entry, unique across `fields`: the key and the language identifier the value was read as, plus an occurrence counter when the same pair is reported twice. `name` is the semantic key and repeats — a document that carries a field in two scripts yields one entry per language — so use `id`, not `name`, to address or key a single entry.",
        +          "example": "surname@1032",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "label": {
        +          "description": "Our human label.",
        +          "example": "Surname",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "language": {
        +          "description": "The language this reading was made in, e.g. `Greek`; null for the neutral, transliterated Latin reading.",
        +          "example": "Greek",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "name": {
        +          "description": "Our stable snake_case key.",
        +          "example": "surname",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "value": {
        +          "description": "The value of this reading: the national-script spelling when `language` names one, the transliterated Latin value otherwise. Null when the field is empty.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "id",
        +        "name",
        +        "label",
        +        "category",
        +        "value",
        +        "language",
        +        "confidence"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanHolder": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "birth_date": {
        +          "anyOf": [
        +            {
        +              "description": "Calendar date, ISO-8601 (`YYYY-MM-DD`).",
        +              "format": "date",
        +              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The holder's date of birth, ISO-8601 (`YYYY-MM-DD`). Null when none was read."
        +        },
        +        "full_name": {
        +          "description": "The holder's name as the document prints it in one combined field. Null when the document carries no such field — it is not composed from the two above.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "given_names": {
        +          "description": "The holder's given names, as printed. Null when none was read.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "nationality": {
        +          "anyOf": [
        +            {
        +              "description": "ISO 3166-1 alpha-3 country code.",
        +              "example": "GRC",
        +              "pattern": "^[A-Z]{3}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The holder's nationality, ISO 3166-1 alpha-3. Null when none was read; it is not assumed from the issuing state."
        +        },
        +        "sex": {
        +          "anyOf": [
        +            {
        +              "enum": [
        +                "M",
        +                "F",
        +                "X"
        +              ],
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The sex the document states: `M`, `F`, or `X` for unspecified. Null when none was read."
        +        },
        +        "surname": {
        +          "description": "The holder's surname, as printed. Null when none was read.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "given_names",
        +        "surname",
        +        "full_name",
        +        "birth_date",
        +        "sex",
        +        "nationality"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanId": {
        +      "description": "Scan identifier: a UUID version 7 (RFC 9562), canonical lower-case `8-4-4-4-12`. Its leading 48 bits are the millisecond the scan was made, so ids sort in the order the scans happened — but treat the value as opaque: nothing else about it is part of the contract.",
        +      "example": "01a0af18-cd8d-7a61-9f2d-4c7b8e105da3",
        +      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
        +      "type": "string"
        +    },
        +    "ScanImages": {
        +      "additionalProperties": false,
        +      "description": "Image crops, returned in the recognition response only. Each is scaled down by height, proportionally and never upwards, to at most 250 px for `document_crop` and 100 px for every other crop, then re-encoded with every metadata block dropped.",
        +      "properties": {
        +        "barcode": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The barcode area of the document, when it carries one."
        +        },
        +        "chip": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The chip area of the document, when it carries one."
        +        },
        +        "document_crop": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The document itself, cropped out of the uploaded picture and deskewed — the front side of a card, the data page of a booklet."
        +        },
        +        "main_photo": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The holder's photograph as printed on the document."
        +        },
        +        "rear": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The reverse side of the document, when the picture carried one and a crop of it was produced."
        +        },
        +        "signature": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The holder's signature as printed on the document."
        +        },
        +        "watermark_face": {
        +          "anyOf": [
        +            {
        +              "description": "Image as a `data:` URL with base64 payload.",
        +              "pattern": "^data:image\\/(jpeg|png);base64,[A-Za-z0-9+/]+={0,2}$",
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The faint second copy of the holder's face printed into the page as a security feature — a different image from `main_photo`, and the one a verifier compares against it. Null when the document carries none."
        +        }
        +      },
        +      "required": [
        +        "document_crop",
        +        "rear",
        +        "main_photo",
        +        "signature",
        +        "watermark_face",
        +        "barcode",
        +        "chip"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanMeta": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "billed": {
        +          "description": "Whether this scan was charged to the balance.",
        +          "type": "boolean"
        +        },
        +        "confidence": {
        +          "allOf": [
        +            {
        +              "$ref": "#/definitions/ConfidenceBand"
        +            }
        +          ],
        +          "description": "How strongly the recognition backs this reading as a whole. Each entry of `fields` carries its own band as well, and they can differ from this one."
        +        },
        +        "created_at": {
        +          "description": "Timestamp, ISO-8601 in UTC (`YYYY-MM-DDTHH:MM:SSZ`).",
        +          "format": "date-time",
        +          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
        +          "type": "string"
        +        },
        +        "id": {
        +          "$ref": "#/definitions/ScanId"
        +        },
        +        "reference": {
        +          "description": "The request's `reference`, echoed back.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "schema_version": {
        +          "const": "1.0",
        +          "description": "The version of this body, always `1.0`. A consumer that pins this value checks that the body is the one it was written against.",
        +          "type": "string"
        +        },
        +        "status": {
        +          "$ref": "#/definitions/ScanStatus"
        +        },
        +        "timing": {
        +          "anyOf": [
        +            {
        +              "$ref": "#/definitions/ScanTiming"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        }
        +      },
        +      "required": [
        +        "schema_version",
        +        "id",
        +        "status",
        +        "billed",
        +        "confidence",
        +        "timing",
        +        "created_at",
        +        "reference"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanMrz": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "lines": {
        +          "anyOf": [
        +            {
        +              "items": {
        +                "type": "string"
        +              },
        +              "type": "array"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The zone's lines in order, exactly as read — two for a TD3 passport, three for a TD1 card. The zone's alphabet is `A-Z`, `0-9` and the filler `<`, so a line carries no whitespace. Null when the document carries none."
        +        },
        +        "reason": {
        +          "description": "One plain sentence naming what did not check out, for `failed`; null otherwise.",
        +          "example": "Check digit failed for: document number, date of birth",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "status": {
        +          "$ref": "#/definitions/MrzStatus"
        +        },
        +        "text": {
        +          "description": "The same lines run together with nothing between them: one unbroken string, with no newlines and no spaces. Null when there are none.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "status",
        +        "reason",
        +        "lines",
        +        "text"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanQuality": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "overall": {
        +          "description": "Whether the uploaded picture was good enough to recognize from. `not_checked` when nothing measured it — a scan read back from storage, which keeps no engine output.",
        +          "enum": [
        +            "not_checked",
        +            "pass",
        +            "warn",
        +            "fail"
        +          ],
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "overall"
        +      ],
        +      "type": "object"
        +    },
        +    "ScanStatus": {
        +      "description": "Outcome of a scan. Exactly these five string values; there are no numeric codes.",
        +      "enum": [
        +        "recognized",
        +        "no_document_found",
        +        "unreadable",
        +        "unsupported_document",
        +        "rejected"
        +      ],
        +      "type": "string"
        +    },
        +    "ScanTiming": {
        +      "additionalProperties": false,
        +      "description": "The split of the request's time. Null on a scan made before the split existed and read back out of storage: only the engine call was timed then, and the two halves cannot be recovered from it.",
        +      "properties": {
        +        "processing_ms": {
        +          "description": "The recognition itself — the server-side engine call.",
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "total_ms": {
        +          "description": "From the request arriving to the result being complete. At least `upload_ms + processing_ms`; the remainder is the gates that run after `upload_ms` is taken — the allowance, the idempotency check and the credit hold — plus preparing the result images and mapping the engine's output into this body. It stops there: writing the history row and serializing the response happen after the number is fixed, so the same figure is stored and returned.",
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "upload_ms": {
        +          "description": "From the request's headers reaching the server to its body being received and validated, with your key resolved and its rate limit checked. The allowance, idempotency and credit gates are claimed after this number is taken, so they are not in it. Dominated by your own connection and by how large the image is — this is the half you can shrink, by sending a smaller picture from closer by.",
        +          "maximum": 9007199254740991,
        +          "minimum": 0,
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "upload_ms",
        +        "processing_ms",
        +        "total_ms"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "authenticity": {
        +      "$ref": "#/definitions/ScanAuthenticity"
        +    },
        +    "document": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/definitions/ScanDocument"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "fields": {
        +      "description": "Every field the engine extracted off the printed document, re-keyed to our vocabulary — the open set. Always present; empty when nothing was extracted. A field read in more than one language appears once per language, so `name` repeats and only `id` is unique.",
        +      "items": {
        +        "$ref": "#/definitions/ScanField"
        +      },
        +      "type": "array"
        +    },
        +    "holder": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/definitions/ScanHolder"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "images": {
        +      "$ref": "#/definitions/ScanImages"
        +    },
        +    "meta": {
        +      "$ref": "#/definitions/ScanMeta"
        +    },
        +    "mrz": {
        +      "$ref": "#/definitions/ScanMrz"
        +    },
        +    "quality": {
        +      "$ref": "#/definitions/ScanQuality"
        +    }
        +  },
        +  "required": [
        +    "meta",
        +    "document",
        +    "holder",
        +    "fields",
        +    "mrz",
        +    "images",
        +    "quality",
        +    "authenticity"
        +  ],
        +  "type": "object"
        +}
    • Changedsearch_docs1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "results": {
        +      "description": "Matching sections, best first; empty when nothing matched.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "link": {
        +            "description": "Address of the section on the documentation site.",
        +            "type": "string"
        +          },
        +          "page": {
        +            "description": "Path of the page the section is on; empty for the home page.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Relevance: heading matches count five times a body match.",
        +            "type": "number"
        +          },
        +          "snippet": {
        +            "description": "The start of the section's text.",
        +            "type": "string"
        +          },
        +          "title": {
        +            "description": "Heading of the matching documentation section.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "title",
        +          "page",
        +          "link",
        +          "snippet",
        +          "score"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "results"
        +  ],
        +  "type": "object"
        +}
  8. 3 tool updates
    • First observedcheck_balance
    • First observedscan_document
    • First observedsearch_docs

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Reads passports, ID cards and driver's licences from a photo or scan and returns the printed fields and MRZ as structured JSON. One credit ($0.01) per recognised document; nothing is charged when no document is found.
    6
    106 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Extract structured, schema-typed data from invoices, purchase orders, receipts, and tax forms, and classify documents into custom label sets — via a hosted MCP server. Free tier included.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources