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

# Upload a proof-of-address document

> Attaches a proof-of-address document to the banking application, for the cases where the partner asks for one. The application must already exist and have an individual on it, so complete the application first.

**Two things reject uploads that otherwise look fine.** A `.jpg` file must be sent as `fileType: "jpeg"` — `"jpg"` is refused. And the partner caps the *decoded* size at 10MB, even though their own upload page advertises 20MB; oversized files are rejected here before the round-trip.

`fileContent` accepts either a bare base64 string or a `data:` URL, so a browser `FileReader.readAsDataURL` result can be passed through unchanged.

This is a Firebase callable served from the Cloud Function URL (`https://us-central1-kyc-ts.cloudfunctions.net/uploadBankingDocument`), not the `https://laso.finance` base URL used by the paywalled routes. Callables wrap the request in `{"data": ...}` and the reply in `{"result": ...}`. Send the `id_token` from `/auth` as a Bearer token. Free.



## OpenAPI

````yaml /api-reference/openapi.json post /uploadBankingDocument
openapi: 3.1.0
info:
  title: Laso Finance x402 API
  version: 1.0.0
  x-docs-revision: 106571cd77c5
  x-docs-manifest: https://laso.finance/.well-known/docs-version.json
  contact:
    email: agents+support@laso.finance
  x-guidance: >-
    Laso Finance is a payment-gated (x402) API that lets an AI agent spend USDC
    on real-world financial products: prepaid cards (U.S. and international),
    gift cards, push-to-card transfers to USD/EUR/GBP debit cards, and
    Venmo/PayPal payouts.


    Payment: every paid route is an x402 v2 endpoint. Call it with no payment
    header to receive a 402 challenge listing the accepted networks, then replay
    with a signed USDC payment. Both Base (eip155:8453) and Solana
    (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) are accepted on every paid route;
    the caller picks either chain.


    Identity: `GET /auth` is free and identity-only. Prove wallet ownership with
    a `SIGN-IN-WITH-X` (CAIP-122) header to receive a Firebase id_token, then
    send that token as a Bearer credential to the authenticated read routes
    (`get-card-data`, `get-account-balance`, `get-kyc-status`, etc.). Paid
    routes also return fresh auth credentials in their response, so a payment is
    never required just to obtain a token.


    Recommended flow: (1) `GET /auth` to establish identity, (2) call a paid
    route (e.g. `GET /get-card`) to purchase a product, paying USDC on Base or
    Solana, (3) poll the authenticated read routes with the returned Bearer
    token to fetch the resulting card/transfer details. Full machine-readable
    instructions live at https://laso.finance/SKILL.md.
  description: >-
    Payment-gated API for Laso Finance. All paywalled routes use the x402
    protocol — the caller includes a USDC payment header on Base (eip155:8453)
    or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) and the server verifies
    payment before processing. Free routes require no payment header.


    ## Getting started


    To set up a wallet for making x402 payments, choose a provider:


    - **Locus** (default): https://paywithlocus.com/SKILL.md

    - **Sponge**: https://wallet.paysponge.com/skill.md — automatic x402 service
    discovery

    - **Ampersend**: https://www.ampersend.ai/getting-started.md — self-custody
    on Base or Solana with dual-approval spending limits. Laso Finance is a
    default skill, so no manual endpoint registration is needed.


    ## How x402 works


    1. Call a paywalled endpoint without a payment header → receive a `402
    Payment Required` response containing payment details (price, recipient
    address, network).

    2. Construct an x402 payment header using the details from the 402 response.

    3. Replay the request with the payment header → the server verifies payment
    and processes the request.


    ## Authentication flow


    `GET /auth` is free: callers prove wallet ownership by sending a
    `SIGN-IN-WITH-X` header (CAIP-122 wallet signature). Paywalled routes
    (`/get-card`, `/order-gift-card`, `/get-push-to-card`, `/order-intl-card`)
    also return fresh auth credentials in their responses, so a payment is never
    required just to obtain a token.


    Most routes return auth credentials (`id_token`, `refresh_token`,
    `expires_in`). Use the `id_token` as a Bearer token to call authenticated
    Laso Finance endpoints like `/get-card-data`. When the `id_token` expires,
    use `POST /auth` with `grant_type: refresh_token` to get a new one.


    ## Important notes


    The `/get-card` USA prepaid card endpoint is U.S. only — issued in USD,
    usable at U.S.-based merchants only, and physical goods must ship to a U.S.
    address. For non-U.S. merchants or non-USD currencies, use `GET
    /order-intl-card` instead (international prepaid card, admin-fulfilled
    within 24 hours). All cards are intended for the caller's own use.


    For step-by-step instructions, read https://laso.finance/SKILL.md
servers:
  - url: https://laso.finance
    description: Production
security: []
paths:
  /uploadBankingDocument:
    post:
      tags:
        - Banking
      summary: Upload a proof-of-address document
      description: >-
        Attaches a proof-of-address document to the banking application, for the
        cases where the partner asks for one. The application must already exist
        and have an individual on it, so complete the application first.


        **Two things reject uploads that otherwise look fine.** A `.jpg` file
        must be sent as `fileType: "jpeg"` — `"jpg"` is refused. And the partner
        caps the *decoded* size at 10MB, even though their own upload page
        advertises 20MB; oversized files are rejected here before the
        round-trip.


        `fileContent` accepts either a bare base64 string or a `data:` URL, so a
        browser `FileReader.readAsDataURL` result can be passed through
        unchanged.


        This is a Firebase callable served from the Cloud Function URL
        (`https://us-central1-kyc-ts.cloudfunctions.net/uploadBankingDocument`),
        not the `https://laso.finance` base URL used by the paywalled routes.
        Callables wrap the request in `{"data": ...}` and the reply in
        `{"result": ...}`. Send the `id_token` from `/auth` as a Bearer token.
        Free.
      operationId: uploadBankingDocument
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - data
              properties:
                data:
                  type: object
                  required:
                    - userId
                    - documentType
                    - fileType
                    - fileContent
                    - country
                  properties:
                    userId:
                      type: string
                      description: The Laso user id (the `usr_...` value from /auth).
                      example: usr_7aff81763cae58c936aa6de67dd5a95e
                    documentType:
                      type: string
                      enum:
                        - proof_of_address
                        - bank_statement
                        - utility_bill
                      description: The kind of document.
                      example: utility_bill
                    fileType:
                      type: string
                      enum:
                        - pdf
                        - jpeg
                        - png
                      description: The file's format. Send a .jpg as `jpeg`.
                      example: jpeg
                    fileContent:
                      type: string
                      description: >-
                        The file, base64-encoded. A `data:` URL is also
                        accepted. Decoded size must be 10MB or less.
                    country:
                      type: string
                      description: The document's country, ISO 3166-1 alpha-2.
                      example: US
                    filename:
                      type: string
                      description: The file's name.
                      example: utility-bill.pdf
      responses:
        '200':
          description: The created document id and its review status.
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: object
                    properties:
                      documentId:
                        type: string
                      status:
                        type: string
        '400':
          description: A required field is missing or invalid.
        '401':
          description: Missing, invalid, or expired Bearer token.
        '403':
          description: The caller is not this user and is not an admin.
        '412':
          description: >-
            The application has no individual to attach a document to yet.
            Complete the application first.
      security:
        - BearerAuth: []
      servers:
        - url: https://us-central1-kyc-ts.cloudfunctions.net
components:
  securitySchemes:
    BearerAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Firebase ID token from `/auth` or any paid route, sent as a Bearer
        token: `Authorization: Bearer <id_token>` (the `Bearer ` prefix is
        required).

````