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

# Upload a document

> Uploads a file and creates a document record. `purpose` records what you will use the document for, and only your request sets it: send `purpose=transaction_support` to attach the document to a payout or an order, or the payout or order refuses the document id. Conduit identifies what the file contains, and its own determination is what applies; `classificationStatus` does not control attachment. Sending `type` is optional and records which requirement slot you uploaded the file against, so the file is shown against that slot. Optional multipart fields: `purpose`, `name` (human-readable label), `type` and `eddEvidenceKind`. Send `type=EDD_EVIDENCE` with an `eddEvidenceKind` when the requirements response asks for it. Maximum file size is 10 MB; the request may contain at most 16 multipart fields in total. File type is determined by inspecting the file's contents — the `Content-Type` header and filename extension are advisory only.



## OpenAPI

````yaml https://api.sandbox.conduit.financial/v2/api-docs/openapi.json post /documents
openapi: 3.0.0
info:
  title: Conduit Sandbox API
  description: >-
    **Sandbox API** — clients integrate against this surface to exercise happy
    and unhappy paths without consuming real KYC/PSP credits or moving real
    money. Customer KYC, banking partners, and crypto custody are stubbed;
    org-level KYB runs against real providers. Simulation endpoints under
    `/v2/sandbox/*` drive specific scenarios.


    Internal and portal endpoints are excluded from this spec.
  version: '2.0'
  contact: {}
servers:
  - url: https://api.sandbox.conduit.financial/v2
    description: Sandbox
  - url: https://api.conduit.financial/v2
    description: Production
security:
  - api-key: []
tags:
  - name: Customers
  - name: Registered Addresses
  - name: Wallets
  - name: Wallet Signers
  - name: Signing Quorum
  - name: Virtual Accounts
  - name: Applications
  - name: RFIs
  - name: Documents
  - name: Verifications
  - name: Signing Requests
  - name: Transactions
  - name: Payouts
  - name: Whitelist Recipients
  - name: Orders
  - name: Asset Chain Pairs
  - name: Quotes
  - name: Webhook Endpoints
  - name: Webhook Deliveries
  - name: Webhook Event Types
  - name: Features
  - name: Customer Onboarding
  - name: Markup
  - name: Sandbox
paths:
  /documents:
    post:
      tags:
        - Documents
      summary: Upload a document
      description: >-
        Uploads a file and creates a document record. `purpose` records what you
        will use the document for, and only your request sets it: send
        `purpose=transaction_support` to attach the document to a payout or an
        order, or the payout or order refuses the document id. Conduit
        identifies what the file contains, and its own determination is what
        applies; `classificationStatus` does not control attachment. Sending
        `type` is optional and records which requirement slot you uploaded the
        file against, so the file is shown against that slot. Optional multipart
        fields: `purpose`, `name` (human-readable label), `type` and
        `eddEvidenceKind`. Send `type=EDD_EVIDENCE` with an `eddEvidenceKind`
        when the requirements response asks for it. Maximum file size is 10 MB;
        the request may contain at most 16 multipart fields in total. File type
        is determined by inspecting the file's contents — the `Content-Type`
        header and filename extension are advisory only.
      operationId: DocumentsController_create_v2
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    Document file. Allowed types (validated by inspecting the
                    file's magic bytes, not the filename or Content-Type
                    header): application/pdf, image/jpeg, image/png. Maximum
                    size: 10 MB.
                purpose:
                  type: string
                  enum:
                    - organization_onboarding
                    - kyc
                    - feature_request
                    - transaction_support
                    - rfi_response
                  description: >-
                    What the document is for. A payout or order accepts only
                    `transaction_support` in `documents`; an RFI reply accepts
                    only `rfi_response` in `documentIds`.
                name:
                  type: string
                  description: Human-readable label for the document.
                type:
                  type: string
                  enum:
                    - BUSINESS_REGISTRATION
                    - ARTICLES_OF_INCORPORATION
                    - TAX_CERTIFICATE
                    - OPERATING_LICENSE
                    - REGULATORY_LICENSE
                    - SHAREHOLDERS_REGISTRY
                    - DIRECTORS_REGISTRY
                    - AUTHORIZATION_TO_ACT
                    - PROOF_OF_ADDRESS
                    - CERTIFICATE_OF_GOOD_STANDING
                    - FLOW_OF_FUNDS
                    - AUDITED_FINANCIAL_STATEMENT
                    - BANK_STATEMENT
                    - ORG_STRUCTURE_CHART
                    - AML_AUDIT
                    - COMPLIANCE_POLICY
                    - INSTITUTIONAL_INVESTOR_DOCUMENTATION
                    - IDENTITY_VERIFICATION
                    - IDENTITY_VERIFICATION_ATTESTATION
                    - EDD_EVIDENCE
                    - BANK_VERIFICATION_LETTER
                    - INVOICE
                    - CONTRACT
                    - PAYROLL_REGISTER
                    - INVESTMENT_AGREEMENT
                    - OTHER
                    - business_registration
                    - articles_of_incorporation
                    - tax_certificate
                    - operating_license
                    - regulatory_license
                    - shareholders_registry
                    - directors_registry
                    - authorization_to_act
                    - proof_of_address
                    - certificate_of_good_standing
                    - flow_of_funds
                    - audited_financial_statement
                    - bank_statement
                    - org_structure_chart
                    - aml_audit
                    - compliance_policy
                    - institutional_investor_documentation
                    - identity_verification
                    - identity_verification_attestation
                    - edd_evidence
                    - bank_verification_letter
                    - invoice
                    - contract
                    - payroll_register
                    - investment_agreement
                    - other
                  description: >-
                    The requirement slot you uploaded this file against, from
                    `documents[].canonicalType` in the requirements response, or
                    a payout's `acceptedDocumentTypes`, including `other`. Upper
                    or lower case: `invoice` and `INVOICE` both record
                    `INVOICE`. Sending it shows the file against that slot;
                    Conduit still identifies the document itself, and that
                    determination is what applies.
                eddEvidenceKind:
                  type: string
                  enum:
                    - payslip_or_employment_letter
                    - tax_return
                    - sale_of_asset_or_inheritance
                    - bank_statement
                  description: >-
                    Which kind of evidence the file is. Required when `type` is
                    `EDD_EVIDENCE`, and refused with any other `type`.
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentCreateResponseDto'
        '400':
          description: >-
            **INVALID_OID_FORMAT**: A path or query parameter expected a valid
            object identifier but received a value that does not match the
            expected format.


            **VALIDATION_ERROR**: The request body or query parameters failed
            validation. One or more fields have invalid values, missing required
            properties, or incorrect types. A required text field that holds
            only spaces counts as missing. Multipart file uploads that fail at
            the multipart-parser layer (unexpected form-field name, too many
            parts) carry an extra 'field' member naming the offending
            form-field.


            **MALFORMED_JSON**: The request body could not be parsed as JSON.
            Bodies declared as 'application/json' — and bodies with no
            Content-Type header, which are assumed to be JSON — must contain
            syntactically valid JSON.


            **UNSUPPORTED_FILE_TYPE**: The uploaded file's content does not
            match an allowed type. File type is determined by inspecting the
            file's contents (magic bytes), not the filename extension or the
            Content-Type header. Allowed types: PDF, JPEG, PNG.


            **INVALID_FILE_NAME**: The uploaded file's name contains characters
            that are not allowed (path separators, control characters, NUL
            bytes, or path traversal sequences).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorDto'
              example:
                type: INVALID_OID_FORMAT
                title: Invalid Object ID Format
                status: 400
                detail: >-
                  A path or query parameter expected a valid object identifier
                  but received a value that does not match the expected format.
                resolution: >-
                  Verify that all IDs in the request URL and query parameters
                  are correctly formatted. IDs are typically prefixed strings
                  like 'cus_...', 'app_...', or 'doc_...'.
                docs: https://conduit-v2.mintlify.app/errors#invalid-oid-format
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
        '401':
          description: >-
            **API_KEY_MISSING**: The request did not include an API key. All API
            requests must be authenticated.


            **API_KEY_INVALID**: The provided API key is not recognized or has
            been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
              example:
                type: API_KEY_MISSING
                title: API Key Missing
                status: 401
                detail: >-
                  The request did not include an API key. All API requests must
                  be authenticated.
                resolution: >-
                  Include your API key in the 'x-api-key' header with every
                  request.
                docs: https://conduit-v2.mintlify.app/errors#api-key-missing
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
        '403':
          description: >-
            **ORGANIZATION_ACCESS_SUSPENDED**: Conduit has suspended this
            organization's access. Requests with the organization's API keys and
            from its users are refused until Conduit restores access.


            **API_KEY_READ_ONLY**: This API key has read-only access and cannot
            perform write operations. Read-only keys may make read requests
            (GET, HEAD, OPTIONS) only.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
              example:
                type: ORGANIZATION_ACCESS_SUSPENDED
                title: Organization Access Suspended
                status: 403
                detail: >-
                  Conduit has suspended this organization's access. Requests
                  with the organization's API keys and from its users are
                  refused until Conduit restores access.
                resolution: Contact Conduit support.
                docs: >-
                  https://conduit-v2.mintlify.app/errors#organization-access-suspended
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
        '413':
          description: >-
            **FILE_TOO_LARGE**: The uploaded file exceeds the maximum allowed
            size (10 MB). The response carries an extra 'field' member naming
            the form-field that exceeded the limit (typically 'file').
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
              example:
                type: FILE_TOO_LARGE
                title: File Too Large
                status: 413
                detail: >-
                  The uploaded file exceeds the maximum allowed size (10 MB).
                  The response carries an extra 'field' member naming the
                  form-field that exceeded the limit (typically 'file').
                resolution: >-
                  Reduce the file size and re-upload. Multi-page PDFs that
                  exceed the limit should be split into smaller files.
                  High-resolution images may be downscaled or re-encoded with
                  stronger compression.
                docs: https://conduit-v2.mintlify.app/errors#file-too-large
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
        '415':
          description: >-
            **UNSUPPORTED_MEDIA_TYPE**: The request carries a body with a
            Content-Type this endpoint cannot parse. JSON endpoints accept
            'application/json'; a body with no Content-Type header at all is
            assumed to be JSON. File-upload endpoints accept only
            'multipart/form-data' — JSON or undeclared bodies are rejected
            there.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
              example:
                type: UNSUPPORTED_MEDIA_TYPE
                title: Unsupported Media Type
                status: 415
                detail: >-
                  The request carries a body with a Content-Type this endpoint
                  cannot parse. JSON endpoints accept 'application/json'; a body
                  with no Content-Type header at all is assumed to be JSON.
                  File-upload endpoints accept only 'multipart/form-data' — JSON
                  or undeclared bodies are rejected there.
                resolution: >-
                  Send the request body with the 'Content-Type:
                  application/json' header. For file uploads, use 'Content-Type:
                  multipart/form-data' — upload endpoints accept no other body
                  type.
                docs: https://conduit-v2.mintlify.app/errors#unsupported-media-type
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
        '429':
          description: >-
            **RATE_LIMITED**: Too many requests. This error is returned by three
            independent checks: the per-organization bucket applied to every
            authenticated API request; the per-IP bucket applied to
            unauthenticated traffic before an API key is validated; and the
            per-IP bucket applied when repeated invalid API keys are submitted
            from the same address. Honor the Retry-After header (also exposed as
            retryAfterSeconds in the body) before retrying. Current limits and
            remaining budget are visible in X-RateLimit-Limit (the bucket size),
            X-RateLimit-Remaining, and X-RateLimit-Reset (seconds until the
            bucket refills) on every response once your API key is accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitedErrorDto'
              example:
                type: RATE_LIMITED
                title: Rate Limited
                status: 429
                detail: >-
                  Too many requests. This error is returned by three independent
                  checks: the per-organization bucket applied to every
                  authenticated API request; the per-IP bucket applied to
                  unauthenticated traffic before an API key is validated; and
                  the per-IP bucket applied when repeated invalid API keys are
                  submitted from the same address. Honor the Retry-After header
                  (also exposed as retryAfterSeconds in the body) before
                  retrying. Current limits and remaining budget are visible in
                  X-RateLimit-Limit (the bucket size), X-RateLimit-Remaining,
                  and X-RateLimit-Reset (seconds until the bucket refills) on
                  every response once your API key is accepted.
                resolution: >-
                  Sleep until Retry-After seconds have elapsed, then retry. For
                  sustained workloads exceeding the per-organization defaults,
                  request a rate-limit increase through your support contact.
                docs: https://conduit-v2.mintlify.app/errors#rate-limited
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
                retryAfterSeconds: 3
        '500':
          description: >-
            **INTERNAL_ERROR**: An unexpected error occurred while processing
            your request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
              example:
                type: INTERNAL_ERROR
                title: Internal Error
                status: 500
                detail: An unexpected error occurred while processing your request.
                resolution: >-
                  Retry the request after a brief delay. If the error persists,
                  contact support and include the correlationId from the error
                  response for investigation.
                docs: https://conduit-v2.mintlify.app/errors#internal-error
                instance: /v2/...
                correlationId: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
                timestamp: '2026-01-15T09:30:00.000Z'
components:
  schemas:
    DocumentCreateResponseDto:
      type: object
      properties:
        id:
          type: string
          pattern: ^doc_[0-9A-Za-z]{22}$
          description: Unique document identifier
        fileName:
          description: Original file name as uploaded
          example: passport-scan.pdf
          type: string
        mimeType:
          description: MIME type of the uploaded file
          example: application/pdf
          type: string
        name:
          description: Human-readable label for the document
          example: John Doe Passport
          type: string
        classifiedTypes:
          description: >-
            Canonical document types assigned by the server-side classifier.
            Omitted until classification runs (asynchronously, after the
            document is attached to a submitted application); the type declared
            at upload is stored separately and does not populate this field.
          type: array
          items:
            type: string
            enum:
              - BUSINESS_REGISTRATION
              - ARTICLES_OF_INCORPORATION
              - TAX_CERTIFICATE
              - OPERATING_LICENSE
              - REGULATORY_LICENSE
              - SHAREHOLDERS_REGISTRY
              - DIRECTORS_REGISTRY
              - AUTHORIZATION_TO_ACT
              - PROOF_OF_ADDRESS
              - CERTIFICATE_OF_GOOD_STANDING
              - FLOW_OF_FUNDS
              - AUDITED_FINANCIAL_STATEMENT
              - BANK_STATEMENT
              - ORG_STRUCTURE_CHART
              - AML_AUDIT
              - COMPLIANCE_POLICY
              - INSTITUTIONAL_INVESTOR_DOCUMENTATION
              - IDENTITY_VERIFICATION
              - IDENTITY_VERIFICATION_ATTESTATION
              - EDD_EVIDENCE
              - BANK_VERIFICATION_LETTER
              - INVOICE
              - CONTRACT
              - PAYROLL_REGISTER
              - INVESTMENT_AGREEMENT
              - OTHER
        eddEvidenceKind:
          description: >-
            Which kind of enhanced due diligence evidence the uploader declared,
            for a document uploaded with `type=EDD_EVIDENCE`. Omitted for any
            other document.
          type: string
          enum:
            - payslip_or_employment_letter
            - tax_return
            - sale_of_asset_or_inheritance
            - bank_statement
        classificationStatus:
          description: >-
            Server-side classifier lifecycle: `pending` (not yet run),
            `completed` (a verdict was produced — the type set may be empty), or
            `failed` (the classifier could not complete: the file may be
            unreadable, or a transient vendor/network error was exhausted).
            Transient failures are re-attempted on the next review run; a
            persistent `failed` warrants re-uploading a clearer file. A document
            that is never submitted with an application stays `pending`, a
            payout or order supporting document included.
          type: string
          enum:
            - pending
            - completed
            - failed
        purpose:
          description: >-
            What the document was uploaded for, as declared by the uploader.
            Omitted when the upload declared none. Only a `transaction_support`
            document can be attached to a payout or an order.
          type: string
          enum:
            - organization_onboarding
            - kyc
            - feature_request
            - transaction_support
            - rfi_response
        fileSize:
          description: >-
            Size in bytes. Omitted for documents uploaded before size capture
            was added.
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the document was uploaded
          example: '2026-01-15T09:30:00.000Z'
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the document was last updated
          example: '2026-01-15T09:30:00.000Z'
      required:
        - id
        - classificationStatus
        - createdAt
        - updatedAt
    ValidationErrorDto:
      type: object
      properties:
        type:
          type: string
          description: Machine-readable error code
          example: CUSTOMER_NOT_FOUND
        title:
          type: string
          description: Human-readable error type label
          example: Customer Not Found
        status:
          type: number
          description: HTTP status code
          example: 404
        detail:
          type: string
          description: Human-readable explanation of this occurrence
          example: Customer with id cus_034A0gCCVsxdV2PjHLx9k1 not found
        resolution:
          type: string
          description: What the developer should do to resolve this error
          example: >-
            Verify the customer ID. Check you are using the correct API key for
            this organization.
        docs:
          type: string
          description: URL to error documentation
          example: https://conduit-v2.mintlify.app/errors#customer-not-found
        instance:
          type: string
          description: Request path that produced the error
          example: /v2/customers/cus_034A0gCCVsxdV2PjHLx9k1
        correlationId:
          description: Request correlation ID
          example: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
          type: string
        timestamp:
          type: string
          description: ISO 8601 UTC timestamp
          example: '2026-04-27T20:00:00.000Z'
        details:
          description: >-
            Additional structured data for domain-specific errors (e.g. missing
            field lists, pair info)
        errors:
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
                description: JSON pointer to the invalid field
                example: /email
              detail:
                type: string
                description: What is wrong with this field
                example: Invalid email format
              allowedValues:
                description: The values this field accepts, when it is a closed set
                example:
                  - ach
                  - fedwire
                  - rtp
                type: array
                items:
                  type: string
              category:
                description: >-
                  Class of blocker (requirements-validator output only). 'field'
                  = form-field gap, 'document' = missing or insufficient
                  document (including per-UBO document slots), 'individual' =
                  required person missing.
                example: field
                type: string
                enum:
                  - field
                  - document
                  - individual
            required:
              - pointer
              - detail
      required:
        - type
        - title
        - status
        - detail
        - resolution
        - docs
        - instance
        - timestamp
    ProblemDetailDto:
      type: object
      properties:
        type:
          type: string
          description: Machine-readable error code
          example: CUSTOMER_NOT_FOUND
        title:
          type: string
          description: Human-readable error type label
          example: Customer Not Found
        status:
          type: number
          description: HTTP status code
          example: 404
        detail:
          type: string
          description: Human-readable explanation of this occurrence
          example: Customer with id cus_034A0gCCVsxdV2PjHLx9k1 not found
        resolution:
          type: string
          description: What the developer should do to resolve this error
          example: >-
            Verify the customer ID. Check you are using the correct API key for
            this organization.
        docs:
          type: string
          description: URL to error documentation
          example: https://conduit-v2.mintlify.app/errors#customer-not-found
        instance:
          type: string
          description: Request path that produced the error
          example: /v2/customers/cus_034A0gCCVsxdV2PjHLx9k1
        correlationId:
          description: Request correlation ID
          example: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
          type: string
        timestamp:
          type: string
          description: ISO 8601 UTC timestamp
          example: '2026-04-27T20:00:00.000Z'
        details:
          description: >-
            Additional structured data for domain-specific errors (e.g. missing
            field lists, pair info)
      required:
        - type
        - title
        - status
        - detail
        - resolution
        - docs
        - instance
        - timestamp
    RateLimitedErrorDto:
      type: object
      properties:
        type:
          type: string
          description: Machine-readable error code
          example: CUSTOMER_NOT_FOUND
        title:
          type: string
          description: Human-readable error type label
          example: Customer Not Found
        status:
          type: number
          description: HTTP status code
          example: 404
        detail:
          type: string
          description: Human-readable explanation of this occurrence
          example: Customer with id cus_034A0gCCVsxdV2PjHLx9k1 not found
        resolution:
          type: string
          description: What the developer should do to resolve this error
          example: >-
            Verify the customer ID. Check you are using the correct API key for
            this organization.
        docs:
          type: string
          description: URL to error documentation
          example: https://conduit-v2.mintlify.app/errors#customer-not-found
        instance:
          type: string
          description: Request path that produced the error
          example: /v2/customers/cus_034A0gCCVsxdV2PjHLx9k1
        correlationId:
          description: Request correlation ID
          example: 00469ea4-52c1-4ffa-bd05-9f28b236a5fe
          type: string
        timestamp:
          type: string
          description: ISO 8601 UTC timestamp
          example: '2026-04-27T20:00:00.000Z'
        details:
          description: >-
            Additional structured data for domain-specific errors (e.g. missing
            field lists, pair info)
        retryAfterSeconds:
          type: integer
          minimum: 0
          exclusiveMinimum: true
          maximum: 9007199254740991
          description: Seconds to wait before retrying
          example: 3
      required:
        - type
        - title
        - status
        - detail
        - resolution
        - docs
        - instance
        - timestamp
        - retryAfterSeconds
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key

````

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