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

> ## Agent Instructions
> Money is always a decimal string at the currency's precision (for example "29.00"), paired with an ISO 4217 currency field. Never use minor units.
> Build against the sandbox first: base URL https://sandbox-api.bachs.io with sk_sandbox_ keys. Production is https://api.bachs.io with sk_live_ keys; going live is a key swap.
> Treat webhooks (for example collection.succeeded) as the source of truth for fulfilment, never client-side events or redirects.
> Subscriptions are created by completing a checkout for a recurring product. There is no direct create-subscription endpoint.
> IDs carry resource prefixes (cust_, prod_, sub_, chk_, inv_, ref_) and timestamps are ISO 8601 UTC.

# Upload a compliance file

> Upload an identity document or a company filing and receive a file `id`. Then attach it to the person or account it is for: [Attach a document to a person](/api-reference/persons/attach-a-document-to-a-person) or [Attach a company document](/api-reference/connected-accounts/attach-a-company-document). Uploading and attaching are separate steps, so a wrongly filed document is re-attached instead of re-uploaded.

Send the file as `multipart/form-data`. JPEG, PNG and PDF are accepted, up to **10 MB**.

A file belongs to the account it was uploaded for. To upload for a connected account, send `X-Account-Id`. A file uploaded without it belongs to your platform account and cannot be attached to a connected account.

The response has no download URL. Identity documents are never readable through the API.

For product images, use [Upload a file](/api-reference/media/upload-a-file) instead.



## OpenAPI

````yaml /docs/openapi/openapi.json post /v1/files
openapi: 3.0.3
info:
  title: Bachs API
  version: 1.0.0
  description: >-
    The Bachs API lets you accept payments, manage subscriptions, and move money
    across African markets.


    - **Authentication:** pass your secret key as `Authorization: Bearer
    sk_...`. See [Authentication](/authentication) for keys, scopes, and sandbox
    vs production.

    - **Errors:** errors use `detail` and `error_code`; `doc_url` and
    field-level `errors` are optional. See [Errors](/errors).

    - **Pagination:** list endpoints return `{ items, pagination }`. See
    [Pagination](/guides/pagination).

    - **Idempotency:** use `Idempotency-Key` on public `POST` and `PATCH`;
    reconcile uncertain write outcomes before retrying. See
    [Idempotency](/guides/idempotency).

    - **Base URLs and rate limits:** see the
    [Introduction](/api-reference/overview).
  contact:
    name: Bachs Support
    url: https://bachs.io
servers:
  - url: https://api.bachs.io
    description: Production
  - url: https://sandbox-api.bachs.io
    description: Sandbox
security:
  - ApiKeyAuth: []
tags:
  - name: Payments
    description: Accept payments from customers
  - name: Refunds
    description: Create and manage customer refunds
  - name: Disputes
    description: Respond to chargebacks and manage dispute evidence
  - name: Balances
    description: View balances and account information
  - name: Conversions
    description: Quote, execute, and query currency conversions
  - name: Payouts
    description: Withdraw funds to external accounts
  - name: Webhooks
    description: Receive real-time payment notifications
  - name: Authentication
    description: API key management and authentication
  - name: Customers
    description: Create and manage customers
  - name: Products
    description: Define and manage your billing catalog
  - name: Product Groups
    description: Bundle products for multi-plan checkout
  - name: Media
    description: Upload files and get an upload_id to attach to products
  - name: Checkouts
    description: Create and manage API-driven checkouts without products
  - name: Subscriptions
    description: >-
      Recurring billing. Subscriptions are created through checkout; manage them
      here.
  - name: Customer sessions
    description: >-
      Open a hosted portal session so a customer can manage their own
      subscriptions, invoices and cards.
  - name: Accounts
    description: >-
      Create the accounts your platform onboards, request their capabilities,
      walk them through their requirements, and read what they still owe.
  - name: Transfers
    description: Move funds between your platform and the accounts you own.
  - name: Platform Fees
    description: Read the platform's cut of an account's sale.
  - name: Virtual Accounts
    description: Create and read fixed bank account numbers for receiving deposits.
  - name: Files
paths:
  /v1/files:
    post:
      tags:
        - Files
      summary: Upload a compliance file
      description: >-
        Upload an identity document or a company filing and receive a file `id`.
        Then attach it to the person or account it is for: [Attach a document to
        a person](/api-reference/persons/attach-a-document-to-a-person) or
        [Attach a company
        document](/api-reference/connected-accounts/attach-a-company-document).
        Uploading and attaching are separate steps, so a wrongly filed document
        is re-attached instead of re-uploaded.


        Send the file as `multipart/form-data`. JPEG, PNG and PDF are accepted,
        up to **10 MB**.


        A file belongs to the account it was uploaded for. To upload for a
        connected account, send `X-Account-Id`. A file uploaded without it
        belongs to your platform account and cannot be attached to a connected
        account.


        The response has no download URL. Identity documents are never readable
        through the API.


        For product images, use [Upload a
        file](/api-reference/media/upload-a-file) instead.
      operationId: createFile
      parameters:
        - name: X-Account-Id
          in: header
          required: false
          schema:
            type: string
          description: >-
            The connected account the file is for, e.g. `acct_3Wq8ZfT1yHnJ5sVe`.
            Send it whenever the file is for a connected account. Without it the
            file is stored under your own platform account, and attaching it to
            a connected account returns `404 NOT_FOUND` with `Attachment not
            found`.
          example: acct_3Wq8ZfT1yHnJ5sVe
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
                - purpose
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload. JPEG, PNG or PDF, up to 10 MB.
                purpose:
                  type: string
                  enum:
                    - identity_document
                    - account_requirement
                  description: >-
                    How the file may be used. A file can only be attached where
                    its purpose fits.
                  x-enumDescriptions:
                    identity_document: A person's government ID or address evidence.
                    account_requirement: A company filing or supporting evidence.
      responses:
        '201':
          description: The file was stored.
          content:
            application/json:
              example:
                id: upl_7c2f9a10bd4e
                purpose: identity_document
                file_name: ada-nin.jpg
                mime_type: image/jpeg
                size: 184320
                created_at: '2026-08-07T09:22:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
        - ApiKeyAuth: []
components:
  responses:
    BadRequest:
      description: >-
        Bad Request - Validation errors or invalid request format. Check the
        `details` object for field-specific validation errors. Common causes:
        missing required fields, invalid data types, values outside allowed
        ranges, or invalid formats.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: Invalid request parameters
            error_code: VALIDATION_ERROR
            errors:
              - field: amount
                message: Amount must be a positive decimal string
                type: value_error
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
    Unauthorized:
      description: >-
        Unauthorized - Invalid, missing, or expired API key. Verify your API key
        is correctly formatted and included in the Authorization header as
        `Bearer sk_sandbox_...` or `Bearer sk_live_...`. Check that your key
        hasn't been revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: Invalid API key
            error_code: UNAUTHORIZED
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
  schemas:
    Error:
      type: object
      description: Standard error response format used across all API endpoints
      properties:
        detail:
          type: string
          description: Human-readable error message explaining what went wrong.
          example: Invalid request parameters
        error_code:
          type: string
          description: >-
            Machine-readable error code. Use this to handle errors
            programmatically. Common codes: VALIDATION_ERROR, UNAUTHORIZED,
            FORBIDDEN, NOT_FOUND, CONFLICT, TOO_MANY_REQUESTS,
            INTERNAL_SERVER_ERROR, BAD_GATEWAY, SERVICE_UNAVAILABLE.
          example: VALIDATION_ERROR
        errors:
          type: array
          description: >-
            Optional field-level details on some validation errors. Other
            validation responses contain only detail and error_code. Entry
            fields depend on the validation source.
          items:
            type: object
            properties:
              field:
                type: string
                description: The field that failed validation.
                example: amount
              message:
                type: string
                description: Description of the validation failure.
                example: Amount must be a positive decimal string
              type:
                type: string
                description: Error type identifier.
                example: value_error
              code:
                type: string
                description: >-
                  Optional requirement-field rejection code. Some validation
                  entries provide code instead of type.
                example: currency_not_supported
            required:
              - field
              - message
        doc_url:
          type: string
          description: Optional link to documentation for this error; some errors omit it.
          example: https://docs.bachs.io/api-reference/error-reference#general
      required:
        - detail
        - error_code
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Bearer token authentication. Pass your API key as `Authorization: Bearer
        sk_...`. See [Authentication](/authentication) for keys, scopes, and
        sandbox vs production.

````

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