> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rial.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a verification

> Create a verification and get the link to send. Its settings are fixed once created; to change them, create another.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/verifications
openapi: 3.1.0
info:
  title: rial API
  version: 0.1.0
  description: 'Prove a photo is real. Base URL: https://api.rial.io'
  contact:
    name: rial-platform team
    url: https://github.com/Rial-ventures-Inc/rial-platform
  license:
    name: UNLICENSED — proprietary, internal use only
servers:
  - url: https://api.rial.io
    description: Production
security: []
tags:
  - name: Verifications
    description: >-
      Create, fetch, list, and finalize verifications. The core of the API —
      every tenant integration starts here.
  - name: Audits
    description: >-
      Check a photo you already have. `POST /v1/audits/sync` answers AI
      detection in the same call; every other audit is a verification in `audit`
      mode.
  - name: Templates
    description: >-
      Publish, update, revoke and inspect link templates — the reusable capture
      links behind `/l/{token}` (a compact JWT carrying the org and template
      slugs; the legacy `/l/{org}/{slug}` keeps resolving). Callable with a
      secret key; each publish snapshots a versioned capture spec (GET-83).
  - name: Databases
    description: >-
      Create, update, inspect and synchronize tenant-scoped databases used by
      reusable verification templates. Callable with a dashboard session or
      secret API key.
  - name: Credits
    description: >-
      Prepaid photo credits at US$0.20 a photo, bought in packs by an agent with
      the card a person saved, under a monthly spend cap. Through the API every
      feature is on in any plan; credits pay for the photos. Callable with a
      dashboard session or secret API key.
paths:
  /v1/verifications:
    post:
      tags:
        - Verifications
      summary: Create a verification
      description: >-
        Create a verification and get the link to send. Its settings are fixed
        once created; to change them, create another.
      requestBody:
        required: true
        description: >-
          Send `steps` for guided photos, or `max_captures` for N anonymous
          photos (default 1) — never both. Everything else is optional.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVerificationRequest'
            example:
              max_captures: 3
              expires_in_seconds: 3600
              context:
                kind: damage_claim
                summary: Toyota Corolla front bumper
              webhook_url: https://api.acmeinsurance.com/rial/webhooks
              metadata:
                claim_id: CLM-9912
      responses:
        '201':
          description: >-
            Verification minted. Returns the canonical wire shape including the
            `capture_url` the tenant sends to the end-user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeveloperVerification'
              example:
                id: vfy_01HXYZABCDEFGHJKMNPQRSTVWX
                status: pending
                capture_url: https://verify.rial.io/v/vfy_01HXYZABCDEFGHJKMNPQRSTVWX
                created_at: '2026-09-16T19:06:57.718Z'
                expires_at: '2026-09-16T20:06:57.718Z'
                captures_count: 0
        '400':
          description: Request body failed Zod validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: invalid_request
                  message: Request body failed validation
                  fields:
                    - path: config.max_captures
                      message: must be ≤ 20
        '401':
          description: No valid session / API key / bot HMAC.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: unauthorized
                  message: Missing or invalid API key
        '402':
          description: >-
            `plan_limit_reached` or `insufficient_credits`: monthly plan quota
            and legacy credits cannot cover another image.
            `monthly_verification_limit_reached`: the account already created
            its monthly verification allowance (1000 unless agreed otherwise)
            this UTC calendar month, through any channel; creation reopens when
            the month turns, or on the Enterprise plan. Verifications and links
            already created can still be completed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: monthly_verification_limit_reached
                  message: >-
                    Monthly limit of 1000 verifications reached. Contact Rial to
                    move to the Enterprise plan.
        '429':
          description: >-
            Tenant rate limit exceeded. Response carries `Retry-After:
            <seconds>` per RFC 7231.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: too_many_requests
                  message: >-
                    Rate limit exceeded for this tenant. Retry after the
                    specified interval.
      security:
        - bearerApiKey: []
components:
  schemas:
    CreateVerificationRequest:
      type: object
      additionalProperties: false
      description: >-
        Body for `POST /v1/verifications`. All fields optional — sensible
        defaults: `max_captures: 1`, `expires_in_seconds: 3600`. Every photo
        gets the screen and AI checks; an audit adds found-online; describing
        the photo (`expected_object`, `context`) turns the context check on.
        Capture quantity comes as EITHER `max_captures` (N anonymous captures)
        OR `steps` (guided slots with key/description/min/max) — never both.
        `context` is what the analysis pipeline cross-references against the
        capture; `metadata` is opaque pass-through echoed back on every webhook
        event.
      properties:
        max_captures:
          type: integer
          minimum: 1
          maximum: 20
          description: >-
            How many anonymous photos to ask for. Use this or `steps`, never
            both. Default 1.
        steps:
          type: array
          items:
            oneOf:
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - image
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  min:
                    type: integer
                    minimum: 0
                    default: 1
                    description: Minimum photos. 0 makes the step optional. Default 1.
                  max:
                    type: integer
                    minimum: 1
                    default: 1
                    description: Maximum photos. Default 1.
                  allow_upload:
                    type: boolean
                    description: >-
                      Also allow picking a file from the gallery instead of the
                      camera.
                  accept:
                    type: array
                    items:
                      type: string
                      enum:
                        - image/jpeg
                        - image/png
                        - image/webp
                        - image/heic
                        - image/heif
                    minItems: 1
                    description: Accepted media types.
                  max_size_bytes:
                    type: integer
                    minimum: 1
                    maximum: 26214400
                    description: Maximum size per photo, in bytes.
                  expected_object:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: >-
                      What must appear in this photo. Overrides the
                      verification-level value.
                  condition_aspects:
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 40
                    minItems: 1
                    maxItems: 6
                    description: >-
                      Aspects to score on this photo. Overrides the
                      verification-level value.
                required:
                  - key
                  - type
                additionalProperties: false
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - text
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  required:
                    type: boolean
                    default: true
                    description: Default true.
                  validation:
                    type: object
                    properties:
                      min_length:
                        type: integer
                        minimum: 0
                        maximum: 2000
                      max_length:
                        type: integer
                        minimum: 1
                        maximum: 2000
                      format:
                        type: string
                        enum:
                          - free_text
                          - numeric_id
                          - alphanumeric_id
                          - email
                        default: free_text
                    default:
                      format: free_text
                    additionalProperties: false
                    description: >-
                      Length and format rules: `free_text`, `numeric_id`,
                      `alphanumeric_id` or `email`.
                  variant:
                    type: string
                    enum:
                      - short
                      - long
                    description: '`short` (one line) or `long`.'
                required:
                  - key
                  - type
                additionalProperties: false
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - upload
                  input:
                    type: string
                    enum:
                      - signature
                    description: >-
                      `signature` shows a signature pad instead of a file
                      picker.
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  min:
                    type: integer
                    minimum: 0
                    default: 1
                    description: Minimum files. 0 makes the step optional. Default 1.
                  max:
                    type: integer
                    minimum: 1
                    default: 1
                    description: Maximum files. Default 1.
                  accept:
                    type: array
                    items:
                      type: string
                      enum:
                        - image/jpeg
                        - image/png
                        - image/webp
                        - image/heic
                        - image/heif
                    minItems: 1
                    default:
                      - image/jpeg
                      - image/png
                      - image/webp
                      - image/heic
                      - image/heif
                    description: Accepted media types.
                  max_size_bytes:
                    type: integer
                    minimum: 1
                    maximum: 26214400
                    default: 10485760
                    description: Maximum size per file, in bytes.
                required:
                  - key
                  - type
                additionalProperties: false
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - video
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  min:
                    type: integer
                    minimum: 0
                    default: 1
                    description: Minimum clips. 0 makes the step optional. Default 1.
                  max:
                    type: integer
                    minimum: 1
                    default: 1
                    description: Maximum clips. Default 1.
                  expected_object:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: >-
                      What the clip must show. Every sampled frame is checked
                      against it and the clip reads as object match / no match
                      by persistence.
                  expected_scene:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: >-
                      What the clip as a whole must show, in order ("a walk
                      around the car with the hood open, ending on the engine
                      bay"). Judged once per clip over a contact sheet of its
                      frames; the clip reads as scene match / no match with the
                      reason. Absent: no scene check.
                  audio:
                    type: boolean
                    default: false
                    description: >-
                      Record the microphone with the clip. The person is asked
                      for microphone access on this step; a refusal still
                      records the video, without sound. Default false.
                  condition_aspects:
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 40
                    minItems: 1
                    maxItems: 6
                    description: >-
                      Aspects to score on the clip. Judged once per clip over a
                      contact sheet of its frames, like `expected_scene`; scored
                      0..10 with a reason each. Overrides the verification-level
                      value.
                  max_duration_sec:
                    type: integer
                    minimum: 1
                    maximum: 60
                    default: 60
                    description: Maximum length of each clip, in seconds.
                required:
                  - key
                  - type
                additionalProperties: false
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - choice
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  required:
                    type: boolean
                    default: true
                    description: Default true.
                  multiple:
                    type: boolean
                    default: false
                    description: Allow picking more than one option.
                  options:
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          minLength: 1
                          maxLength: 64
                          pattern: ^[a-z0-9][a-z0-9_-]*$
                        label:
                          type: string
                          minLength: 1
                          maxLength: 500
                      required:
                        - key
                        - label
                      additionalProperties: false
                    minItems: 1
                    maxItems: 50
                    description: Options to pick from, each with `key` and `label`.
                required:
                  - key
                  - type
                  - options
                additionalProperties: false
              - type: object
                properties:
                  label:
                    type: string
                    minLength: 1
                    maxLength: 200
                    description: Visible title of the step.
                  screen:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      title:
                        type: string
                        minLength: 1
                        maxLength: 120
                      description:
                        type: string
                        maxLength: 8000
                    required:
                      - key
                      - title
                    additionalProperties: false
                    description: >-
                      Groups consecutive steps on one screen: `key` and `title`
                      shared by the group.
                  when:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                      value:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[a-z0-9][a-z0-9_-]*$
                    required:
                      - key
                      - value
                    additionalProperties: false
                    description: >-
                      Show this step only when the step `key` was answered with
                      `value`.
                  key:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9_-]*$
                    description: >-
                      Stable id of the step. Its answer or photos come back
                      under this key.
                  type:
                    type: string
                    enum:
                      - address
                  country:
                    type: string
                    enum:
                      - BR
                    description: '`BR` shows Brazilian address fields.'
                  description:
                    type: string
                    maxLength: 500
                    default: ''
                    description: Instruction shown to the person.
                  required:
                    type: boolean
                    default: true
                    description: Default true.
                required:
                  - key
                  - type
                additionalProperties: false
          minItems: 1
          description: >-
            Guided steps in order: photos, text questions, uploads, choices,
            addresses. Use this or `max_captures`.
        expires_in_seconds:
          type: integer
          minimum: 60
          maximum: 86400
          default: 3600
          description: >-
            How long the capture link stays open, in seconds. Default 3600 (one
            hour), max 86400.
        seal:
          type: boolean
          default: true
          description: Stamp the delivered photos with a C2PA seal. Default true.
        mode:
          type: string
          enum:
            - verification
            - audit
          description: >-
            `verification` (photo taken live, default) or `audit` (a file that
            already exists, uploaded through the API).
        context:
          type: object
          properties:
            kind:
              type: string
              minLength: 1
              maxLength: 64
            summary:
              type: string
              minLength: 1
              maxLength: 500
            attributes:
              type: object
              additionalProperties:
                anyOf:
                  - type: string
                  - type: number
                  - type: boolean
          required:
            - kind
            - summary
          description: >-
            What the photo is supposed to show, for the `context` check: `kind`
            names the thing, `summary` describes it in one line.
        webhook_url:
          type: string
          format: uri
          description: >-
            HTTPS URL that receives `verification.created` and
            `verification.completed`.
        notify_email:
          type:
            - string
            - 'null'
          maxLength: 254
          format: email
          description: >-
            Email that receives the result. `null` opts this verification out;
            absent uses your account default.
        report_language:
          type: string
          enum:
            - es
            - en
        notify_subject_template:
          type:
            - string
            - 'null'
          minLength: 1
          description: Subject of the result email. `{variable}` placeholders allowed.
        notify_body_template:
          type:
            - string
            - 'null'
          minLength: 1
          description: Body of the result email. `{variable}` placeholders allowed.
        completion_message:
          type:
            - string
            - 'null'
          minLength: 1
          maxLength: 2000
          description: >-
            Full plain-text message shown after submitting content. HTML,
            markdown and variables are not interpreted. Omit on create or send
            null on PATCH to use the default.
        metadata:
          type: object
          additionalProperties:
            type: string
            maxLength: 500
          description: >-
            Your own key/value strings, returned with every result and webhook.
            Example: `{ "claim_id": "CLM-9912" }`.
        requires_location:
          type: boolean
          description: >-
            Require a GPS fix on the first photo without comparing it to an
            address.
        security_level:
          type: string
          enum:
            - none
            - low
            - medium
            - high
          description: >-
            How much the phone asks of the person at each shot, from `low` to
            `high`; `none` runs no capture checks. Absent: `none`.
        expected_location:
          type: string
          minLength: 1
          maxLength: 300
          description: >-
            Street address the photo must be taken at. Turns on
            `location_match`.
        expected_object:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            What must appear in the photo, e.g. `"car"`. Turns on
            `object_match`.
        condition_aspects:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 40
          minItems: 1
          maxItems: 6
          description: >-
            One to six aspects to score from 0 to 10, e.g. `["paint", "tires"]`.
            Turns on `condition`.
        expected_info:
          type: object
          properties:
            source:
              type: string
              enum:
                - individual
                - csv
              default: individual
            shared:
              type: object
              properties:
                expected_location:
                  type: string
                  minLength: 1
                  maxLength: 300
                expected_object:
                  type: string
                  minLength: 1
                  maxLength: 200
                condition_aspects:
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 40
                  minItems: 1
                  maxItems: 6
                ocr_type:
                  type: string
                  minLength: 1
                  maxLength: 40
              additionalProperties: false
            subject:
              type: object
              properties:
                expected_location:
                  type: string
                  minLength: 1
                  maxLength: 300
                expected_object:
                  type: string
                  minLength: 1
                  maxLength: 200
                condition_aspects:
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 40
                  minItems: 1
                  maxItems: 6
                ocr_type:
                  type: string
                  minLength: 1
                  maxLength: 40
                asset_ref:
                  type: string
                  minLength: 1
                  maxLength: 120
                person:
                  type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 120
                    email:
                      type: string
                      maxLength: 254
                      format: email
                    phone_e164:
                      type: string
                      pattern: ^\+[1-9]\d{6,14}$
                    external_ref:
                      type: string
                      minLength: 1
                      maxLength: 120
                  additionalProperties: false
              additionalProperties: false
          additionalProperties: false
          description: >-
            Structured alternative to `expected_location`, `expected_object` and
            `condition_aspects`. Send one form or the other.
        brand_slug:
          type: string
          minLength: 2
          maxLength: 40
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          description: >-
            Brand profile shown on the capture page. Absent = your default
            brand.
    DeveloperVerification:
      type: object
      properties:
        id:
          type: string
          pattern: ^vfy_[0-9A-HJKMNP-TV-Z]{26}$
        status:
          type: string
          enum:
            - pending
            - partially_captured
            - completed
            - expired
            - failed
            - abandoned
          description: >-
            Lifecycle state. `pending` → first capture flips to
            `partially_captured` → analysis sets the verdict and transitions to
            `completed`. Terminal: `completed`, `expired`, `failed`. `abandoned`
            is a side-branch off `pending`/`partially_captured`, reported by the
            capture screen via `POST /v1/verifications/:token/progress` when the
            end user leaves before finishing — NOT terminal: a later capture
            resurrects the row to `partially_captured` like any other.
        capture_url:
          type: string
          format: uri
        created_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        captures_count:
          type: integer
          minimum: 0
        verdict:
          anyOf:
            - type: object
              properties:
                reverse_search:
                  type: object
                  properties:
                    state:
                      type: string
                      enum:
                        - pending
                        - review
                        - no_match
                        - inconclusive
                        - expired
                    sources:
                      type: array
                      items:
                        type: string
                        format: uri
                  required:
                    - state
                    - sources
                  description: >-
                    Secondary reverse-search state. Similarity candidates
                    require review; they are not confirmed fraud findings.
                rial:
                  type: boolean
                  description: >-
                    True when the dashboard verdict is verified and no exposed
                    fraud check tripped.
                signals:
                  type: array
                  items:
                    type: string
                    enum:
                      - screen_detected
                      - ai_detected
                      - found_online
                    description: >-
                      A check that tripped: `screen_detected` (photo of a
                      screen), `ai_detected` (AI-generated), `found_online`
                      (already published).
                  description: The checks that tripped.
                unavailable:
                  type: array
                  items:
                    type: string
                    enum:
                      - screen
                      - ai
                      - reverse
                      - context
                  minItems: 1
                  description: >-
                    Checks that could not be completed because the detector
                    never answered after every retry: `screen` (photo of a
                    screen), `ai` (AI-generated), `reverse` (already online),
                    `context`, `depth`. Present only when non-empty; `rial` is
                    then false — the photo was not fully checked, which is not
                    the same as a finding.
              required:
                - rial
                - signals
              description: >-
                Verdict of a live capture. Branch on `rial`; `signals` says why
                when it is false, and `unavailable` when a check could not be
                completed.
            - type: object
              properties:
                reverse_search:
                  type: object
                  properties:
                    state:
                      type: string
                      enum:
                        - pending
                        - review
                        - no_match
                        - inconclusive
                        - expired
                    sources:
                      type: array
                      items:
                        type: string
                        format: uri
                  required:
                    - state
                    - sources
                  description: >-
                    Secondary reverse-search state. Similarity candidates
                    require review; they are not confirmed fraud findings.
                rial:
                  type: boolean
                  description: Rial/no Rial result of the audit, matching the dashboard.
                signals:
                  type: array
                  items:
                    oneOf:
                      - type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - screen_detected
                        required:
                          - type
                      - type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - ai_detected
                          confidence:
                            type: number
                            minimum: 0
                            maximum: 1
                        required:
                          - type
                      - type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - found_online
                        required:
                          - type
                    description: A check that tripped on an audited file.
                unavailable:
                  type: array
                  items:
                    type: string
                    enum:
                      - screen
                      - ai
                      - reverse
                      - context
                  minItems: 1
                  description: >-
                    Checks that could not be completed because the detector
                    never answered after every retry: `screen` (photo of a
                    screen), `ai` (AI-generated), `reverse` (already online),
                    `context`, `depth`. Present only when non-empty; `rial` is
                    then false — the photo was not fully checked, which is not
                    the same as a finding.
              required:
                - rial
                - signals
              description: >-
                Verdict of an audit (`mode: "audit"`, a file that already
                existed). Includes the Rial/no Rial result and the checks that
                tripped. This is an analysis result, not proof of live capture.
        location:
          type: object
          properties:
            lat:
              type: number
            lng:
              type: number
            accuracy_m:
              type: number
              minimum: 0
            derived_from:
              type: string
              enum:
                - exif
                - live
                - last_known_session
                - last_known_system
                - last_known_persisted
            age_ms:
              type: integer
              minimum: 0
            place:
              type: string
          required:
            - lat
            - lng
            - accuracy_m
          description: >-
            Where the photo was taken, from the device. Absent for uploaded
            files and when the device reported no fix.
        location_match:
          type: object
          properties:
            status:
              type: string
              enum:
                - verified
                - no_match
                - ungeocoded
                - rejected
                - not_applicable
            expected_location:
              type: string
            observed_location:
              type: string
            expected_point:
              type: object
              properties:
                lat:
                  type: number
                lng:
                  type: number
              required:
                - lat
                - lng
            observed_point:
              type: object
              properties:
                lat:
                  type: number
                lng:
                  type: number
              required:
                - lat
                - lng
            distance_m:
              type: number
              minimum: 0
            threshold_m:
              type: number
              minimum: 0
            gps_accuracy_m:
              type: number
              minimum: 0
            geocode_ref:
              type: string
            reason:
              type: string
          required:
            - status
          description: >-
            Whether the photo was taken at `expected_location`. `verified`
            within GPS tolerance; `no_match` somewhere else; `ungeocoded` when
            the address or the fix could not be resolved; `rejected` when the
            device reported a mock location.
        object_match:
          type: object
          properties:
            status:
              type: string
              enum:
                - match
                - mismatch
                - inconclusive
            expected_object:
              type: string
          required:
            - status
          description: >-
            Object-check result. Present when an object check was requested
            globally or on an image step. With step-only configuration the
            status is the worst step result and expected_object is omitted.
            Independent of the fraud verdict.
        object_matches:
          type: object
          additionalProperties:
            type: object
            properties:
              status:
                type: string
                enum:
                  - match
                  - mismatch
                  - inconclusive
              expected_object:
                type: string
            required:
              - status
              - expected_object
            description: >-
              Object-check result for one image step, including its expected
              object.
          description: >-
            Object-check results keyed by image step. Missing capture verdicts
            yield inconclusive; otherwise each value is the worst context result
            for the step, ignoring not_applicable when live evidence exists.
        condition:
          type: object
          properties:
            score:
              type: number
              minimum: 0
              maximum: 10
            label:
              type: string
              enum:
                - good
                - fair
                - poor
            aspects:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                  score:
                    type: number
                    minimum: 0
                    maximum: 10
                  reasoning:
                    type: string
                required:
                  - name
                  - score
                  - reasoning
                description: >-
                  One scored aspect of the condition assessment. `name` echoes
                  the free-form tenant-defined aspect from `condition_aspects`
                  verbatim — any language, any domain, no fixed vocabulary.
                  `score` is 0..10 with one decimal; `reasoning` is a
                  one-or-two-sentence visual justification.
            provenance:
              type: object
              properties:
                model:
                  type: string
                prompt:
                  type: string
                instructions_sha256:
                  type: string
                  minLength: 64
                  maxLength: 64
              required:
                - model
                - prompt
              description: >-
                What produced this assessment: the model, the prompt
                (`id@version`) and, when your organization's condition
                instructions applied, their SHA-256 — so a result stays tied to
                the guidance and model of its day. Absent on assessments written
                before this field existed.
            steps:
              type: object
              additionalProperties:
                type: object
                properties:
                  score:
                    type: number
                    minimum: 0
                    maximum: 10
                  label:
                    type: string
                    enum:
                      - good
                      - fair
                      - poor
                  aspects:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        score:
                          type: number
                          minimum: 0
                          maximum: 10
                        reasoning:
                          type: string
                      required:
                        - name
                        - score
                        - reasoning
                      description: >-
                        One scored aspect of the condition assessment. `name`
                        echoes the free-form tenant-defined aspect from
                        `condition_aspects` verbatim — any language, any domain,
                        no fixed vocabulary. `score` is 0..10 with one decimal;
                        `reasoning` is a one-or-two-sentence visual
                        justification.
                  provenance:
                    type: object
                    properties:
                      model:
                        type: string
                      prompt:
                        type: string
                      instructions_sha256:
                        type: string
                        minLength: 64
                        maxLength: 64
                    required:
                      - model
                      - prompt
                    description: >-
                      What produced this assessment: the model, the prompt
                      (`id@version`) and, when your organization's condition
                      instructions applied, their SHA-256 — so a result stays
                      tied to the guidance and model of its day. Absent on
                      assessments written before this field existed.
                required:
                  - score
                  - label
                  - aspects
                description: >-
                  Condition assessment. Present only when the verification was
                  created with `condition_aspects` — the free-form
                  tenant-defined aspect names (any language, any domain).
                  `score` is the one-decimal average of aspect scores; `label`
                  buckets it (>=7.5 good, >=5 fair, else poor). Independent of
                  the fraud verdict.
              description: >-
                Condition results keyed by photo step. Each uses only that
                step’s photos and its rubric, falling back to the shared rubric.
                The aggregate averages all assessed aspect scores.
          required:
            - score
            - label
            - aspects
          description: >-
            Condition assessment. Present only when the verification was created
            with `condition_aspects` — the free-form tenant-defined aspect names
            (any language, any domain). `score` is the one-decimal average of
            aspect scores; `label` buckets it (>=7.5 good, >=5 fair, else poor).
            Independent of the fraud verdict.
        video_analysis:
          type: object
          properties:
            capture_id:
              type: string
            frames_extracted:
              type: integer
              minimum: 0
            frames_analyzed:
              type: integer
              minimum: 0
            scene:
              type: object
              properties:
                verdict:
                  type: string
                  enum:
                    - match
                    - mismatch
                    - inconclusive
                confidence:
                  type: number
                  minimum: 0
                  maximum: 1
                reasoning:
                  type: string
              required:
                - verdict
                - confidence
                - reasoning
              description: >-
                Whether the clip as a whole shows what the video step's
                `expected_scene` asked for, judged once over a contact sheet of
                its frames, with the reason. Absent when the step declared no
                scene or the check did not run.
            condition:
              type: object
              properties:
                score:
                  type: number
                  minimum: 0
                  maximum: 10
                label:
                  type: string
                  enum:
                    - good
                    - fair
                    - poor
                aspects:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                      score:
                        type: number
                        minimum: 0
                        maximum: 10
                      reasoning:
                        type: string
                    required:
                      - name
                      - score
                      - reasoning
                    description: >-
                      One scored aspect of the condition assessment. `name`
                      echoes the free-form tenant-defined aspect from
                      `condition_aspects` verbatim — any language, any domain,
                      no fixed vocabulary. `score` is 0..10 with one decimal;
                      `reasoning` is a one-or-two-sentence visual justification.
                provenance:
                  type: object
                  properties:
                    model:
                      type: string
                    prompt:
                      type: string
                    instructions_sha256:
                      type: string
                      minLength: 64
                      maxLength: 64
                  required:
                    - model
                    - prompt
                  description: >-
                    What produced this assessment: the model, the prompt
                    (`id@version`) and, when your organization's condition
                    instructions applied, their SHA-256 — so a result stays tied
                    to the guidance and model of its day. Absent on assessments
                    written before this field existed.
              required:
                - score
                - label
                - aspects
              description: >-
                The video step's `condition_aspects` scored over a contact sheet
                of the clip — the same 0..10 rubric and labels a photo step
                gets, read across the whole recording. Absent when the step
                declared no aspects or the check did not run.
            signals:
              type: object
              properties:
                screen:
                  type: object
                  properties:
                    detected:
                      type: boolean
                    frames_evaluated:
                      type: integer
                      minimum: 0
                    flagged_ratio:
                      type: number
                      minimum: 0
                      maximum: 1
                    longest_run_ms:
                      type: integer
                      minimum: 0
                    flagged_at_ms:
                      type: array
                      items:
                        type: integer
                        minimum: 0
                  required:
                    - detected
                    - frames_evaluated
                    - flagged_ratio
                    - longest_run_ms
                    - flagged_at_ms
                  description: >-
                    How one check behaved across the sampled frames. `detected`
                    is true when it tripped on at least half of
                    `frames_evaluated` or on three consecutive frames; isolated
                    trips are listed in `flagged_at_ms` without deciding.
                ai:
                  type: object
                  properties:
                    detected:
                      type: boolean
                    frames_evaluated:
                      type: integer
                      minimum: 0
                    flagged_ratio:
                      type: number
                      minimum: 0
                      maximum: 1
                    longest_run_ms:
                      type: integer
                      minimum: 0
                    flagged_at_ms:
                      type: array
                      items:
                        type: integer
                        minimum: 0
                  required:
                    - detected
                    - frames_evaluated
                    - flagged_ratio
                    - longest_run_ms
                    - flagged_at_ms
                  description: >-
                    How one check behaved across the sampled frames. `detected`
                    is true when it tripped on at least half of
                    `frames_evaluated` or on three consecutive frames; isolated
                    trips are listed in `flagged_at_ms` without deciding.
                reverse:
                  type: object
                  properties:
                    detected:
                      type: boolean
                    frames_evaluated:
                      type: integer
                      minimum: 0
                    flagged_ratio:
                      type: number
                      minimum: 0
                      maximum: 1
                    longest_run_ms:
                      type: integer
                      minimum: 0
                    flagged_at_ms:
                      type: array
                      items:
                        type: integer
                        minimum: 0
                  required:
                    - detected
                    - frames_evaluated
                    - flagged_ratio
                    - longest_run_ms
                    - flagged_at_ms
                  description: >-
                    How one check behaved across the sampled frames. `detected`
                    is true when it tripped on at least half of
                    `frames_evaluated` or on three consecutive frames; isolated
                    trips are listed in `flagged_at_ms` without deciding.
                context:
                  type: object
                  properties:
                    detected:
                      type: boolean
                    frames_evaluated:
                      type: integer
                      minimum: 0
                    flagged_ratio:
                      type: number
                      minimum: 0
                      maximum: 1
                    longest_run_ms:
                      type: integer
                      minimum: 0
                    flagged_at_ms:
                      type: array
                      items:
                        type: integer
                        minimum: 0
                  required:
                    - detected
                    - frames_evaluated
                    - flagged_ratio
                    - longest_run_ms
                    - flagged_at_ms
                  description: >-
                    How one check behaved across the sampled frames. `detected`
                    is true when it tripped on at least half of
                    `frames_evaluated` or on three consecutive frames; isolated
                    trips are listed in `flagged_at_ms` without deciding.
              description: >-
                One entry per check that ran on the clip; a missing entry was
                not evaluated, never clean.
            analyzed_at:
              type: string
              format: date-time
          required:
            - capture_id
            - frames_extracted
            - frames_analyzed
            - signals
            - analyzed_at
          description: >-
            Analysis of a video-step clip, sampled at one frame per second and
            run through the same checks a photo gets. Written asynchronously
            after capture — poll or use webhooks; absent until the worker has
            run.
        ocr_primary:
          type: string
        similar_photo:
          type: object
          properties:
            verification_id:
              type: string
            capture_id:
              type: string
            distance:
              type: integer
              minimum: 0
              maximum: 64
            method:
              type: string
              enum:
                - phash
                - embedding
            cosine:
              type: number
              minimum: -1
              maximum: 1
            inliers:
              type: integer
              minimum: 0
          required:
            - verification_id
            - capture_id
            - distance
          description: >-
            An earlier verification of yours whose photo matches this one.
            `method: "phash"`: the perceptual hashes are within threshold
            (Hamming `distance` 0–64; 0 is bit-identical) — a re-upload.
            `method: "embedding"`: the hashes differ but the photos are the same
            scene by embedding (`cosine`) and a geometric check confirmed it
            (`inliers`) — a screenshot or a crop. Present only when a match was
            found. It does not change `rial`: a legitimate re-submission and a
            recycled photo look the same — your reviewer decides.
        answers:
          type: object
          additionalProperties:
            type: object
            properties:
              values:
                type: array
                items:
                  type: string
              address:
                type: object
                properties:
                  street:
                    type: string
                    minLength: 1
                    maxLength: 200
                  number:
                    type: string
                    minLength: 1
                    maxLength: 200
                  neighborhood:
                    type: string
                    minLength: 1
                    maxLength: 200
                  complement:
                    type: string
                    maxLength: 200
                  city:
                    type: string
                    minLength: 1
                    maxLength: 200
                  region:
                    type: string
                    minLength: 1
                    maxLength: 200
                  postal_code:
                    type: string
                    maxLength: 200
                required:
                  - street
                  - number
                  - neighborhood
                  - city
                  - region
                  - postal_code
                additionalProperties: false
              value:
                type: string
                maxLength: 2000
              answered_at:
                type: string
                format: date-time
            required:
              - value
              - answered_at
            description: >-
              One answered text step. `value` is USER-DECLARED — typed by the
              person capturing; unlike live-captured content, it is never
              sensor-attested. Potential PII: it rides the operator/developer
              contracts and the webhook only, never OG cards or third-party
              public surfaces.
        record_seal:
          anyOf:
            - type: object
              properties:
                algorithm:
                  type: string
                  enum:
                    - sha256
                hash:
                  type: string
                  minLength: 64
                  maxLength: 64
                covers:
                  type: array
                  items:
                    type: string
                    enum:
                      - record
                      - answers
                answers_provenance:
                  type: string
                  enum:
                    - user_declared
              required:
                - algorithm
                - hash
                - covers
                - answers_provenance
            - type: object
              properties:
                algorithm:
                  type: string
                  enum:
                    - sha3-512
                hash:
                  type: string
                  minLength: 128
                  maxLength: 128
                covers:
                  type: array
                  items:
                    type: string
                    enum:
                      - record
                      - answers
                answers_provenance:
                  type: string
                  enum:
                    - user_declared
              required:
                - algorithm
                - hash
                - covers
                - answers_provenance
          description: >-
            Integrity seal over the verification record including `answers`.
            Present only when answers exist and sealing is on (`seal !==
            false`). The hash proves the stored answers have not changed — it
            does NOT claim they are true or sensor-attested;
            `answers_provenance` carries that distinction explicitly.
      required:
        - id
        - status
        - capture_url
        - created_at
        - expires_at
        - captures_count
      description: >-
        A verification as your API key sees it. `verdict` appears once analysis
        finished; `object_match`, `location_match` and `condition` appear when
        you asked for them and the check ran. Your `metadata` is not echoed
        back: keep the `id`.
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            fields:
              type: array
              items:
                type: object
                properties:
                  path:
                    type: string
                  message:
                    type: string
                required:
                  - path
                  - message
          required:
            - code
            - message
      required:
        - error
      description: >-
        Uniform error envelope. `code` is the stable string SDKs branch on
        (`invalid_request`, `unauthorized`, `not_found`, `expired`, `step_full`,
        `unknown_step`, `steps_incomplete`, `already_finalized`,
        `too_many_requests`, `plan_limit_reached`, `insufficient_credits`,
        `monthly_verification_limit_reached`, `storage_unavailable`,
        `internal_error`, `report_not_ready`, `report_inconclusive`). `fields`
        is only present on `invalid_request` validation failures.
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: rk_secret_<key>
      description: >-
        Secret API key, created in the dashboard under Settings → API. Send it
        as `Authorization: Bearer rk_secret_…` from your server only.
        Publishable keys (`pk_live_…`) are for the native SDKs and reach the
        capture endpoints alone. An unknown key returns 401.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.