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

# Deposit into the vault

> Move USDC from your wallet into your on-chain vault. Optional: trading and quoting both draw on wallet USDC too.

<Note>
  You do not need this call to trade or to quote. Placing a parlay moves the stake from your wallet
  into the vault in the same step. Maker quotes are backed by wallet USDC plus vault free balance.

  Your vault is created with your first filled position, as bettor or maker. Until then this call
  returns `404`.

  Needs the `funds:deposit` scope and trading enabled. Limited to 10 calls per minute per account.
</Note>


## OpenAPI

````yaml POST /v1/vault/deposit
openapi: 3.0.3
info:
  title: Totalis RFQ API
  version: 2.1.0
  description: >-
    Public REST surface for the Totalis parlay RFQ platform, a decentralized
    request-for-quote marketplace for parlay bets across Kalshi and Polymarket,
    with on-chain Solana vault settlement.


    **Wire format**: snake_case JSON. All successful responses are wrapped in `{
    "data": ... }`; list endpoints add `meta` with cursor-based pagination.
    Errors use a `{ "error": { code, message, details? } }` envelope.


    **Authentication**: programmatic clients send `X-API-Key`; the web dashboard
    uses Privy JWTs (`Authorization: Bearer ...`). Any authenticated user can
    both place parlays and quote as a market maker. There is no separate MM
    role. Admin endpoints are out of scope for this public reference.


    **Rate limiting**: three buckets. Authenticated routes share one per-account
    bucket of 300 req/min (100 without a key). Public market reads (`/markets`,
    `/v1/markets`) are a separate per-IP bucket of 100 req/min that an API key
    does not raise. Quote service routes (`/v1/quote-requests`,
    `/v1/cashout-requests`, `/v1/mm/quote-requests`, `/v1/mm/cashout-requests`)
    have their own per-IP limit, 300 req/min by default. Responses include
    `X-RateLimit-*` headers. Request body limit: 256KB.


    **Pagination**: list endpoints use opaque cursor pagination. Pass
    `meta.cursor` from the previous response as `?cursor=...` to fetch the next
    page; do not parse or construct cursors client-side.
servers:
  - url: https://api.totalis.trade
    description: Production
security:
  - ApiKey: []
tags:
  - name: Markets
    description: Cached Kalshi and Polymarket market data.
  - name: User
    description: User profile, wallet, and devnet helpers.
  - name: API Keys
    description: Manage programmatic access keys for the authenticated user.
paths:
  /v1/vault/deposit:
    post:
      tags:
        - Vault
      summary: Deposit USDC into vault
      description: >-
        Moves USDC from your wallet into your on-chain vault. The vault is
        created with your first filled position, as bettor or maker, so this
        call returns 404 until then. Optional: trading moves the stake into the
        vault by itself, and maker quotes are backed by wallet USDC plus vault
        free balance.
      operationId: depositToVault
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VaultDepositRequest'
      responses:
        '200':
          description: Deposit finalized and reflected in the database mirror
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/VaultTransactionResult'
        '202':
          description: >-
            Deposit accepted; chain outcome or database balance update is
            pending recovery
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/VaultTransactionResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          description: >-
            No vault found (the vault is created with your first filled
            position)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          description: Solana integration not enabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - PrivyJWT: []
        - ApiKey: []
components:
  schemas:
    VaultDepositRequest:
      type: object
      required:
        - amount
      properties:
        amount:
          type: number
          minimum: 0
          exclusiveMinimum: true
          maximum: 1000000
          description: USDC amount to deposit (max 1,000,000)
    VaultTransactionResult:
      type: object
      description: Response for vault deposit/withdraw operations.
      properties:
        tx_signature:
          type: string
          description: Solana transaction signature
        amount:
          type: number
          description: USDC amount deposited/withdrawn
        status:
          type: string
          enum:
            - completed
            - chain_pending
            - balance_pending
          description: |
            `completed` means the finalized chain effect and database mirror
            both committed. `chain_pending` means the broadcast outcome still
            needs chain recovery. `balance_pending` means the transaction
            finalized but the database mirror still needs recovery. Pending
            states fence the vault, and balances may remain stale meanwhile.
            The pending values are returned by deposits; withdrawals retain
            their existing error response while durable recovery is pending.
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
    ErrorBody:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - VALIDATION_ERROR
            - UNAUTHORIZED
            - FORBIDDEN
            - NOT_FOUND
            - CONFLICT
            - RATE_LIMITED
            - PAYLOAD_TOO_LARGE
            - INTERNAL_ERROR
            - SERVICE_UNAVAILABLE
          description: Machine-readable error code.
        message:
          type: string
          description: Human-readable error message.
        details:
          type: object
          description: Additional error context.
        retry_after:
          type: integer
          nullable: true
          description: Seconds until retry; set on 429 responses.
  responses:
    BadRequest:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Programmatic API key. Sent as `X-API-Key: <key>`. Generate one from the
        Totalis dashboard. The WebSocket takes no header; send the key in the
        auth message instead.
    PrivyJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Privy JWT issued to the web dashboard. Sent as `Authorization: Bearer
        <jwt>`. The Privy session signer underpins all wallet-signed actions.

````