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

# Create a verification

> Create a verification on one of your workflows.

What creating one takes depends on the workflow's mode. A hosted workflow takes the user's `mobile`, which they sign in to the journey with, and may take a `return_url`. A staged workflow opens no journey, so it takes neither, and a call that names either is refused. An instant workflow is not created here at all: it is run in the one call that also creates its record, so naming one here is refused with `409`.

Creating is idempotent per subject and workflow: repeating the call returns the existing verification, whatever its status, so retries are always safe. On a hosted workflow the subject is the user the mobile number names; on a staged workflow it is the `reference_user_id`. To run the same subject through again, reset the existing verification.

The status code tells the two apart. `201` means this call created the verification. `200` means this subject already had one in this workflow and you are reading that record back, so nothing was created and nothing was changed: check its `status` before acting on it, because a record already submitted or completed is not waiting for anyone. A verification you meant to be new that answers `200` is a sign the same subject reached you twice.

`context` is checked against the steps of the workflow's latest version that read it. A field one of them needs and you left out is refused, and so is one supplied in a shape that step cannot read - both with `400`, naming the field. Fields no step reads are yours to use as you like and are echoed back untouched. Only a call that creates a verification is checked: one that resolves to a record you already have answers `200` with that record, on the version it runs.

`reference_user_id` is yours and must be unique within the workflow. On a hosted workflow a retry of the same call resolves to the record already holding it, and a reference that belongs to a different user in that workflow is refused with `409`. The same subject in a second workflow keeps the same reference, so the reference and the workflow key together always name one record for you to reconcile against.

A workflow with no prepaid credits left refuses a create with `402`. Only a call that would create a verification is refused: one that resolves to a record you already have answers `200` as it always does, so a retry never turns into a payment error. Read the workflow for its balance, and see `credits` there for how far past it a workflow may be committed before it stops.



## OpenAPI

````yaml /verification/api-reference/openapi.json post /verifications
openapi: 3.1.0
info:
  title: Verify with Privue
  description: >-
    Start identity-and-business verifications and read the results.


    There are three ways to run one, and a verification reads the same whichever
    it was. Every workflow declares which it is for as its `mode`, and a
    workflow is one of them and never more.


    **Hosted.** You create a verification with the user's mobile number and
    receive a journey URL to hand to them. They work through the steps your
    workflow configures, on our screens, and submit. Use this when the person
    being verified is reachable and holds their own documents.


    **Staged.** You create a verification, upload each document you hold against
    the step it answers, and ask for the checks to run. They take longer than a
    request should be held open, so you read the result from a callback or by
    polling. Use this when documents reach you over time, or when you want them
    kept on the record to download later.


    **Instant.** You send the whole submission in one request. The checks run
    before it answers, so the reply is the finished record. The documents are
    read as they arrive and stored nowhere. Use this when you hold everything
    already and want the answer in the call you made.


    Whichever it was, you read the whole record: every step, its state, what it
    collected, and why anything did not pass. An instant verification hands you
    that record in its reply; for the other two, poll the verification or
    register a callback endpoint and be told when it is submitted.


    Across your whole account you can list the workflows configured for you,
    count your verifications by status, and page through the records behind a
    count.


    Every error response has the shape `{"code": "...", "detail": "..."}`.
    Branch on `code`: several causes share a status, and `detail` is written for
    a person reading a log rather than for code. Treat a code you do not
    recognise as the status it arrived at.
  version: 0.1.0
servers:
  - url: https://api.verify.privue.ai
    description: Production
security: []
tags:
  - name: Workflows
    description: >-
      The workflows configured for your account. Read one to see its mode, the
      documents it asks for, and how each step is answered over the API: the
      slots its documents go in and the values it takes.
  - name: Verifications
    description: >-
      Starting a verification, ending one, clearing one to run the same subject
      again, and purging one. Shared by both modes. A start answers 201 when it
      created the verification and 200 when the subject already had one, so a
      duplicate is visible from the status code alone.
  - name: Hosted workflows
    description: >-
      For a workflow the person being verified walks themselves. Start a
      verification with their mobile number, hand them the journey URL on the
      record, or open it for them from inside your own app with a handoff.
  - name: Staged workflows
    description: >-
      For a workflow you build up from documents you already hold. Upload each
      file against the step and slot it answers, withdraw one you got wrong,
      then ask for the checks to run and read the result when they have. Nobody
      is sent anywhere.
  - name: Instant workflows
    description: >-
      For a workflow answered in the request that asks it. Send the whole
      submission at once and read the finished record in the reply. Nothing is
      kept of the documents and nothing is left open to come back to.
  - name: Results
    description: >-
      Reading what a verification came to: one record, a page of them, counts
      across your account, and links to the files it holds.
paths:
  /verifications:
    post:
      tags:
        - Verifications
      summary: Create a verification
      description: >-
        Create a verification on one of your workflows.


        What creating one takes depends on the workflow's mode. A hosted
        workflow takes the user's `mobile`, which they sign in to the journey
        with, and may take a `return_url`. A staged workflow opens no journey,
        so it takes neither, and a call that names either is refused. An instant
        workflow is not created here at all: it is run in the one call that also
        creates its record, so naming one here is refused with `409`.


        Creating is idempotent per subject and workflow: repeating the call
        returns the existing verification, whatever its status, so retries are
        always safe. On a hosted workflow the subject is the user the mobile
        number names; on a staged workflow it is the `reference_user_id`. To run
        the same subject through again, reset the existing verification.


        The status code tells the two apart. `201` means this call created the
        verification. `200` means this subject already had one in this workflow
        and you are reading that record back, so nothing was created and nothing
        was changed: check its `status` before acting on it, because a record
        already submitted or completed is not waiting for anyone. A verification
        you meant to be new that answers `200` is a sign the same subject
        reached you twice.


        `context` is checked against the steps of the workflow's latest version
        that read it. A field one of them needs and you left out is refused, and
        so is one supplied in a shape that step cannot read - both with `400`,
        naming the field. Fields no step reads are yours to use as you like and
        are echoed back untouched. Only a call that creates a verification is
        checked: one that resolves to a record you already have answers `200`
        with that record, on the version it runs.


        `reference_user_id` is yours and must be unique within the workflow. On
        a hosted workflow a retry of the same call resolves to the record
        already holding it, and a reference that belongs to a different user in
        that workflow is refused with `409`. The same subject in a second
        workflow keeps the same reference, so the reference and the workflow key
        together always name one record for you to reconcile against.


        A workflow with no prepaid credits left refuses a create with `402`.
        Only a call that would create a verification is refused: one that
        resolves to a record you already have answers `200` as it always does,
        so a retry never turns into a payment error. Read the workflow for its
        balance, and see `credits` there for how far past it a workflow may be
        committed before it stops.
      operationId: create_verification_record_verifications_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVerificationRequest'
      responses:
        '200':
          description: >-
            This subject already has a verification in this workflow, so nothing
            was created. The record is the one you already have, unchanged and
            whatever state it has reached.
          content:
            application/json:
              example:
                id: 3f2504e0-4f89-41d3-9a0c-0305e82c3301
                mode: hosted
                status: completed
                workflow_key: merchant-onboarding
                version: 2
                mobile: '+919876543210'
                reference_user_id: merchant-42
                context:
                  channel: field-sales
                  state: MH
                return_url: https://yourapp.com/kyc/done
                journey_url: https://verify.privue.ai/acme/merchant-onboarding
                created_at: '2026-08-10T14:02:11'
                last_activity_at: '2026-08-10T14:41:06'
                expires_after_days: 30
                run_requested_at: null
                submitted_at: '2026-08-10T14:41:06'
                completed_at: '2026-08-10T14:41:09'
                cancelled_at: null
                gated_at: null
                gated_by_step: null
                failed_at: null
                expired_at: null
                expired_by: null
                acknowledgement: null
                callback:
                  status: delivered
                  settled_at: '2026-08-10T14:41:09'
                  reason: null
                credits_consumed: 1
                resets: 0
                progress:
                  total: 12
                  passed: 10
                  failed: 0
                  awaiting: 0
                  enriching: 0
                  error: 0
                  declined: 1
                  not_supplied: 0
                  undetermined: 0
                  not_applicable: 1
                steps:
                  - key: contact
                    title: Before we start
                    label: contact_email
                    type: form
                    required: true
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer:
                        email: owner@acmetraders.in
                      outputs:
                        email: owner@acmetraders.in
                    documents: []
                  - key: gst
                    title: GST certificate
                    label: tax_registration
                    type: gst-certificate
                    required: true
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer: {}
                      outputs:
                        gstin: 27AABCA1234F1Z5
                        legal_name: ACME TRADERS PRIVATE LIMITED
                        trade_name: Acme Traders
                        registration_status: Active
                        registration_date: '2020-01-13'
                        business_constitution: Private Limited Company
                        taxpayer_type: Regular
                        e_invoice_mandated: true
                        aggregate_turnover: 'Slab: Rs. 5 Cr. to 25 Cr.'
                        authorized_signatories:
                          - Rahul Mehta
                          - Priya Mehta
                        nature_of_business_activities:
                          - Wholesale Business
                          - Warehouse / Depot
                        business_details:
                          goods_details:
                            - goods_description: Filtering machinery
                              hsn_code: '84212190'
                          service_details: []
                        filings:
                          - return_type: GSTR1
                            financial_year: 2026-2027
                            tax_period: May
                            status: Filed
                            filing_date: '2026-06-04'
                            mode_of_filing: ONLINE
                          - return_type: GSTR3B
                            financial_year: 2026-2027
                            tax_period: May
                            status: Filed
                            filing_date: '2026-06-23'
                            mode_of_filing: ONLINE
                          - return_type: GSTR9
                            financial_year: 2024-2025
                            tax_period: Annual
                            status: Filed
                            filing_date: '2025-12-18'
                            mode_of_filing: ONLINE
                        business_pan: AABCA1234F
                        sole_proprietor_pan: null
                        addresses:
                          - address: 12 Industrial Estate, Pune, Maharashtra 411026
                            tag: Principal Business Address
                        primary_business_address:
                          street: 12 Industrial Estate
                          city: Pune
                          state: Maharashtra
                          country: India
                          postal_code: '411026'
                        other_business_address: null
                        names:
                          - name: ACME TRADERS PRIVATE LIMITED
                            tag: Legal Name
                          - name: Acme Traders
                            tag: Trade Name
                        promoters:
                          - Rahul Mehta
                          - Priya Mehta
                        business_email: accounts@acmetraders.in
                        business_mobile: '9820011223'
                    documents:
                      - id: bb9909b4-44e4-414a-af82-bad690d434ed
                        slot: gst-certificate
                        kind: gst-certificate
                        label: gst_certificate
                        filename: gst-certificate.pdf
                        content_type: application/pdf
                        size_bytes: 182044
                        sha256: >-
                          63f90f32e899197edb4f038322e354f3c6b907602a44a58a0ae52b40a2cd9811
                        received_at: '2026-08-10T14:21:58'
                  - key: pan
                    title: PAN card
                    label: entity_pan
                    type: pan-card
                    required: true
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer: {}
                      outputs:
                        pan: AABCA1234F
                        name: ACME TRADERS PRIVATE LIMITED
                        date_of_birth_or_incorporation: '2011-06-14'
                        card_document_id: 4fd79a54-a8a7-4e07-b902-a2e75af3e467
                        status: valid
                        aadhaar_seeded: null
                        names:
                          - name: ACME TRADERS PRIVATE LIMITED
                            tag: PAN Holder
                    documents:
                      - id: 4fd79a54-a8a7-4e07-b902-a2e75af3e467
                        slot: pan-card
                        kind: pan-card
                        label: entity_pan
                        filename: pan-card.jpg
                        content_type: image/jpeg
                        size_bytes: 92412
                        sha256: >-
                          42b7e28cf9a26dcef6e275de42f7516ad36ee86c6aa45888821a81217e62a670
                        received_at: '2026-08-10T14:09:12'
                  - key: identity
                    title: Identity
                    label: null
                    type: digilocker
                    required: false
                    state: passed
                    reasons: []
                    gaps:
                      - code: digilocker-document-missing
                        message: Your pan document was not shared from DigiLocker.
                        details:
                          doc_type: pan
                    collected:
                      answer:
                        session_id: e0d4a1f6-7c93-4b28-9f51-3a8c62d0be47
                      outputs:
                        name: Rahul Mehta
                        names:
                          - name: Rahul Mehta
                            tag: DigiLocker Holder
                        email: rahul.mehta@example.com
                        mobile: '9876543210'
                        date_of_birth: 14/03/1986
                        gender: Male
                        pan: null
                        masked_aadhaar: XXXXXXXX4172
                        photo_document_id: c48b2e57-9a10-4d3f-b6e8-1f7c9a05d24b
                    documents:
                      - id: 7e5c1a90-2f83-4a12-9c47-6d0b58e2af31
                        slot: digilocker-docs
                        kind: aadhaar
                        label: null
                        filename: aadhaar.pdf
                        content_type: application/pdf
                        size_bytes: 148820
                        sha256: >-
                          e17c4b8025d9a63f04e7b158c92da370465f8b1e07c3d924a6b508f1c73e2d05
                        received_at: '2026-08-10T14:14:37'
                      - id: c48b2e57-9a10-4d3f-b6e8-1f7c9a05d24b
                        slot: digilocker-docs
                        kind: photo
                        label: null
                        filename: photo.jpg
                        content_type: image/jpeg
                        size_bytes: 18734
                        sha256: >-
                          b8043f7e1c592a6d0e34b871f5c9d206a47e3b9018c5d62faf7b04e39c1a5867
                        received_at: '2026-08-10T14:14:38'
                  - key: selfie
                    title: Selfie
                    label: null
                    type: selfie
                    required: false
                    state: declined
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: bank
                    title: Bank account
                    label: payout_account
                    type: bank-account
                    required: true
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer:
                        source: typed
                        account_number: '50100234567890'
                        ifsc: HDFC0001234
                      outputs:
                        source: typed
                        account_number: '50100234567890'
                        ifsc: HDFC0001234
                        registered_name: ACME TRADERS PRIVATE LIMITED
                        names:
                          - name: ACME TRADERS PRIVATE LIMITED
                            tag: Bank Account Holder
                        bank_name: null
                        branch: null
                    documents: []
                  - key: trade-licence
                    title: Trade licence
                    label: null
                    type: documents
                    required: false
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer: {}
                      outputs: {}
                    documents:
                      - id: 2a6f8d13-4c95-4e7b-8f30-5b1e6c9a7d02
                        slot: licence
                        kind: licence
                        label: trade_licence
                        filename: shop-establishment-licence.pdf
                        content_type: application/pdf
                        size_bytes: 221893
                        sha256: >-
                          0a9c7f1b5e2d48a6c3f07b91d4e85a2c6f13b8074de92a5c1f6b3e08d7a24c95
                        received_at: '2026-08-10T14:27:03'
                      - id: 8b31c4e6-7d92-4a58-b0f1-3e6d2c94a17f
                        slot: lease
                        kind: lease
                        label: lease_agreement
                        filename: lease-agreement.pdf
                        content_type: application/pdf
                        size_bytes: 654201
                        sha256: >-
                          7d4e1c08b3a95f26d07e4b1a8c53f902e6b7d148a05c39f2b8e6104d7c3a95e2
                        received_at: '2026-08-10T14:28:44'
                  - key: premises
                    title: Premises photos
                    label: null
                    type: premises-photos
                    required: false
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer:
                        locations:
                          5c9e07b2-8f41-4d6a-9e35-2b7a1c8f60d4:
                            latitude: 18.629812
                            longitude: 73.813104
                            address: >-
                              12, Industrial Estate Rd, Bhosari, Pune,
                              Maharashtra 411026, India
                            place_id: ChIJhTQr8kW_wjsR1nQm2eF0hQY
                          e6142f8a-3b57-4c90-8d21-9a4f7e0b53c6:
                            latitude: 18.629774
                            longitude: 73.813251
                            address: >-
                              12, Industrial Estate Rd, Bhosari, Pune,
                              Maharashtra 411026, India
                            place_id: ChIJhTQr8kW_wjsR1nQm2eF0hQY
                      outputs:
                        addresses:
                          - >-
                            12, Industrial Estate Rd, Bhosari, Pune, Maharashtra
                            411026, India
                    documents:
                      - id: 5c9e07b2-8f41-4d6a-9e35-2b7a1c8f60d4
                        slot: storefront
                        kind: storefront
                        label: storefront_photo
                        filename: storefront.jpg
                        content_type: image/jpeg
                        size_bytes: 1442310
                        sha256: >-
                          c1f5b70e934a26d8071c4be95f3a20d7e846b1c95023f7ad6b48e01c9f735a26
                        received_at: '2026-08-10T14:33:19'
                      - id: e6142f8a-3b57-4c90-8d21-9a4f7e0b53c6
                        slot: interior
                        kind: interior
                        label: interior_photo
                        filename: interior.jpg
                        content_type: image/jpeg
                        size_bytes: 1180955
                        sha256: >-
                          9b0d3e64a17c58f2e40b96d7c85a13f0246e9b7d1c503a8f6b2e74d09c1a5837
                        received_at: '2026-08-10T14:34:02'
                  - key: premises-proof
                    title: Proof of premises
                    label: null
                    type: address-proof
                    required: false
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer: {}
                      outputs:
                        verified_tags:
                          - Principal Business Address
                        unverified_tags: []
                        readings:
                          - slot: utility-bill
                            kind: electricity
                            label: electricity_bill
                            premises_address: >-
                              12, Industrial Estate Rd, Bhosari, Pune,
                              Maharashtra 411026, India
                            verified_tags:
                              - Principal Business Address
                    documents:
                      - id: 0c73de91-6a24-4b8f-95d0-7e41b25c8a63
                        slot: utility-bill
                        kind: electricity
                        label: electricity_bill
                        filename: electricity-bill.pdf
                        content_type: application/pdf
                        size_bytes: 96410
                        sha256: >-
                          3e8b1d95c072a46f8b5309e7d41c6a28b90f7e35c1d84620a7f3b9e05d268c14
                        received_at: '2026-08-10T14:36:50'
                  - key: addresses
                    title: Tag the addresses
                    label: null
                    type: address-tagging
                    required: false
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer:
                        addresses: []
                      outputs:
                        addresses:
                          - address: >-
                              12, Industrial Estate Rd, Bhosari, Pune,
                              Maharashtra 411026, India
                            tag: Principal Business Address
                        recognised:
                          - >-
                            12, Industrial Estate Rd, Bhosari, Pune, Maharashtra
                            411026, India
                    documents: []
                  - key: review
                    title: Review
                    label: applicant_signoff
                    type: review
                    required: true
                    state: passed
                    reasons: []
                    gaps: []
                    collected:
                      answer:
                        declarations:
                          - key: terms-of-service
                            label: tos_consent
                            title: Terms of service
                            content: >-
                              I accept the [terms of
                              service](https://yourapp.com/terms) and the
                              [privacy policy](https://yourapp.com/privacy).
                            accepted: true
                          - key: information-true
                            label: truth_declaration
                            title: null
                            content: >-
                              Everything I have provided is true and correct to
                              the best of my knowledge.
                            accepted: true
                          - key: contact-on-whatsapp
                            label: whatsapp_optin
                            title: null
                            content: >-
                              You may contact me about this application on
                              WhatsApp.
                            accepted: false
                      outputs: {}
                    documents: []
              schema:
                $ref: '#/components/schemas/VerificationRecord'
        '201':
          description: >-
            The verification you have just created, including the journey URL on
            a hosted workflow.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationRecord'
              example:
                id: 3f2504e0-4f89-41d3-9a0c-0305e82c3301
                mode: hosted
                status: open
                workflow_key: merchant-onboarding
                version: 2
                mobile: '+919876543210'
                reference_user_id: merchant-42
                context:
                  channel: field-sales
                  state: MH
                return_url: https://yourapp.com/kyc/done
                journey_url: https://verify.privue.ai/acme/merchant-onboarding
                created_at: '2026-08-10T14:02:11'
                last_activity_at: '2026-08-10T14:02:11'
                expires_after_days: 30
                run_requested_at: null
                submitted_at: null
                completed_at: null
                cancelled_at: null
                gated_at: null
                gated_by_step: null
                failed_at: null
                expired_at: null
                expired_by: null
                acknowledgement: null
                callback: null
                credits_consumed: 0
                resets: 0
                progress:
                  total: 12
                  passed: 0
                  failed: 0
                  awaiting: 8
                  enriching: 0
                  error: 0
                  declined: 0
                  not_supplied: 0
                  undetermined: 4
                  not_applicable: 0
                steps:
                  - key: contact
                    title: Before we start
                    label: contact_email
                    type: form
                    required: true
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: gst
                    title: GST certificate
                    label: tax_registration
                    type: gst-certificate
                    required: true
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: pan
                    title: PAN card
                    label: entity_pan
                    type: pan-card
                    required: true
                    state: undetermined
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: identity
                    title: Identity
                    label: null
                    type: digilocker
                    required: false
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: selfie
                    title: Selfie
                    label: null
                    type: selfie
                    required: false
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: bank
                    title: Bank account
                    label: payout_account
                    type: bank-account
                    required: true
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: trade-licence
                    title: Trade licence
                    label: null
                    type: documents
                    required: false
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: premises
                    title: Premises photos
                    label: null
                    type: premises-photos
                    required: false
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: premises-proof
                    title: Proof of premises
                    label: null
                    type: address-proof
                    required: false
                    state: undetermined
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: alt-business-proof
                    title: Alternative proof of business
                    label: null
                    type: documents
                    required: true
                    state: undetermined
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: addresses
                    title: Tag the addresses
                    label: null
                    type: address-tagging
                    required: false
                    state: undetermined
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
                  - key: review
                    title: Review
                    label: applicant_signoff
                    type: review
                    required: true
                    state: awaiting
                    reasons: []
                    gaps: []
                    collected: null
                    documents: []
        '400':
          description: >-
            The workflow key is unknown; the context omits a field the
            workflow's required steps cannot run without, or supplies one in a
            shape the step that reads it cannot use; a hosted workflow was
            created without a mobile number, or with a return URL that is not on
            the workflow's allowlist; or a workflow you supply yourself was
            created with a mobile number or a return URL, which it takes neither
            of.


            The code is one of `mobile-required`, `workflow-not-found`,
            `context-incomplete`, `context-value-invalid`,
            `return-url-not-allowed` or `journey-fields-refused`.
          content:
            application/json:
              example:
                code: mobile-required
                detail: >-
                  workflow 'merchant-onboarding' is hosted, so creating one
                  names the mobile number its user signs in with
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: |-
            The API key is missing, malformed, or revoked.

            The code is `unauthenticated`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: unauthenticated
                detail: Missing or malformed Authorization header
        '402':
          description: >-
            The workflow has no prepaid credits left. Either none were ever
            granted for it, or its verifications have used them, their term has
            passed, or we have taken them back. Nothing on the workflow can be
            created or moved on until it is topped up; everything on it stays
            readable. Read the workflow to see where its balance stands.


            The code is `credits-exhausted`.
          content:
            application/json:
              example:
                code: credits-exhausted
                detail: >-
                  the credits for workflow 'merchant-onboarding' are gone; of
                  500 granted, 500 used
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            The workflow belongs to the other environment. An API key is for
            `uat` or for `production` and reaches only that environment's
            workflows. Or the key is valid but not enrolled for verifications,
            or not set up for exactly one of `uat` and `production`, in which
            case ask us to reissue it.


            The code is one of `environment-mismatch` or `client-not-enrolled`.
          content:
            application/json:
              example:
                code: environment-mismatch
                detail: >-
                  workflow 'merchant-onboarding' is production and this request
                  is for uat
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            The `reference_user_id` already belongs to a different user in this
            workflow. Or the workflow is instant, which is run in the call that
            creates its record rather than created here. Or: The workflow
            already has as many verifications going as it may: `runs.limit` on
            the workflow is how many, and one of them ending frees a place.


            The code is one of `reference-taken`, `workflow-not-runnable` or
            `live-limit-reached`.
          content:
            application/json:
              example:
                code: reference-taken
                detail: >-
                  reference_user_id 'merchant-42' already belongs to
                  verification 3f2504e0-4f89-41d3-9a0c-0305e82c3301
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            The request body is not valid. The detail names each field at fault
            and what was wrong with it.


            The code is `request-invalid`.
          content:
            application/json:
              example:
                code: request-invalid
                detail: 'mobile: String should match pattern ''^(?:\+91)?[6-9][0-9]{9}$'''
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: |-
            The API key is rate limited. Retry after a pause.

            The code is `rate-limited`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: rate-limited
                detail: 'Unauthorized: RATE_LIMITED'
        '500':
          description: >-
            The workflow's latest version declares a gate check it cannot ask:
            no checks endpoint is registered for the workflow, or the check's
            fallback redirects to a link the workflow's return URLs do not
            allow. Nothing was created. Or this subject already has a
            verification in this workflow, and the workflow's output
            transformations cannot convert a value it holds, so its record
            cannot be read. Contact us to have the workflow's configuration put
            right.


            The code is `workflow-misconfigured`.
          content:
            application/json:
              example:
                code: workflow-misconfigured
                detail: >-
                  workflow 'merchant-onboarding' cannot ask its gate check
                  'gst-onboarded': the workflow registers no endpoint to ask its
                  checks at
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: |-
            API keys could not be checked right now. Retry.

            The code is `auth-unavailable`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: auth-unavailable
                detail: Auth provider unavailable
      security:
        - HTTPBearer: []
components:
  schemas:
    CreateVerificationRequest:
      properties:
        workflow_key:
          type: string
          minLength: 1
          title: Workflow Key
          description: Which of your workflows the verification runs.
        mobile:
          anyOf:
            - type: string
              pattern: ^(?:\+91)?[6-9][0-9]{9}$
            - type: 'null'
          title: Mobile
          description: >-
            The user's Indian mobile number, on a hosted workflow. It is how
            they sign in to the journey, and a call without it is refused.


            A workflow you supply yourself opens no journey, so it takes no
            mobile number and a call that names one is refused.
        reference_user_id:
          type: string
          maxLength: 255
          minLength: 1
          title: Reference User Id
          description: >-
            Your own identifier for this user, unique within the workflow. It is
            echoed back on every response, and together with the workflow key it
            is the handle that survives once the verification has expired, so
            make it something you can reconcile against your own records.


            Creating one again with a reference that already belongs to a
            different user in the same workflow is refused. Running the same
            user through a second workflow is not: that is a verification of its
            own under the same identifier.
        context:
          additionalProperties: true
          type: object
          title: Context
          description: >-
            Facts you already know about the user, as a flat JSON object.
            Workflow conditions and step inputs can read these values to decide
            what the journey asks for.


            Context is fixed for the life of the verification: a reset preserves
            it, and nothing can add to it afterwards. Where a workflow has a
            required step that cannot run without one of these fields, creating
            one without it is refused, and the response names every field that
            was missing.
        return_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Return Url
          description: >-
            Where the user is sent after they submit the journey, on a hosted
            workflow. Must match one of the return URLs registered for the
            workflow being started, which each carry their own.


            A workflow you supply yourself sends nobody anywhere, so it takes no
            return URL and a call that names one is refused.
      additionalProperties: false
      type: object
      required:
        - workflow_key
        - reference_user_id
      title: CreateVerificationRequest
      description: What creating a verification takes.
      examples:
        - context:
            channel: field-sales
            state: MH
          mobile: '+919876543210'
          reference_user_id: merchant-42
          return_url: https://yourapp.com/kyc/done
          workflow_key: merchant-onboarding
    VerificationRecord:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: The verification's id.
        mode:
          $ref: '#/components/schemas/WorkflowMode'
          description: >-
            How verifications on this workflow are conducted. `hosted`: the
            person being verified walks the journey on our screens and submits
            it. `staged`: you create a verification, upload each document
            against the step it answers, and then ask for the checks to run.
            `instant`: you send the whole submission in one request, which runs
            the checks and answers with the finished record.


            A workflow is one of the three, and every endpoint belonging to
            another is refused on it.
        status:
          $ref: '#/components/schemas/VerificationStatus'
          description: >-
            open while the run is live and the user may act, which a step held
            up by a technical problem does not end; submitted once the user has
            finished, which they can only do with every step settled, so the
            result is final from that moment; completed once the checks that
            follow a submission have run, such as notifying you by callback, and
            the data is safe to read; failed if the run reached an unrecoverable
            state, in which case reset it or create a new one; cancelled if you
            ended the run; gated if a check this workflow puts to a system of
            yours stopped the journey there, which ends the run where it stood.
            A check stops it when your system answers `terminate` or `redirect`,
            or when your system gave no answer and the workflow falls back to
            `terminate`. Poll until the status is one of completed, cancelled,
            gated or failed.


            expired supersedes all of them once the retention window runs out:
            the run is of no further use and is kept for your audit alone. It
            says nothing about how the run had ended, so read completed_at,
            cancelled_at, gated_at or failed_at for that rather than expecting
            the status to hold it.
        workflow_key:
          type: string
          minLength: 1
          title: Workflow Key
          description: The workflow this verification runs.
        version:
          type: integer
          minimum: 1
          title: Version
          description: >-
            Which version of the workflow this verification runs. It is the
            workflow's latest version when the verification was created, and it
            holds for the verification's whole life: a change published to the
            workflow afterwards never changes what this verification asks for,
            which steps it reports or the names its outputs arrive under.
            Resetting the verification moves it onto the latest version at the
            time.
        mobile:
          anyOf:
            - type: string
            - type: 'null'
          title: Mobile
          description: >-
            The user's mobile number, as you provided it. Null on a verification
            you supplied yourself, and null once the verification has expired.
        reference_user_id:
          type: string
          title: Reference User Id
          description: Your identifier for this verification, echoed back.
        context:
          additionalProperties: true
          type: object
          title: Context
          description: >-
            The facts you supplied when you created it, unchanged. Empty once
            the verification has expired.
        return_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Return Url
          description: Where the user is sent after submitting, where one was given.
        journey_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Journey Url
          description: >-
            Where to send your user, on a hosted verification. The same address
            serves every user of this workflow and carries no credential, so it
            is safe to send over WhatsApp, SMS, or email, and the user proves
            who they are by signing in with the mobile number you created the
            verification with. To open the journey from inside your own app with
            the user already signed in, create a handoff instead.


            Null on a verification you supplied yourself, which opens no
            journey.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When the verification was created.
        run_requested_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Run Requested At
          description: >-
            When you asked for the checks to run, on a staged verification. From
            that moment the submission is frozen: uploads, withdrawals and a run
            request with different values are refused until you reset.


            On an instant verification it is when the request carrying the whole
            submission arrived. Null on a hosted one, and null on a staged one
            until you ask.
        submitted_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Submitted At
          description: >-
            When the verification was submitted, if it has been: by the user on
            a hosted workflow, by the run of the checks on one you supplied
            yourself.
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Completed At
          description: When the verification completed, if it has.
        cancelled_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Cancelled At
          description: When the verification was cancelled, if it was.
        gated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Gated At
          description: When a check of yours stopped the journey, if one did.
        gated_by_step:
          anyOf:
            - type: string
            - type: 'null'
          title: Gated By Step
          description: >-
            The step whose check stopped the journey, if one did. A workflow may
            put more than one check to you, and this says which of them the run
            stopped at.


            It is set and cleared with `gated_at`: it stays set once the
            verification expires or you purge it, so the record still says how
            the run had ended, and a reset clears both.
        failed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Failed At
          description: When the verification was marked failed, if it was.
        expired_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Expired At
          description: >-
            When the verification expired, if it has. From that moment it is
            kept for your audit and nothing else: it holds what each step
            concluded and nothing the user gave, so no answers, no values read
            off their documents, and no files. The step states you read are the
            ones frozen at that moment. Read the other timestamps to see how it
            had ended before it expired.
        expired_by:
          anyOf:
            - $ref: '#/components/schemas/ExpiryCause'
            - type: 'null'
          description: >-
            What expired the verification. `retention` when its workflow's
            retention window ran out; `client` when you purged it. Null until it
            expires.
        last_activity_at:
          type: string
          format: date-time
          title: Last Activity At
          description: >-
            When the verification was last acted on: by the user on a hosted
            workflow, by you or by the run of the checks on one you supplied
            yourself. A verification that is created and never touched reads the
            moment it was created. `expires_after_days` is counted from here, so
            the two together say when a record left untouched expires.
        expires_after_days:
          type: integer
          minimum: 1
          title: Expires After Days
          description: >-
            How many days this verification may go without activity before it
            expires and everything the user provided is deleted, as the version
            it runs states. It is this verification's own window: a later
            version of its workflow can state a different one, which reaches the
            verifications created or reset after it, so read the window here
            rather than off the workflow. On an expired verification it is the
            window it was held to.
        acknowledgement:
          anyOf:
            - $ref: '#/components/schemas/AcknowledgementRecord'
            - type: 'null'
          description: >-
            The receipt the user was sent telling them their submission arrived,
            on a workflow that acknowledges submissions by email. Null wherever
            nothing has been sent: a workflow that acknowledges nothing, a
            verification carrying no address to send to, a submission still
            being finalised, and a send that could not be made.


            It names the submission it answers. A reset undoes a submission
            without unsending its receipt, so read `submitted_at` here against
            the record's own to tell a receipt for the submission this record
            stands in from one for a submission it no longer does.
        callback:
          anyOf:
            - $ref: '#/components/schemas/CallbackRecord'
            - type: 'null'
          description: >-
            How the callback for this verification's run ended:
            `verification.submitted` once it was submitted, or
            `verification.gated` once a check of yours stopped it. Null until
            the callback settles, and on every verification of a workflow with
            no callback endpoint registered. A verification completes, or stays
            gated, whether or not its callback was delivered, so read this to
            tell a result you were told about from one you were not.
        credits_consumed:
          type: integer
          title: Credits Consumed
          description: >-
            How many credits this verification has used. A run uses one credit
            when it first reaches completed, cancelled or expired, whatever the
            workflow asks for and however many of its checks ran. A run that
            ends as failed or gated uses none, and one still open or submitted
            has used nothing yet.


            Resetting a verification runs the subject through again, which is a
            run of its own and uses a credit of its own, so a record reset twice
            and completed each time reads `3`.
        resets:
          type: integer
          title: Resets
          description: >-
            How many times this verification has been reset. A reset clears
            everything the record collected and runs the subject through the
            checks again, so a verification reading `2` is on its third run and
            holds what that one has collected.


            Each of these opened a run charged a credit of its own where it
            ended, which is what `credits_consumed` counts. A reset that cleared
            a run no credit had paid for also drew one of the workflow's resets:
            see `resets` on the workflow.
        progress:
          $ref: '#/components/schemas/ProgressRecord'
          description: >-
            Every step of the journey counted by where it stands, the ones left
            out included.
        steps:
          items:
            $ref: '#/components/schemas/StepRecord'
          type: array
          title: Steps
          description: >-
            The steps this journey has not ruled out, in journey order. A
            workflow presents the steps that apply to whoever is being verified,
            so a journey that took one branch reports that branch and not the
            others; `progress.not_applicable` says how many are missing from
            here, and reading the verification with `include_not_applicable`
            shows them.


            A step is only missing once something has ruled it out. One whose
            place in the journey turns on a value an earlier step has yet to
            publish is here, reading `undetermined`, so a verification you have
            just created reports every step its workflow declares and they
            resolve into the other states as it goes on.
      type: object
      required:
        - id
        - mode
        - status
        - workflow_key
        - version
        - mobile
        - reference_user_id
        - context
        - return_url
        - journey_url
        - created_at
        - run_requested_at
        - submitted_at
        - completed_at
        - cancelled_at
        - gated_at
        - gated_by_step
        - failed_at
        - expired_at
        - expired_by
        - last_activity_at
        - expires_after_days
        - acknowledgement
        - callback
        - credits_consumed
        - resets
        - progress
        - steps
      title: VerificationRecord
      description: The whole record of one verification; safe to poll.
    ErrorResponse:
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: >-
            What went wrong. Branch on this rather than on the status code,
            which several causes share, and never on `detail`.


            Treat a code you do not recognise as the status it arrived at: codes
            are added as new causes become reachable, and an existing one never
            changes meaning.
        detail:
          type: string
          title: Detail
          description: >-
            What went wrong, in words, naming the workflow, verification, step
            or field at fault where one is. Written for a person reading a log
            rather than for code to read, so it is not stable and nothing should
            be matched against it.
      type: object
      required:
        - code
        - detail
      title: ErrorResponse
      description: The envelope every failure is answered in.
    WorkflowMode:
      type: string
      enum:
        - hosted
        - staged
        - instant
      title: WorkflowMode
      description: >-
        How a verification on this workflow is conducted, which every other rule
        about it follows from.
    VerificationStatus:
      type: string
      enum:
        - open
        - submitted
        - completed
        - cancelled
        - gated
        - expired
        - failed
      title: VerificationStatus
      description: Where a verification stands.
    ExpiryCause:
      type: string
      enum:
        - retention
        - client
      title: ExpiryCause
      description: What deleted a verification's data and closed the record for audit.
    AcknowledgementRecord:
      properties:
        submitted_at:
          type: string
          format: date-time
          title: Submitted At
          description: The submission this receipt answers.
        sent_at:
          type: string
          format: date-time
          title: Sent At
          description: When it was sent.
        message_id:
          type: string
          title: Message Id
          description: The identifier of the message that was sent, for tracing one send.
      type: object
      required:
        - submitted_at
        - sent_at
        - message_id
      title: AcknowledgementRecord
      description: The receipt telling the user their submission arrived.
    CallbackRecord:
      properties:
        status:
          $ref: '#/components/schemas/CallbackStatus'
          description: >-
            delivered once your endpoint accepted the callback; failed once
            every attempt at it was spent without one being accepted.
        settled_at:
          type: string
          format: date-time
          title: Settled At
          description: When the callback was accepted, or when the attempts ran out.
        reason:
          anyOf:
            - type: string
            - type: 'null'
          title: Reason
          description: >-
            Why no attempt was accepted, on a failed callback. Null on a
            delivered one.
      type: object
      required:
        - status
        - settled_at
        - reason
      title: CallbackRecord
      description: How the callback for this verification ended.
    ProgressRecord:
      properties:
        total:
          type: integer
          title: Total
          description: >-
            How many steps the workflow declares. Counted whichever steps the
            record reports, so on a journey that took one branch this is more
            than `steps` holds.
        passed:
          type: integer
          title: Passed
          description: Steps that were checked and passed.
        failed:
          type: integer
          title: Failed
          description: Steps that were checked and did not pass.
        awaiting:
          type: integer
          title: Awaiting
          description: Steps the user has not answered yet.
        enriching:
          type: integer
          title: Enriching
          description: Steps whose checks are still running.
        error:
          type: integer
          title: Error
          description: Steps where a check could not run.
        declined:
          type: integer
          title: Declined
          description: Steps the user chose not to provide.
        not_supplied:
          type: integer
          title: Not Supplied
          description: Steps the run closed over with nothing provided for them.
        undetermined:
          type: integer
          title: Undetermined
          description: >-
            Steps whose place in this journey is not settled yet, because
            whether they are asked for turns on something that has still to
            happen. These are reported in `steps`.
        not_applicable:
          type: integer
          title: Not Applicable
          description: >-
            Steps this journey ruled out, which the record leaves out of
            `steps`. Read the verification with `include_not_applicable` to see
            them.
      type: object
      required:
        - total
        - passed
        - failed
        - awaiting
        - enriching
        - error
        - declined
        - not_supplied
        - undetermined
        - not_applicable
      title: ProgressRecord
      description: >-
        Every step of the journey counted by where it stands; total equals the
        sum of the other fields.


        Counted over the whole journey, while `steps` reports only the part of
        it nothing has ruled out, so this is where a record says how much of the
        journey it is leaving out.
    StepRecord:
      properties:
        key:
          type: string
          title: Key
          description: The step's key within the workflow.
        title:
          anyOf:
            - type: string
            - type: 'null'
          title: Title
          description: >-
            The heading this step is presented under, in your workflow's own
            words. Null only where the workflow no longer declares the step,
            which a record read after its workflow changed can hold.
        label:
          anyOf:
            - type: string
            - type: 'null'
          title: Label
          description: >-
            Your own name for this step, where your workflow carries one.
            Several steps may share one, so a journey that asks a sole
            proprietor, a partner and a director each for a PAN reads the same
            name on whichever of them ran. Null where the workflow carries none;
            the `key` is what names this step everywhere.
        type:
          $ref: '#/components/schemas/StepType'
          description: The step's type.
        required:
          type: boolean
          title: Required
          description: Whether the journey cannot be submitted without this step.
        state:
          $ref: '#/components/schemas/StepState'
          description: >-
            Where the step stands. declined means the user chose not to provide
            it; not-supplied means the run closed with nothing provided for it,
            so it was closed over rather than left waiting; enriching means the
            step's checks are still running; error means a check could not run
            and will be retried; passed and failed are the outcomes of those
            checks; awaiting means the user has not answered it yet.


            undetermined means whether this journey asks for the step at all
            turns on something that has yet to happen, such as a value an
            earlier step will publish. It is not a step being waited on and not
            one ruled out: read it as a question the journey has not reached. It
            settles into one of the other states as the journey does, except
            where a verification ends with a check that never ran: the steps
            that turned on that check stay undetermined on the finished record.


            not-applicable means this journey did not ask for the step, because
            your workflow's rules ruled it out or because a value it reads was
            settled without being established. That is a conclusion rather than
            an open question, and the record leaves those steps out, so you only
            meet this state on one you read with `include_not_applicable`.
        reasons:
          items:
            $ref: '#/components/schemas/StepReason'
          type: array
          title: Reasons
          description: Why the step has not passed, when it has not.
        gaps:
          items:
            $ref: '#/components/schemas/StepReason'
          type: array
          title: Gaps
          description: >-
            What a passed step passed without: optional pieces it asked for that
            did not arrive. Empty unless the step passed.
        collected:
          anyOf:
            - $ref: '#/components/schemas/CollectedRecord'
            - type: 'null'
          description: What the step collected, once it was answered.
        documents:
          items:
            $ref: '#/components/schemas/DocumentRecord'
          type: array
          title: Documents
          description: The files this step holds, oldest first.
      type: object
      required:
        - key
        - title
        - label
        - type
        - required
        - state
        - reasons
        - gaps
        - collected
        - documents
      title: StepRecord
      description: One step of the workflow that this user was asked for.
    ErrorCode:
      type: string
      enum:
        - unauthenticated
        - client-not-enrolled
        - rate-limited
        - auth-unavailable
        - environment-mismatch
        - request-invalid
        - body-unreadable
        - page-cursor-invalid
        - window-invalid
        - request-too-large
        - not-found
        - method-not-allowed
        - internal-error
        - workflow-not-found
        - workflow-version-not-found
        - workflow-not-runnable
        - workflow-not-walkable
        - workflow-misconfigured
        - context-incomplete
        - context-value-invalid
        - mobile-required
        - journey-fields-refused
        - return-url-not-allowed
        - reference-taken
        - verification-not-found
        - verification-not-open
        - verification-expired
        - run-in-progress
        - credits-exhausted
        - resets-exhausted
        - live-limit-reached
        - step-not-found
        - step-not-ready
        - step-invalid
        - document-not-found
        - document-not-stored
        - document-too-large
        - document-type-not-allowed
      title: ErrorCode
      description: >-
        What went wrong, as a value to branch on.


        Published vocabulary, stated here rather than shared with any other
        product of ours: these are read by integrations we do not control, so a
        name here means what it says for as long as the endpoint answering it
        exists.


        One code names one cause, so a status carrying several causes is told
        apart by the code and never by the message. Codes are added as new
        causes become reachable; an integration therefore treats an unrecognised
        code as the status it arrived at.
    CallbackStatus:
      type: string
      enum:
        - delivered
        - failed
      title: CallbackStatus
      description: >-
        How the hand-off to the client ended. Absent while none has been
        attempted, or none is owed.
    StepType:
      type: string
      enum:
        - form
        - documents
        - parsed-documents
        - pan-card
        - bank-account
        - gst-certificate
        - digilocker
        - selfie
        - premises-photos
        - address-tagging
        - address-proof
        - udyam
        - pcb-certificate
        - name-match
        - gate-check
        - review
      title: StepType
      description: The sixteen step types. This list is closed.
    StepState:
      type: string
      enum:
        - not-applicable
        - undetermined
        - awaiting
        - enriching
        - error
        - passed
        - failed
        - declined
        - not-supplied
      title: StepState
      description: Where one step of a journey stands.
    StepReason:
      properties:
        code:
          type: string
          title: Code
          description: A stable identifier for the reason.
        message:
          type: string
          title: Message
          description: A readable explanation of the reason.
        details:
          additionalProperties: true
          type: object
          title: Details
          description: >-
            What the reason is about, as the values its message was written
            from. Keyed per code and not a fixed shape, so read a key you know
            and ignore the rest. A reason about one of a step's document slots
            carries that slot's key as `slot`, which is what attributes it to a
            single document rather than to the step as a whole.


            Empty on a record whose collected data has been cleared: the
            specifics go with the material, and only the code and the message
            are kept.
      type: object
      required:
        - code
        - message
      title: StepReason
      description: One machine-readable reason a step has not passed.
    CollectedRecord:
      properties:
        answer:
          additionalProperties: true
          type: object
          title: Answer
          description: >-
            The user's current answer, shaped per step type. A step whose answer
            is the files it gathered reports them as its documents rather than
            here, so this is empty on a step that asks for nothing else.
        outputs:
          additionalProperties: true
          type: object
          title: Outputs
          description: >-
            What the step's checks established. A step that passed publishes
            these for the steps after it to read, so a later check can be made
            against them.


            A step that failed reports what its checks found here as well, and
            nothing after it reads those. A cross-check that failed on one name
            still scored the others, and this is where those scores are.


            Where a step published its outputs, every field its type publishes
            is here, and one with nothing to say is null, so read those for a
            value rather than for the key. Two cases carry no key at all: a step
            that published nothing reports an empty object, and a form step
            publishes the fields your workflow declares, so one the user left
            blank is absent.


            Where your workflow is set up to reach you in names or shapes of
            your own, these keys are those names, and a field your workflow
            converts arrives as its expression yields it. Every other value
            keeps the place and the shape it is published in. This reference
            describes the fields as the system publishes them, so they are what
            to translate from, and `output_transformations` on the workflow
            states the translation. It reaches this object alone: `answer` comes
            back in the shape you send it.
      type: object
      required:
        - answer
        - outputs
      title: CollectedRecord
      description: What a step collected and what its checks established.
    DocumentRecord:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: The document's id, used to download it.
        slot:
          type: string
          title: Slot
          description: The named slot the file sits in.
        kind:
          type: string
          title: Kind
          description: >-
            Which of its slot's kinds the file was provided as. Every slot names
            at least one, and `intake.slots` names them for every step answered
            over this API. A file a check fetched carries the kind of document
            the source returned, and a photo taken on the person's own screens
            carries the kind of photo it was asked for.
        label:
          anyOf:
            - type: string
            - type: 'null'
          title: Label
          description: >-
            That kind's name in your own system, where your workflow gives it
            one. The same label on the same document across branches is how you
            find it without knowing which branch ran.
        filename:
          type: string
          title: Filename
          description: The original filename.
        content_type:
          type: string
          title: Content Type
          description: The file's MIME type.
        size_bytes:
          type: integer
          title: Size Bytes
          description: The file's size in bytes.
        sha256:
          type: string
          title: Sha256
          description: The SHA-256 hash of the file's contents.
        received_at:
          type: string
          format: date-time
          title: Received At
          description: When the file was received.
      type: object
      required:
        - id
        - slot
        - kind
        - label
        - filename
        - content_type
        - size_bytes
        - sha256
        - received_at
      title: DocumentRecord
      description: >-
        One file on the record, whether the user uploaded it or the step fetched
        it on their behalf.
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````

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