Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/infinihash-com:infinihash-com-documents-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Infinihash KYC Documents API
version: 1.0.0
description: 'Identity verification, KYB, sanctions screening, UBO orchestration and periodic review.
Auth: send your key as `X-API-Key: ` (or `Authorization: Bearer `).
Most endpoints are mounted twice — at the root (`/kyc/...`) and under `/api` (`/api/kyc/...`). Prefer the `/api` form; it is what the hosted portals and SDKs use.
Python SDK: `pip install "git+https://github.com/Infinihash/kyc-python@v0.1.0"` (https://github.com/Infinihash/kyc-python; runnable examples in examples/).'
contact:
name: Infinihash
url: https://kyc.infinihash.com
servers:
- url: https://kyc-api.infinihash.com
description: Production
tags:
- name: Documents
paths:
/kyc/mobile-upload-token:
get:
x-route-source:
file: routes/mobile-upload.js
method: get
path: /mobile-upload-token
summary: Create a phone-upload (QR) token
description: Issues a one-time token, valid 5 minutes, that a phone can use at POST /kyc/mobile-upload/{token} to hand a document to the desktop session. Tokens live in process memory. Mounted at the root only.
tags:
- Documents
operationId: createMobileUploadToken
parameters:
- name: entityId
in: query
required: false
schema:
type: string
description: Entity the upload belongs to; defaults to the API key id.
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Token
content:
application/json:
schema:
$ref: '#/components/schemas/MobileUploadToken'
'400':
description: entityId required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid API key
'429':
description: Rate limited
/kyc/mobile-upload/status/{token}:
get:
x-route-source:
file: routes/mobile-upload.js
method: get
path: /mobile-upload/status/:token
summary: Poll a phone-upload token
description: 'Desktop polling: pending until the phone uploads, then complete with the stored artifact; expired when the token is unknown or older than 5 minutes. Mounted at the root only.'
tags:
- Documents
operationId: getMobileUploadStatus
parameters:
- name: token
in: path
required: true
schema:
type: string
description: token
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Token state
content:
application/json:
schema:
$ref: '#/components/schemas/MobileUploadStatus'
'401':
description: Missing or invalid API key
'429':
description: Rate limited
/kyc/mobile-upload/{token}:
post:
x-route-source:
file: routes/mobile-upload.js
method: post
path: /mobile-upload/:token
summary: Receive a document from the phone
description: Called by the phone (no API key; the unguessable token is the credential). Multipart upload of one `file` part (JPEG, PNG, HEIC/HEIF or PDF, max 25 MB) stored as an artifact; the token is single-use. A wrong file type or oversized file is rejected by the upload middleware and surfaces as 500 from the global error handler. Mounted at the root only.
tags:
- Documents
operationId: uploadFromMobile
parameters:
- name: token
in: path
required: true
schema:
type: string
description: token
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
description: image/jpeg, image/png, image/heic, image/heif or application/pdf, max 25 MB
required:
- file
security: []
responses:
'200':
description: Stored
content:
application/json:
schema:
$ref: '#/components/schemas/MobileUploadResult'
'400':
description: No file uploaded
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: Token already used
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'410':
description: Token expired or invalid
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Upload failed (also unsupported file type / file too large)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/kyc/{id}/extraction:
get:
x-route-source:
file: routes/kyc.js
method: get
path: /:id/extraction
summary: Get the CIS extraction result with confidence
description: 'Latest VLM extraction of the submission''s CIS document: structured fields, per-field confidence and the list of fields below the 0.7 review threshold (needs_review).'
tags:
- Documents
operationId: get_kyc_id_extraction
parameters:
- name: id
in: path
required: true
schema:
type: string
description: KYC submission id
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Extraction result
content:
application/json:
schema:
$ref: '#/components/schemas/KycExtraction'
'401':
description: Missing or invalid API key
'404':
description: Submission not found, or no VLM extraction result (upload a CIS document first)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/documents/extract:
post:
x-route-source:
file: routes/documents.js
method: post
path: /extract
summary: Extract fields from a document (no submission)
description: Stateless extraction of a passport, ID, formation document, Form ADV, proof of address or CIS. Nothing is stored. Image documents go through the quality gate first (422 on poor quality, 503 if the gate is down) and passports/IDs are cross-checked against their MRZ. Max 10 MB; JSON body only.
tags:
- Documents
operationId: post_documents_extract
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractRequest'
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Extraction result
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractResult'
'400':
description: Unreadable body, unknown/unclassifiable docType, unsupported MIME type, missing data, file over 10 MB, or HEIC conversion failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid API key
'422':
description: Image quality gate failed (reasons, quality in body) or extraction failed schema validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Extraction failed (detail has the cause)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'503':
description: 'Image quality gate unavailable (reason: preflight_unavailable); retry shortly'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/documents/{submissionId}:
post:
x-route-source:
file: routes/documents.js
method: post
path: /:submissionId
summary: Upload a document to a submission
description: Attaches a document to the submission and starts extraction in the background (202). Poll GET /documents/{submissionId}. A duplicate passport/ID image already on the submission returns 200 with dedupe:true. If the image quality gate is down the document is parked and the submission set to pending_manual_review (202, status pending_manual_review). Accepts JSON (base64 data) or multipart/form-data with a `file` part (doc_type is accepted as an alias of docType). Max 10 MB.
tags:
- Documents
operationId: post_documents_submissionId
parameters:
- name: submissionId
in: path
required: true
schema:
type: string
description: KYC submission id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractRequest'
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
docType:
type: string
enum:
- passport
- id
- formation
- adv
- proof_of_address
- cis
- auto
description: '"auto" classifies the document (falling back to the filename); a document that cannot be classified is rejected with 400.'
doc_type:
type: string
description: Alias of docType.
mimeType:
type: string
enum:
- image/jpeg
- image/png
- image/webp
- application/pdf
- image/heic
- image/heif
description: HEIC/HEIF is converted to JPEG on ingest.
filename:
type: string
required:
- file
- docType
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Duplicate image already on the submission; nothing re-processed
content:
application/json:
schema:
$ref: '#/components/schemas/DocUploadDedupe'
'202':
description: Document accepted; extraction enqueued (or parked for manual review)
content:
application/json:
schema:
$ref: '#/components/schemas/DocUploadAccepted'
'400':
description: Unreadable body, missing data, unsupported MIME type, file over 10 MB, invalid or unclassifiable docType, or HEIC conversion failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid API key
'404':
description: Submission not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: Image quality gate failed (reasons, quality in body) or extraction failed schema validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Document processing failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
get:
x-route-source:
file: routes/documents.js
method: get
path: /:submissionId
summary: List documents of a submission
description: Lists the documents uploaded to the submission, newest first, with processing status, extracted fields, preflight and MRZ results.
tags:
- Documents
operationId: get_documents_submissionId
parameters:
- name: submissionId
in: path
required: true
schema:
type: string
description: KYC submission id
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Documents
content:
application/json:
schema:
$ref: '#/components/schemas/DocList'
'401':
description: Missing or invalid API key
'404':
description: Submission not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/kyc/{id}/extraction:
get:
x-route-source:
file: routes/kyc.js
method: get
path: /:id/extraction
summary: Get the CIS extraction result with confidence
description: 'Latest VLM extraction of the submission''s CIS document: structured fields, per-field confidence and the list of fields below the 0.7 review threshold (needs_review).'
tags:
- Documents
operationId: getKycExtraction
parameters:
- name: id
in: path
required: true
schema:
type: string
description: KYC submission id
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Extraction result
content:
application/json:
schema:
$ref: '#/components/schemas/KycExtraction'
'401':
description: Missing or invalid API key
'404':
description: Submission not found, or no VLM extraction result (upload a CIS document first)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/documents/extract:
post:
x-route-source:
file: routes/documents.js
method: post
path: /extract
summary: Extract fields from a document (no submission)
description: Stateless extraction of a passport, ID, formation document, Form ADV, proof of address or CIS. Nothing is stored. Image documents go through the quality gate first (422 on poor quality, 503 if the gate is down) and passports/IDs are cross-checked against their MRZ. Max 10 MB; JSON body only.
tags:
- Documents
operationId: extractDocument
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractRequest'
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Extraction result
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractResult'
'400':
description: Unreadable body, unknown/unclassifiable docType, unsupported MIME type, missing data, file over 10 MB, or HEIC conversion failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid API key
'422':
description: Image quality gate failed (reasons, quality in body) or extraction failed schema validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Extraction failed (detail has the cause)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'503':
description: 'Image quality gate unavailable (reason: preflight_unavailable); retry shortly'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/documents/{submissionId}:
post:
x-route-source:
file: routes/documents.js
method: post
path: /:submissionId
summary: Upload a document to a submission
description: Attaches a document to the submission and starts extraction in the background (202). Poll GET /documents/{submissionId}. A duplicate passport/ID image already on the submission returns 200 with dedupe:true. If the image quality gate is down the document is parked and the submission set to pending_manual_review (202, status pending_manual_review). Accepts JSON (base64 data) or multipart/form-data with a `file` part (doc_type is accepted as an alias of docType). Max 10 MB.
tags:
- Documents
operationId: uploadDocument
parameters:
- name: submissionId
in: path
required: true
schema:
type: string
description: KYC submission id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DocExtractRequest'
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
docType:
type: string
enum:
- passport
- id
- formation
- adv
- proof_of_address
- cis
- auto
description: '"auto" classifies the document (falling back to the filename); a document that cannot be classified is rejected with 400.'
doc_type:
type: string
description: Alias of docType.
mimeType:
type: string
enum:
- image/jpeg
- image/png
- image/webp
- application/pdf
- image/heic
- image/heif
description: HEIC/HEIF is converted to JPEG on ingest.
filename:
type: string
required:
- file
- docType
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Duplicate image already on the submission; nothing re-processed
content:
application/json:
schema:
$ref: '#/components/schemas/DocUploadDedupe'
'202':
description: Document accepted; extraction enqueued (or parked for manual review)
content:
application/json:
schema:
$ref: '#/components/schemas/DocUploadAccepted'
'400':
description: Unreadable body, missing data, unsupported MIME type, file over 10 MB, invalid or unclassifiable docType, or HEIC conversion failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or invalid API key
'404':
description: Submission not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: Image quality gate failed (reasons, quality in body) or extraction failed schema validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Document processing failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
get:
x-route-source:
file: routes/documents.js
method: get
path: /:submissionId
summary: List documents of a submission
description: Lists the documents uploaded to the submission, newest first, with processing status, extracted fields, preflight and MRZ results.
tags:
- Documents
operationId: listDocuments
parameters:
- name: submissionId
in: path
required: true
schema:
type: string
description: KYC submission id
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: Documents
content:
application/json:
schema:
$ref: '#/components/schemas/DocList'
'401':
description: Missing or invalid API key
'404':
description: Submission not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
DocPreflight:
type: object
properties:
ok:
type: boolean
quality:
type: object
additionalProperties: true
description: Image quality metrics.
reasons:
type: array
items:
type: string
reason:
type: string
MobileUploadStatus:
type: object
properties:
status:
type: string
enum:
- pending
- complete
- expired
description: expired also covers unknown tokens.
artifact:
type: object
additionalProperties: true
description: Stored artifact_metadata row (snake_case columns such as id, entity_id, artifact_type, storage_path, file_size_bytes, mime_type). Only when complete.
required:
- status
DocExtractResult:
type: object
properties:
docType:
type: string
enum:
- passport
- id
- formation
- adv
- proof_of_address
- cis
detectedType:
type: string
description: Present when docType was "auto".
data:
type: object
additionalProperties: true
description: Extracted fields; the shape depends on docType.
provider:
type: string
confidence:
type: number
description: 0-1
warnings:
type: array
items:
type: string
discrepancies:
description: Cross-field discrepancies found by the extractor, when any.
preflight:
$ref: '#/components/schemas/DocPreflight'
mrz:
type: object
additionalProperties: true
description: Machine-readable-zone parse (passport/id images only).
mrzMismatch:
type: boolean
description: true when the MRZ disagrees with the extracted fields or its checksums fail.
mrzDiscrepancies:
type: array
items:
type: string
MobileUploadResult:
type: object
properties:
ok:
type: boolean
enum:
- true
artifact:
type: object
additionalProperties: true
description: Stored artifact_metadata row (id, entity_id, artifact_type, storage_path, file_size_bytes, mime_type, ...).
DocUploadDedupe:
type: object
properties:
documentId:
type: string
docType:
type: string
status:
type: string
dedupe:
type: boolean
enum:
- true
imageRef:
type: string
required:
- documentId
- dedupe
DocExtractRequest:
type: object
properties:
docType:
type: string
enum:
- passport
- id
- formation
- adv
- proof_of_address
- cis
- auto
description: '"auto" classifies the document (falling back to the filename); a document that cannot be classified is rejected with 400.'
mimeType:
type: string
enum:
- image/jpeg
- image/png
- image/webp
- application/pdf
- image/heic
- image/heif
description: HEIC/HEIF is converted to JPEG on ingest.
data:
type: string
format: byte
description: Base64 file content, max 10 MB decoded.
filename:
type: string
description: Optional; used to guess the document type when docType is "auto".
originalData:
type: string
description: Set by the server when HEIC is converted; do not send.
originalMimeType:
type: string
description: Set by the server when HEIC is converted; do not send.
required:
- docType
- mimeType
- data
description: JSON only on this route. Unreadable (non-object) bodies are rejected with 400 "Unreadable request body".
DocList:
type: object
properties:
submissionId:
type: string
count:
type: integer
documents:
type: array
items:
$ref: '#/components/schemas/DocListItem'
DocUploadAccepted:
type: object
properties:
documentId:
type: string
docType:
type: string
detectedType:
type: string
description: Present when docType was "auto".
submissionId:
type: string
description: Only on the deferred-preflight response.
status:
type: string
enum:
- pending
- pending_manual_review
description: '"pending": extraction runs in the background, poll GET /documents/{submissionId}. "pending_manual_review": the image quality gate was unavailable; the document is parked and the submission re-processed automatically.'
reason:
type: string
enum:
- preflight_unavailable
message:
type: string
_links:
type: object
properties:
submission:
type: string
documents:
type: string
required:
- documentId
- status
MobileUploadToken:
type: object
properties:
token:
type: string
description: 48-hex-char one-time token.
expires_in:
type: integer
enum:
- 300
description: Seconds (5 minutes).
Error:
type: object
required:
- error
properties:
error:
type: string
DocListItem:
type: object
properties:
id:
type: string
docType:
type: string
provider:
type:
- string
- 'null'
status:
type: string
description: pending | processing | complete | error | review ...
error:
type:
- string
- 'null'
extracted:
type:
- object
- 'null'
additionalProperties: true
description: Extracted fields (shape depends on docType).
preflight:
type:
- object
- 'null'
additionalProperties: true
mrz:
type:
- object
- 'null'
additionalProperties: true
mrzMismatch:
type: boolean
createdAt:
type: string
format: date-time
startedAt:
type:
- string
- 'null'
format: date-time
completedAt:
type:
- string
- 'null'
format: date-time
KycExtraction:
type: object
properties:
submissionId:
type: string
documentId:
type: string
fields:
type:
- object
- 'null'
additionalProperties: true
description: Structured fields extracted from the CIS document by the VLM.
confidence:
type: object
additionalProperties:
type: number
description: Per-field confidence 0-1.
needs_review:
type: array
items:
type: string
extraction_model:
type: string
extraction_latency_ms:
type:
- integer
- 'null'
extracted_at:
type:
- string
- 'null'
format: date-time
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
BearerAuth:
type: http
scheme: bearer