Didit Standalone APIs API

The Standalone APIs API from Didit — 14 operation(s) for standalone apis.

OpenAPI Specification

didit-standalone-apis-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification Billing Standalone APIs API
  description: Identity verification API. Authenticate with x-api-key header.
servers:
- url: https://verification.didit.me
tags:
- name: Standalone APIs
paths:
  /v3/id-verification/:
    post:
      summary: ID Verification (document OCR + fraud checks)
      description: 'OCR an identity document and run document fraud checks in one call — returns the extracted holder fields, the parsed MRZ, an `Approved`/`Declined` `status`, and a `warnings` list explaining every issue found. Supports 14,000+ document types from 220+ countries and territories.


        **How it works.** Send the document''s `front_image` (required) and, for two-sided documents, the `back_image`. Upload uncropped photos with all four corners of the document visible — the service detects, aligns, and crops the document itself, so do not pre-crop. The document is classified automatically (you never declare the country or document type), the visual zone is read with OCR, and the MRZ and any barcodes are decoded. Cross-checks then validate dates, number formats, and MRZ check digits, and compare the visual zone against the MRZ. With `perform_document_liveness=true`, the images are additionally screened for screen replays, printed copies, and portrait manipulation.


        **Decision logic.** `status` is `Approved` unless at least one warning resolves to a decline. Fraud and hard-failure risks always decline: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, plus extraction failures (`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `INVALID_DATE`, and `MRZ_NOT_DETECTED` exist in workflow sessions but are never produced by this standalone endpoint.) Three risk groups are configurable per request via `invalid_mrz_action`, `inconsistent_data_action`, and `expiration_date_not_detected_action` (`DECLINE` or `NO_ACTION`). All other warnings (e.g. `POSSIBLE_DUPLICATED_USER`) are informational and never decline on their own. A document that cannot be processed at all returns `400` with `{"error": "COULD_NOT_RECOGNIZE_DOCUMENT"}`; a readable but problematic document returns `200` with `status: "Declined"` — always inspect `id_verification.status` and `id_verification.warnings`, not just the HTTP code.


        **Billing.** Each `200` response consumes one ID Verification API credit (standalone APIs have no free tier). When the organization''s balance cannot cover the call, the endpoint returns `403` with the not-enough-credits error before any image processing.


        **Session persistence (`save_api_request`, default `true`).** When `true`, the call is persisted as an API-type session: it appears in the Business Console, the returned `request_id` is a real session id you can pass to `GET /v3/session/{sessionId}/decision/`, the cropped document/portrait images are stored and returned as short-lived media URLs (`https://<media-host>/ocr/...`), and a `status.updated` webhook is emitted to your configured webhook endpoints. When `false`, nothing is stored, `request_id` is a one-off correlation UUID, and `portrait_image`/`front_image`/`back_image` are returned inline as base64-encoded JPEG strings.


        **Sandbox.** Sandbox API keys skip all processing and billing: after request validation (malformed input still returns `400`), the endpoint returns a static `Approved` mock payload (a fictional "Sandbox User" USA identity card), no session is persisted, and no credits are consumed.


        **Authentication.** Send your application''s API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{"detail": "You do not have permission to perform this action."}`) — this API never returns `401`.


        **Rate limit.** Shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.'
      operationId: post_v3id-verification
      tags:
      - Standalone APIs
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
              - front_image
              properties:
                front_image:
                  type: string
                  format: binary
                  description: 'Front side of the identity document. Allowed extensions: `tiff`, `jpg`, `jpeg`, `png`, `webp`, `pdf`. Maximum upload size: **10 MB** (larger files are rejected with `400`). PDFs are rendered to an image before OCR; encrypted PDFs require `front_image_password`. Images are automatically compressed to ~0.5 MB and EXIF orientation is applied. Upload the full, uncropped capture with all four corners of the document visible.'
                front_image_password:
                  type: string
                  description: Password to decrypt `front_image` when it is an encrypted PDF. Sending an encrypted PDF without (or with a wrong) password returns `400`.
                  writeOnly: true
                back_image:
                  type: string
                  format: binary
                  description: Back side of the document — send it whenever the document has one (many ID cards carry the MRZ or a barcode on the back; omitting it simply leaves the MRZ and back-side fields empty in the response — this endpoint does not raise a missing-MRZ warning). Same format and size limits as `front_image`. When omitted, `back_image` and back-side fields are `null` in the response.
                back_image_password:
                  type: string
                  description: Password to decrypt `back_image` when it is an encrypted PDF.
                  writeOnly: true
                perform_document_liveness:
                  type: boolean
                  default: false
                  description: 'When `true`, also screens both images for presentation fraud: screen replays (`SCREEN_CAPTURE_DETECTED`), printed copies (`PRINTED_COPY_DETECTED`), and portrait manipulation (`PORTRAIT_MANIPULATION_DETECTED`). Any of these auto-declines. Adds latency, so enable it only when you need fraud screening.'
                  example: true
                minimum_age:
                  type: integer
                  nullable: true
                  default: null
                  minimum: 1
                  maximum: 120
                  description: Accepted and validated (1–120) but **currently not applied** by this endpoint — it never produces a `MINIMUM_AGE_NOT_MET` warning from this field. Enforce age rules from the returned `date_of_birth`/`age`, or use a verification-session workflow with age restrictions.
                expiration_date_not_detected_action:
                  type: string
                  enum:
                  - NO_ACTION
                  - DECLINE
                  default: NO_ACTION
                  description: 'What to do when no expiration date can be read (`EXPIRATION_DATE_NOT_DETECTED`). Default `NO_ACTION` because many identity documents print no expiry date. Note: a *detected and past* expiry date always declines (`DOCUMENT_EXPIRED`), regardless of this option.'
                invalid_mrz_action:
                  type: string
                  enum:
                  - NO_ACTION
                  - DECLINE
                  default: DECLINE
                  description: What to do when the extracted MRZ fails check-digit validation (`MRZ_VALIDATION_FAILED`). A missing MRZ raises no warning on this endpoint. Only relevant for documents that carry an MRZ. `REVIEW` is not supported on this endpoint and returns `400`.
                inconsistent_data_action:
                  type: string
                  enum:
                  - NO_ACTION
                  - DECLINE
                  default: DECLINE
                  description: 'What to do when extracted data is internally inconsistent: `DATA_INCONSISTENT`, `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` (visual zone disagrees with the MRZ), or `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`.'
                preferred_characters:
                  type: string
                  enum:
                  - latin
                  - non_latin
                  default: latin
                  description: Preferred script for name/address fields on documents that print both Latin and non-Latin text (Arabic, Cyrillic, CJK, …). `latin` returns transliterated/Latin values; `non_latin` prefers the native script.
                save_api_request:
                  type: boolean
                  default: true
                  description: When `true` (default), persists the call as an API-type session — visible in the Business Console, retrievable via `GET /v3/session/{sessionId}/decision/` using the returned `request_id`, announced through a `status.updated` webhook, and with document images returned as media URLs. When `false`, nothing is stored, `request_id` is a transient UUID, and images are returned inline as base64 JPEG strings.
                  example: true
                vendor_data:
                  type: string
                  description: Optional opaque string (your internal user id, email, UUID…) stored on the persisted session and echoed back in the response. Use it to correlate API calls with your own records and to filter sessions later.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: Optional JSON object stored with the session (when `save_api_request=true`) and echoed back in the response. In multipart requests, send it as a JSON-encoded string field (e.g. `metadata={"flow":"onboarding"}`) — it is parsed into an object.
                  example:
                    flow: onboarding
            example:
              front_image: (binary JPEG/PNG/PDF of the document front)
              back_image: (binary JPEG/PNG/PDF of the document back)
              perform_document_liveness: true
              save_api_request: true
              vendor_data: user-123
              metadata:
                flow: onboarding
      responses:
        '200':
          description: 'Document processed. `id_verification.status` is `Approved` or `Declined`; every detected issue is itemized in `id_verification.warnings`. A problematic document still returns `200` with `status: "Declined"` — inspect the body, not just the HTTP code. When `save_api_request=true`, `request_id` is the persisted session id and image fields are short-lived media URLs; with `save_api_request=false` they are inline base64 JPEG strings.'
          content:
            application/json:
              examples:
                Approved:
                  summary: Two-sided ID card read cleanly (saved — images as media URLs)
                  value:
                    request_id: 11d219ed-d59c-4b1d-8d65-9b933f12d5b8
                    id_verification:
                      status: Approved
                      document_type: Identity Card
                      document_subtype: ID_CARD_GENERIC
                      document_number: CBX164224
                      personal_number: 20446581H
                      portrait_image: https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...
                      front_image: https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...
                      back_image: https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...
                      front_image_camera_front: null
                      back_image_camera_front: null
                      front_image_camera_front_face_match_score: null
                      back_image_camera_front_face_match_score: null
                      front_image_quality_score:
                        focus_score: 78
                        brightness_score: 83.2
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 40.7
                        overall_score: 70.2
                      back_image_quality_score:
                        focus_score: 100
                        brightness_score: 95.6
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 43
                        overall_score: 84.4
                      date_of_birth: '1980-01-13'
                      age: 46
                      expiration_date: '2032-03-31'
                      date_of_issue: '2022-03-31'
                      issuing_state: ESP
                      issuing_state_name: Spain
                      first_name: Julio Francisco
                      last_name: Fores Sena
                      full_name: Julio Francisco Fores Sena
                      gender: M
                      address: Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal De La Laguna,Santa Cruz De Tenerife
                      formatted_address: Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain
                      place_of_birth: Valencia, Valencia
                      marital_status: UNKNOWN
                      nationality: ESP
                      extra_fields:
                        first_surname: Fores
                        second_surname: Sena
                      mrz:
                        surname: FORES SENA
                        name: JULIO FRANCISCO
                        country: ESP
                        nationality: ESP
                        birth_date: '800113'
                        expiry_date: '320331'
                        sex: M
                        document_type: ID
                        document_number: CBX164224
                        optional_data: 20446581H
                        optional_data_2: ''
                        birth_date_hash: '9'
                        expiry_date_hash: '8'
                        document_number_hash: '3'
                        final_hash: '3'
                        personal_number: 20446581H
                        warnings: []
                        errors: []
                        mrz_type: TD1
                        mrz_string: 'IDESPCBX164224320446581H<<<<<<

                          8001139M3203318ESP<<<<<<<<<<<3

                          FORES<SENA<<JULIO<FRANCISCO<<<'
                        mrz_key: CBX164224380011393203318
                      parsed_address:
                        street_1: Avenida el Cardonal 52
                        street_2: b
                        city: La Laguna
                        region: Canarias
                        country: ES
                        postal_code: '38108'
                        address_type: Avenida
                        formatted_address: Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain
                        raw_results:
                          address_components:
                          - long_name: b
                            short_name: b
                            types:
                            - subpremise
                          - long_name: '52'
                            short_name: '52'
                            types:
                            - street_number
                          - long_name: Avenida el Cardonal
                            short_name: Av. el Cardonal
                            types:
                            - route
                          - long_name: La Laguna
                            short_name: La Laguna
                            types:
                            - locality
                            - political
                          - long_name: Spain
                            short_name: ES
                            types:
                            - country
                            - political
                          - long_name: '38108'
                            short_name: '38108'
                            types:
                            - postal_code
                          formatted_address: Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain
                          geometry:
                            location:
                              lat: 28.4501161
                              lng: -16.3004407
                            location_type: ROOFTOP
                          types:
                          - street_address
                          - subpremise
                        document_location:
                          latitude: 28.4501161
                          longitude: -16.3004407
                        label: Spain Identity Card Address
                        is_verified: true
                        category: Residential
                      warnings: []
                      barcodes: []
                    vendor_data: user-123
                    metadata:
                      flow: onboarding
                    created_at: '2026-06-12T02:21:56.013573+00:00'
                Declined - expired document:
                  summary: Front-only upload of an expired ID card
                  value:
                    request_id: f61681b8-9422-4378-ac3e-04c6a247fb45
                    id_verification:
                      status: Declined
                      document_type: Identity Card
                      document_subtype: ID_CARD_GENERIC
                      document_number: BNK123072
                      personal_number: 21771255F
                      portrait_image: https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-portrait_image-1d9a.jpg?signature=...
                      front_image: https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-front_image-5c2b.jpg?signature=...
                      back_image: null
                      front_image_camera_front: null
                      back_image_camera_front: null
                      front_image_camera_front_face_match_score: null
                      back_image_camera_front_face_match_score: null
                      front_image_quality_score:
                        focus_score: 100
                        brightness_score: 95.7
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 22.2
                        overall_score: 79.3
                      back_image_quality_score: null
                      date_of_birth: '1997-01-30'
                      age: 29
                      expiration_date: '2025-11-26'
                      date_of_issue: null
                      issuing_state: ESP
                      issuing_state_name: Spain
                      first_name: Lucia
                      last_name: Marin Castro
                      full_name: Lucia Marin Castro
                      gender: F
                      address: null
                      formatted_address: null
                      place_of_birth: null
                      marital_status: UNKNOWN
                      nationality: ESP
                      extra_fields:
                        first_surname: Marin
                        second_surname: Castro
                      mrz: {}
                      parsed_address: null
                      warnings:
                      - risk: DOCUMENT_EXPIRED
                        feature: ID_VERIFICATION
                        additional_data: null
                        log_type: error
                        short_description: Document expired
                        long_description: The document's expiration date has passed, rendering it no longer valid for use.
                      barcodes: []
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:25:48.117204+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: Persisted session id when `save_api_request=true` (usable with `GET /v3/session/{sessionId}/decision/`); otherwise a transient correlation UUID.
                  id_verification:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                        - Approved
                        - Declined
                        description: '`Approved` when no warning resolves to a decline; `Declined` otherwise — the `warnings` list explains why.'
                      document_type:
                        type: string
                        nullable: true
                        description: 'Detected document type display name: `Identity Card`, `Passport`, `Driver''s License`, `Residence Permit`, `Health Insurance Card`, or `Tax Card`. `null` when the document could not be classified.'
                        example: Identity Card
                      document_subtype:
                        type: string
                        nullable: true
                        description: Finer-grained subtype when available (e.g. `ID_CARD_GENERIC`, `EPASSPORT`).
                        example: ID_CARD_GENERIC
                      document_number:
                        type: string
                        nullable: true
                        example: CBX164224
                      personal_number:
                        type: string
                        nullable: true
                        description: Secondary personal/national number printed on some documents.
                        example: 20446581H
                      portrait_image:
                        type: string
                        nullable: true
                        description: Cropped portrait photo from the document. A short-lived media URL (`https://<media-host>/ocr/...`) when `save_api_request=true` (default); an inline base64-encoded JPEG string when `save_api_request=false`. `null` when no portrait was detected.
                      front_image:
                        type: string
                        nullable: true
                        description: Aligned crop of the document front. Media URL when saved, inline base64 JPEG otherwise.
                      back_image:
                        type: string
                        nullable: true
                        description: Aligned crop of the document back. `null` when no `back_image` was uploaded.
                      front_image_camera_front:
                        type: string
                        nullable: true
                        description: Always `null` on this endpoint (populated only in camera-capture verification sessions).
                      back_image_camera_front:
                        type: string
                        nullable: true
                        description: Always `null` on this endpoint.
                      front_image_camera_front_face_match_score:
                        type: number
                        nullable: true
                        description: Always `null` on this endpoint.
                      back_image_camera_front_face_match_score:
                        type: number
                        nullable: true
                        description: Always `null` on this endpoint.
                      front_image_quality_score:
                        type: object
                        nullable: true
                        description: Capture-quality diagnostics for the uploaded image (`null` when the side was not provided or scoring failed). All scores are 0–100.
                        properties:
                          focus_score:
                            type: number
                            format: float
                            description: Sharpness of the document crop (higher is sharper).
                          brightness_score:
                            type: number
                            format: float
                            description: Exposure quality (higher is better).
                          brightness_issue:
                            type: string
                            nullable: true
                            description: '`ok` when exposure is fine, otherwise the detected issue (e.g. too dark / too bright).'
                          is_document_fully_visible:
                            type: boolean
                            nullable: true
                            description: Whether all four corners of the document are inside the frame.
                          resolution_score:
                            type: number
                            format: float
                            description: Effective resolution of the document area.
                          overall_score:
                            type: number
                            format: float
                            description: Aggregate quality score.
                      back_image_quality_score:
                        type: object
                        nullable: true
                        description: Capture-quality diagnostics for the uploaded image (`null` when the side was not provided or scoring failed). All scores are 0–100.
                        properties:
                          focus_score:
                            type: number
                            format: float
                            description: Sharpness of the document crop (higher is sharper).
                          brightness_score:
                            type: number
                            format: float
                            description: Exposure quality (higher is better).
                          brightness_issue:
                            type: string
                            nullable: true
                            description: '`ok` when exposure is fine, otherwise the detected issue (e.g. too dark / too bright).'
                          is_document_fully_visible:
                            type: boolean
                            nullable: true
                            description: Whether all four corners of the document are inside the frame.
                          resolution_score:
                            type: number
                            format: float
                            description: Effective resolution of the document area.
                          overall_score:
                            type: number
                            format: float
                            description: Aggregate quality score.
                      date_of_birth:
                        type: string
                        format: date
                        nullable: true
                        example: '1980-01-13'
                      age:
                        type: integer
                        nullable: true
                        description: Holder age in years, computed from `date_of_birth`.
                        example: 46
                      expiration_date:
                        type: string
                        format: date
                        nullable: true
                        example: '2032-03-31'
                      date_of_issue:
                        type: string
                        format: date
                        nullable: true
                        example: '2022-03-31'
                      issuing_state:
                        type: string
                        nullable: true
                        description: Issuing country (ISO 3166-1 alpha-3).
                        example: ESP
                      issuing_state_name:
                        type: string
                        nullable: true
                        example: Spain
                      first_name:
                        type: string
                        nullable: true
                        example: Julio Francisco
                      last_name:
                        type: string
                        nullable: true
                        example: Fores Sena
                      full_name:
                        type: string
                        nullable: true
                        example: Julio Francisco Fores Sena
                      gender:
                        type: string
                        nullable: true
                        description: '`M`, `F`, or `null` when not printed/detected.'
                        example: M
                      address:
                        type: string
                        nullable: true
                        description: Address exactly as printed on the document.
                      formatted_address:
                        type: string
                        nullable: true
                        description: Geocoded, normalized version of `address`.
                      place_of_birth:
                        type: string
                        nullable: true
                        example: Valencia, Valencia
                      marital_status:
                        type: string
                        nullable: true
                        description: '`UNKNOWN` unless the document prints marital status.'
                        example: UNKNOWN
                      nationality:
                        type: string
                        nullable: true
                        description: Holder nationality (ISO 3166-1 alpha-3).
                        example: ESP
                      extra_fields:
                        type: object
                        nullable: true
                        additionalProperties: true
                        description: Document-specific extras that have no dedicated column (e.g. `first_surname`/`second_surname` on Spanish IDs, license classes on driving licenses).
                      mrz:
                        type: object
                        description: Parsed machine-readable zone. An **empty object** (`{}`) when the document has no MRZ or it could not be read — also check the `warnings` list in that case. Dates inside the MRZ use the raw `YYMMDD` format.
                        properties:
                          surname:
                            type: string
                            example: FORES SENA
                          name:
                            type: string
                            example: JULIO FRANCISCO
                          country:
                            type: string
                            description: Issuing country (ISO 3166-1 alpha-3).
                            example: ESP
                          nationality:
                            type: string
                            description: Holder nationality (ISO 3166-1 alpha-3).
                            example: ESP
                          birth_date:
                            type: string
                            description: Raw MRZ date of birth (`YYMMDD`).
                            example: '800113'
                          expiry_date:
                            type: string
                            description: Raw MRZ expiry date (`YYMMDD`).
                            example: '320331'
                          sex:
                            type: string
                            example: M
                          document_type:
                            type: string
                            description: MRZ document-type code (e.g. `ID`, `P`).
                            example: ID
                          document_number:
                            type: string
                            example: CBX164224
                          optional_data:
                            type: string
                            nullable: true
                            example: 20446581H
                          optional_data_2:
                            type: string
                            nullable: true
                            example: ''
                          birth_date_hash:
                            type: string
                            description: MRZ check digit for the birth date.
                            example: '9'
          

# --- truncated at 32 KB (418 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/didit/refs/heads/main/openapi/didit-standalone-apis-api-openapi.yml