openapi: 3.0.3
info:
  title: Credit Coop API
  description: >-
    Backend API for Credit Coop cashflow-secured DeFi lending platform.


    To chat with an AI agent about this API, use a prompt like "Using
    https://api.creditcoop.xyz/docs/openapi.json tell me how to... ?"
  version: 3.0.0
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: "API key in the format: cc_xxx_yyy (for customer API routes)"
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Clerk authentication token (session JWT or Clerk OAuth access
        token) used by Credit Coop
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://clerk.creditcoop.xyz/oauth/authorize
          tokenUrl: https://clerk.creditcoop.xyz/oauth/token
          scopes:
            openid: OpenID Connect
            email: User email
            profile: User profile
      description: Credit Coop OAuth
  schemas:
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
        message:
          type: string
        statusCode:
          type: integer
    Organization:
      type: object
      required:
        - id
        - name
        - slug
      properties:
        id:
          type: string
          format: uuid
          description: Organization unique identifier
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          maxLength: 255
          description: Organization display name
        slug:
          type: string
          maxLength: 100
          description: URL-friendly identifier
        header:
          type: string
          nullable: true
          description: Short tagline or headline for the organization profile
        description:
          type: string
          nullable: true
          description: Brief summary of the organization
        overview:
          type: string
          nullable: true
          description: Long-form organization description (may contain Markdown)
        links:
          type: array
          description: Organization links and image assets. Labels starting with "#" are
            image assets (e.g. "#logo", "#header"); all others are external
            links (e.g. "Twitter", "Website").
          items:
            type: object
            required:
              - id
              - label
              - url
            properties:
              id:
                type: string
                format: uuid
                description: Link unique identifier
              label:
                type: string
                description: Link type. "#logo" and "#header" denote image assets; other values
                  (e.g. "Twitter", "Website") denote external links.
              linkText:
                type: string
                nullable: true
                description: Display text for external links (e.g. "@raincards", "rain.xyz")
              iconUrl:
                type: string
                nullable: true
                description: Icon image URL for external links
              url:
                type: string
                description: Target URL (image URL for asset links, destination URL for external
                  links)
    Pagination:
      type: object
      required:
        - total
        - limit
        - offset
      properties:
        total:
          type: integer
          description: Total number of records matching the query
        limit:
          type: integer
          description: Maximum number of records returned per page
        offset:
          type: integer
          description: Number of records skipped from the start
    Token:
      type: object
      required:
        - id
        - address
        - networkId
        - symbol
        - decimals
      properties:
        id:
          type: string
          format: uuid
          description: Token unique identifier
          example: 550e8400-e29b-41d4-a716-446655440000
        address:
          type: string
          description: Token contract address
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        networkId:
          type: string
          description: CAIP-2 network identifier
          example: eip155:1
        symbol:
          type: string
          description: Token ticker symbol (e.g. "USDC", "WETH")
        name:
          type: string
          nullable: true
          description: Full token name
        decimals:
          type: integer
          minimum: 0
          maximum: 255
          description: Number of decimal places for the token
        wraps:
          type: string
          nullable: true
          description: Underlying asset this token represents (e.g. "USD" for USDC, "ETH"
            for WETH)
        iconUrl:
          type: string
          nullable: true
          description: URL of the token icon image
        coingeckoId:
          type: string
          nullable: true
          description: CoinGecko API identifier for price lookups
    Network:
      type: object
      required:
        - networkId
        - displayName
      properties:
        networkId:
          type: string
          description: CAIP-2 network identifier
          example: eip155:1
        displayName:
          type: string
          description: Human-readable network name (e.g. "Ethereum Mainnet")
        explorerUrl:
          type: string
          nullable: true
          description: Block explorer base URL
        rpcUrl:
          type: string
          nullable: true
          description: RPC endpoint URL
        iconUrl:
          type: string
          nullable: true
          description: URL of the network icon image
        nativeCurrencySymbol:
          type: string
          nullable: true
          description: Native currency ticker (e.g. "ETH")
        nativeCurrencyDecimals:
          type: integer
          nullable: true
          description: Native currency decimal places
    Vault:
      type: object
      required:
        - id
        - address
        - networkId
        - protocolVersion
        - label
        - organizationId
        - deployedAt
      properties:
        id:
          type: string
          format: uuid
          description: Vault unique identifier
          example: 550e8400-e29b-41d4-a716-446655440000
        address:
          type: string
          description: Vault contract address
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        networkId:
          type: string
          description: CAIP-2 network identifier
          example: eip155:1
        protocolVersion:
          type: string
          nullable: true
          description: Credit Coop protocol/contract generation (e.g. "v1", "v2"). Null
            when not classified.
          example: v2
        label:
          type: string
          nullable: true
          description: Display label for the vault. Always present; null if not configured.
        organizationId:
          type: string
          format: uuid
          nullable: true
          description: Vault curator organization ID
          example: 550e8400-e29b-41d4-a716-446655440000
        deployedAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when the vault contract was deployed
          example: 2025-01-15T10:30:00Z
        organization:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/Organization"
          description: Organization details with links. Only included when expand includes
            "organization".
        relatedAddresses:
          type: object
          nullable: true
          description: On-chain related addresses. Only included when expand includes
            "related-addresses".
          properties:
            creditStrategy:
              type: string
              nullable: true
              description: CreditStrategy contract address. Manages credit allocation from
                vault funds to credit facilities.
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            liquidStrategy:
              type: string
              nullable: true
              description: LiquidStrategy contract address. Manages liquid asset reserves in
                the vault.
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            vaultCurator:
              type: string
              nullable: true
              description: Vault curator (manager) address of the CreditStrategy contract.
                Retrieved by calling manager() on the creditStrategy.
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        assets:
          type: object
          nullable: true
          description: Asset information. Only included when expand includes "assets".
          properties:
            assetToken:
              type: string
              nullable: true
              description: Asset token address
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            shareToken:
              type: string
              nullable: true
              description: Share token address
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            decimals:
              type: integer
              nullable: true
              description: Asset token decimals
            totalAssets:
              type: string
              nullable: true
              description: Total assets in the vault (raw uint256 — divide by 10^decimals to
                get human-readable value)
            totalLiquidAssets:
              type: string
              nullable: true
              description: Total liquid assets. Vault's balance - total pending deposits -
                claimable redeem assets + liquid strategy total assets +
                uninvested credit strategy assets (raw uint256 — divide by
                10^decimals to get human-readable value)
            totalSupply:
              type: string
              nullable: true
              description: Total supply of vault shares (raw uint256 — divide by 10^decimals
                to get human-readable value)
            sharePrice:
              type: string
              nullable: true
              description: Share price of the vault (raw uint256 — divide by 10^decimals to
                get human-readable value)
            baseUnit:
              type: string
              nullable: true
              description: Minimum accounting unit used by the CreditStrategy for scaling
                interest calculations (raw uint256). Equal to 10^decimals.
            totalActiveCredit:
              type: string
              nullable: true
              description: Total active credit from CreditStrategy. Deposits plus accrued and
                repaid interest for all credit lines (raw uint256 — divide by
                10^decimals to get human-readable value)
            uninvestedCreditAssets:
              type: string
              nullable: true
              description: Uninvested credit assets. Asset token balance held by
                CreditStrategy (raw uint256 — divide by 10^decimals to get
                human-readable value)
        apy:
          type: object
          nullable: true
          description: APY data from historical sharePrice snapshots. Only included when
            expand includes "apy".
          properties:
            apyPct30D:
              type: number
              nullable: true
              description: 30-day APY in percent (e.g. 5.0 = 5%). Null if insufficient
                snapshot data.
        fees:
          type: object
          nullable: true
          description: Credit strategy fees in basis points. Only included when expand
            includes "fees".
          properties:
            managementFee:
              type: integer
              description: Management fee in basis points (e.g. 200 = 2%)
            performanceFee:
              type: integer
              description: Performance fee in basis points (e.g. 1000 = 10%)
    CreditFacility:
      type: object
      required:
        - id
        - address
        - networkId
        - protocolVersion
        - label
        - organizationId
      properties:
        id:
          type: string
          format: uuid
          description: Credit facility unique identifier
          example: 550e8400-e29b-41d4-a716-446655440000
        address:
          type: string
          description: SecuredLine contract address
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        networkId:
          type: string
          description: CAIP-2 network identifier
          example: eip155:1
        protocolVersion:
          type: string
          nullable: true
          description: Credit Coop protocol/contract generation (e.g. "v1", "v2"). Null
            when not classified.
          example: v2
        label:
          type: string
          nullable: true
          description: Display label for the credit facility. Always present; null if not
            configured.
        organizationId:
          type: string
          format: uuid
          nullable: true
          description: Borrower organization ID
          example: 550e8400-e29b-41d4-a716-446655440000
        organization:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/Organization"
          description: Organization details with links. Only included when expand includes
            "organization".
        relatedAddresses:
          type: object
          nullable: true
          description: On-chain related addresses. Only included when expand includes
            "related-addresses".
          properties:
            spigot:
              type: string
              nullable: true
              description: Spigot contract address. Captures and routes borrower revenue to
                debt repayment.
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            borrower:
              type: string
              nullable: true
              description: Address authorized to borrow, repay, and close credit lines
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            admin:
              type: string
              nullable: true
              description: Credit facility administrator address
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            spigotOperator:
              type: string
              nullable: true
              description: Address authorized to execute revenue claims on the Spigot
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
            escrow:
              type: string
              nullable: true
              description: Escrow contract address. Holds collateral posted by the borrower
                and enforces the minimum collateral ratio.
              example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        fees:
          type: object
          nullable: true
          description: Fee configuration for the Credit Facility. Only included when
            expand includes "fees".
          required:
            - originationFee
            - swapFee
            - servicingFee
          properties:
            originationFee:
              type: string
              description: Origination fee (basis points)
            swapFee:
              type: string
              description: Swap fee (basis points)
            servicingFee:
              type: string
              description: Servicing fee (basis points)
        counts:
          type: object
          nullable: true
          description: Active credit lines and open proposals counts. Only included when
            expand includes "counts".
          required:
            - activeCreditLines
            - openProposals
          properties:
            activeCreditLines:
              type: integer
              description: Number of active credit lines
            openProposals:
              type: integer
              description: Number of open mutual consent proposals
        status:
          type: object
          nullable: true
          description: On-chain contract status. Only included when expand includes
            "status".
          required:
            - code
            - label
          properties:
            code:
              type: integer
              description: "Numeric status code (0: UNINITIALIZED, 1: ACTIVE, 2: LIQUIDATABLE,
                3: REPAID, 4: INSOLVENT, 5: ABORTED)"
            label:
              type: string
              enum:
                - UNINITIALIZED
                - ACTIVE
                - LIQUIDATABLE
                - REPAID
                - INSOLVENT
                - ABORTED
                - UNKNOWN
              description: Human-readable status label. UNKNOWN is returned when the on-chain
                status code is outside the known range (e.g., a new status added
                by a future contract version).
        collateral:
          type: object
          nullable: true
          description: On-chain collateral state from the Escrow contract. Only included
            when expand includes "collateral". Null when the facility has no
            escrow, RPC is unavailable, or the facility predates the Escrow
            architecture.
          required:
            - maxLtvBps
            - totalOutstandingDebt
            - collateralValue
            - ltvBps
            - targetLtvBps
            - collateralTokens
          properties:
            maxLtvBps:
              type: string
              nullable: true
              description: Maximum loan-to-value ratio allowed for this facility, in basis
                points (10000 = 100%). Computed server-side as 10000² /
                minimumCollateralRatio (integer floor). Null when the facility
                does not enforce a collateral requirement.
              example: "8000"
            totalOutstandingDebt:
              type: string
              nullable: true
              description: Total outstanding debt in USD as a formatted decimal string with
                trailing zeros trimmed (e.g. "1234.56"). The debt token's
                decimals are read from the first active credit position and
                applied server-side. "0" when there are no active positions.
                Null when the facility does not enforce a collateral
                requirement.
              example: "1234.56"
            collateralValue:
              type: string
              nullable: true
              description: Collateral value in USD as a formatted decimal string with trailing
                zeros trimmed (e.g. "2000" or "1999.99"). Formatted server-side.
                Null when the facility does not enforce a collateral
                requirement.
              example: "2000"
            ltvBps:
              type: string
              nullable: true
              description: 'Current loan-to-value ratio in basis points: (totalOutstandingDebt
                × 10000) / collateralValue, computed server-side from raw
                on-chain values (decimals normalized before division). "0" when
                there is no outstanding debt. "999999999" (sentinel) when debt
                is positive but on-chain collateral value is 0 — the facility is
                effectively infinitely undercollateralized. Null when the
                facility does not enforce a collateral requirement, or when debt
                decimals could not be resolved.'
              example: "6666"
            targetLtvBps:
              type: string
              nullable: true
              description: Target LTV in basis points. Defines the minimum collateral value
                required to back the facility's credit limit (min collateral ≈
                creditLimit × 10000 / targetLtvBps). Null when no target is
                configured for this facility.
              example: "7500"
            collateralTokens:
              type: array
              description: Every token ever enabled as collateral on the Escrow, with its
                current on-chain amount and USD value. May be empty if
                EnableCollateral events have not been ingested for this Escrow.
              items:
                type: object
                required:
                  - address
                  - amount
                  - decimals
                  - usdValue
                properties:
                  address:
                    type: string
                    description: Collateral token address (ERC-20).
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  amount:
                    type: string
                    nullable: true
                    description: Current on-chain collateral amount (raw uint256; divide by
                      `decimals` to get human-readable value). Null if the
                      on-chain `getCollateralData` read failed.
                  decimals:
                    type: integer
                    nullable: true
                    description: Decimals of the collateral token itself (for rendering `amount`).
                      Null if ERC-20 metadata could not be fetched.
                  usdValue:
                    type: string
                    nullable: true
                    description: USD value of the current collateral amount as a human-readable
                      decimal string (e.g. "1234.56"), up to 6 decimal places
                      with trailing zeros trimmed. Null if amount, price, or
                      decimals is unavailable.
    CreditLine:
      type: object
      required:
        - lineTokenId
      properties:
        lineTokenId:
          type: string
          description: Credit line token ID
        deposit:
          type: string
          nullable: true
          description: Deposit amount (raw uint256 — divide by 10^decimals to get
            human-readable value)
        creditLimit:
          type: string
          nullable: true
          description: "Credit limit (raw uint256 — divide by 10^decimals to get
            human-readable value). For open lines: equals current deposit. For
            closed lines: deposit from the most recent AddCredit or
            IncreaseCredit event."
        principal:
          type: string
          nullable: true
          description: Principal amount borrowed (raw uint256 — divide by 10^decimals to
            get human-readable value)
        interestBalance:
          type: string
          nullable: true
          description: "Total interest balance (raw uint256 — divide by 10^decimals to get
            human-readable value). Open lines: interestAccrued + interestRepaid.
            Closed lines: interestRepaid."
        interestAccrued:
          type: string
          nullable: true
          description: Interest accrued (raw uint256 — divide by 10^decimals to get
            human-readable value)
        interestRepaid:
          type: string
          nullable: true
          description: Interest repaid (raw uint256 — divide by 10^decimals to get
            human-readable value)
        token:
          type: string
          nullable: true
          description: Token address for this credit line
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        decimals:
          type: integer
          nullable: true
          description: Token decimals
        isOpen:
          type: boolean
          nullable: true
          description: Whether the credit line is open
        isRestricted:
          type: boolean
          nullable: true
          description: Whether the credit line is restricted
        earlyWithdrawalFee:
          type: string
          nullable: true
          description: Early withdrawal fee in basis points
        deadline:
          type: string
          format: date-time
          nullable: true
          description: Credit line deadline
          example: 2025-01-15T10:30:00Z
        drawRate:
          type: string
          nullable: true
          description: Draw rate in basis points (interest rate on borrowed principal)
        facilityRate:
          type: string
          nullable: true
          description: Facility rate in basis points (interest rate on unused deposit)
        apyPct:
          type: number
          nullable: true
          description: Computed APY as a percentage (e.g. 5.0 = 5.0%). Weighted average of
            drawRate on principal and facilityRate on unused deposit.
        createdTxHash:
          type: string
          nullable: true
          description: Transaction hash of the AddCredit event that created this line
        createdBlockNumber:
          type: integer
          nullable: true
          description: Block number when this credit line was created
        createdAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when this credit line was created
          example: 2025-01-15T10:30:00Z
        fees:
          type: object
          nullable: true
          description: Only included when expand=fees is specified. Null if fetching failed.
          required:
            - originationFees
          properties:
            originationFees:
              type: string
              description: Total origination fees paid for this credit line (raw uint256 —
                divide by 10^decimals to get human-readable value)
        error:
          type: string
          nullable: true
          description: Error message if fetching this credit line failed. Other fields
            will be null.
    VaultCreditLineRelatedAddresses:
      type: object
      required:
        - facility
        - facilityOrganizationId
      properties:
        facility:
          type: string
          nullable: true
          description: SecuredLine contract address for this credit line
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        facilityOrganizationId:
          type: string
          format: uuid
          nullable: true
          description: Organization ID of the borrower associated with the facility
            address. Null if the facility address is not registered.
    FacilityCreditLineRelatedAddresses:
      type: object
      required:
        - lender
      properties:
        lender:
          type: string
          description: Lender address (owner of the credit line NFT)
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        vault:
          type: string
          nullable: true
          description: Lending vault address associated with the lender
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        vaultCurator:
          type: string
          nullable: true
          description: Vault curator address for the lender
          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
paths:
  /v3/platform/networks:
    get:
      operationId: listNetworks
      summary: List supported blockchain networks
      tags:
        - Platform
      description: List all supported blockchain networks
      security: &a1
        - ApiKeyAuth: []
        - BearerAuth: []
        - OAuth2: []
        - {}
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - networks
                properties:
                  networks:
                    type: array
                    items:
                      $ref: "#/components/schemas/Network"
  /v3/platform/tokens:
    get:
      operationId: listTokens
      summary: List supported tokens
      tags:
        - Platform
      description: List all supported tokens with optional filters. No authentication
        required, but authenticated requests may receive increased rate limits.
      parameters:
        - schema:
            type: string
          in: query
          name: address
          required: false
          description: "Filter by contract address (0x...). Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
          in: query
          name: networkId
          required: false
          description: Filter by CAIP-2 network ID (e.g. eip155:8453)
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - tokens
                properties:
                  tokens:
                    type: array
                    items:
                      $ref: "#/components/schemas/Token"
  /v3/platform/stats:
    get:
      operationId: getPlatformStats
      summary: Get platform statistics
      tags:
        - Platform
      description: Get all platform statistics in a single response. No authentication
        required, but authenticated requests may receive increased rate limits.
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - totalVolumeUsd
                  - activeLoansUsd
                  - totalInterestPaidUsd
                  - totalBorrowedUsd
                properties:
                  totalVolumeUsd:
                    type: string
                    description: Total volume in USD (borrows + repayments). Returned as a string to
                      avoid floating-point precision loss.
                    example: "1234567.890000"
                  activeLoansUsd:
                    type: string
                    description: Current outstanding principal in USD. Returned as a string to avoid
                      floating-point precision loss.
                    example: "500000.000000"
                  totalInterestPaidUsd:
                    type: string
                    description: Total interest paid in USD. Returned as a string to avoid
                      floating-point precision loss.
                    example: "45678.900000"
                  totalBorrowedUsd:
                    type: string
                    description: Cumulative total borrowed in USD (all time). Returned as a string
                      to avoid floating-point precision loss.
                    example: "2000000.000000"
  /v3/platform/stats/vault-apys:
    get:
      operationId: getPlatformVaultApys
      summary: Get vault APYs
      tags:
        - Platform
      description: Get APY for all lending vaults from sharePrice snapshots. No
        authentication required, but authenticated requests may receive
        increased rate limits.
      parameters:
        - schema:
            type: integer
            default: 30
          in: query
          name: period
          required: false
          description: Number of days to look back for APY calculation
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - weightedApyBps
                  - weightedApyPct
                  - totalTvl
                  - periodDays
                  - vaultCount
                  - decimals
                properties:
                  weightedApyBps:
                    type: number
                    description: TVL-weighted average APY in basis points
                  weightedApyPct:
                    type: number
                    description: TVL-weighted average APY as percentage number (e.g. 8.50 = 8.50%)
                  totalTvl:
                    type: string
                  periodDays:
                    type: number
                  vaultCount:
                    type: number
                  decimals:
                    type: integer
                    description: Max decimals used for TVL normalization across vaults
  /v3/platform/stats/time-series:
    get:
      operationId: getPlatformTimeSeries
      summary: Get platform activity time-series
      tags:
        - Platform
      description: Platform-wide borrow/repay totals bucketed by period, with
        cumulative outstanding. Aggregate-only — no per-borrower data. No
        authentication required.
      parameters:
        - schema:
            type: string
            maxLength: 50
          in: query
          name: networkId
          required: false
          description: CAIP-2 network filter (e.g. "eip155:1")
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: startDate
          required: false
          description: Inclusive start date (YYYY-MM-DD)
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: endDate
          required: false
          description: Inclusive end date (YYYY-MM-DD)
        - schema:
            type: string
            enum:
              - monthly
              - daily
            default: monthly
          in: query
          name: granularity
          required: false
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - series
                properties:
                  series:
                    type: array
                    items:
                      type: object
                      required:
                        - period
                        - borrowUsd
                        - repayPrincipalUsd
                        - repayInterestUsd
                        - netOutstandingUsd
                        - cumulativeVolumeUsd
                      properties:
                        period:
                          type: string
                          description: "'YYYY-MM' (monthly) or 'YYYY-MM-DD' (daily)"
                        borrowUsd:
                          type: string
                          description: Total borrowed in USD this period.
                        repayPrincipalUsd:
                          type: string
                          description: Total principal repaid in USD this period.
                        repayInterestUsd:
                          type: string
                          description: Total interest repaid in USD this period.
                        netOutstandingUsd:
                          type: string
                          description: Cumulative outstanding principal in USD at end of period.
                        cumulativeVolumeUsd:
                          type: string
                          description: Cumulative total volume in USD (borrow + repaid principal +
                            interest) accumulated across the returned periods.
  /v3/platform/stats/tvl/time-series:
    get:
      operationId: getPlatformTvlTimeSeries
      summary: Get platform TVL time-series
      tags:
        - Platform
      description: Platform-wide TVL bucketed by period, from vault totalAssets()
        snapshots. Includes disabled vaults. Aggregate-only — no per-borrower
        data. No authentication required.
      parameters:
        - schema:
            type: string
            maxLength: 50
          in: query
          name: networkId
          required: false
          description: CAIP-2 network filter (e.g. "eip155:1")
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: startDate
          required: false
          description: Inclusive start date (YYYY-MM-DD). Defaults to a safe lookback
            window.
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: endDate
          required: false
          description: Inclusive end date (YYYY-MM-DD). Defaults to today (UTC).
        - schema:
            type: string
            enum:
              - monthly
              - daily
            default: monthly
          in: query
          name: granularity
          required: false
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - series
                properties:
                  series:
                    type: array
                    items:
                      type: object
                      required:
                        - period
                        - tvl
                      properties:
                        period:
                          type: string
                          description: "'YYYY-MM' (monthly) or 'YYYY-MM-DD' (daily)"
                        tvl:
                          type: string
                          description: Total value locked in USD at end of period.
  /v3/platform/stats/vault-apys/time-series:
    get:
      operationId: getPlatformVaultApysTimeSeries
      summary: Get platform weighted-APY time-series
      tags:
        - Platform
      description: Platform-wide TVL-weighted APY bucketed by period, from vault
        sharePrice()/totalAssets() snapshots. Includes disabled vaults.
        Aggregate-only — no per-borrower data. No authentication required.
      parameters:
        - schema:
            type: string
            maxLength: 50
          in: query
          name: networkId
          required: false
          description: CAIP-2 network filter (e.g. "eip155:1")
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: startDate
          required: false
          description: Inclusive start date (YYYY-MM-DD). Defaults to a safe lookback
            window.
        - schema:
            type: string
            format: date
            pattern: ^\d{4}-\d{2}-\d{2}$
          in: query
          name: endDate
          required: false
          description: Inclusive end date (YYYY-MM-DD). Defaults to today (UTC).
        - schema:
            type: string
            enum:
              - monthly
              - daily
            default: monthly
          in: query
          name: granularity
          required: false
        - schema:
            type: integer
            default: 30
            minimum: 1
            maximum: 366
          in: query
          name: period
          required: false
          description: Trailing APY lookback window in days (independent of granularity).
            Default 30, max 366.
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - series
                properties:
                  series:
                    type: array
                    items:
                      type: object
                      required:
                        - period
                        - weightedApyBps
                        - weightedApyPct
                        - totalTvl
                        - decimals
                        - vaultCount
                      properties:
                        period:
                          type: string
                          description: "'YYYY-MM' (monthly) or 'YYYY-MM-DD' (daily)"
                        weightedApyBps:
                          type:
                            - "null"
                            - number
                          description: TVL-weighted APY in basis points; null when no vault has enough
                            history in the bucket.
                        weightedApyPct:
                          type:
                            - "null"
                            - number
                          description: TVL-weighted APY as percentage number (e.g. 8.50 = 8.50%); null
                            mirrors weightedApyBps.
                        totalTvl:
                          type: string
                          description: Total weight (scaled totalAssets) used for the bucket.
                        decimals:
                          type: integer
                          description: Max decimals used to normalize the bucket TVL weights.
                        vaultCount:
                          type: integer
                          description: Vaults that contributed APY + weight to the bucket.
  /v3/api-keys:
    post:
      operationId: createApiKey
      summary: Create API key
      tags:
        - API Keys
      description: Create a new API key for the specified organization. The key
        authenticates requests as a member of that organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organizationId:
                  type: string
                  format: uuid
                  description: "The organization this API key belongs to. Requests authenticated
                    with this key will be made as a member of this organization.
                    Example: 550e8400-e29b-41d4-a716-446655440000"
                name:
                  type: string
                  maxLength: 255
                  description: Name for the API key
                expiresInDays:
                  type: number
                  description: Number of days until the key expires
              required:
                - organizationId
                - name
      security: &a2
        - ApiKeyAuth: []
        - BearerAuth: []
        - OAuth2: []
      responses:
        "201":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - organizationId
                  - keyPrefix
                  - name
                  - fullKey
                  - createdAt
                  - message
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 550e8400-e29b-41d4-a716-446655440000
                  organizationId:
                    type: string
                    format: uuid
                    example: 550e8400-e29b-41d4-a716-446655440000
                  keyPrefix:
                    type: string
                    example: cc_abc123
                  name:
                    type: string
                  fullKey:
                    type: string
                    description: Full API key. Only returned once at creation — save it immediately.
                  expiresAt:
                    type: string
                    format: date-time
                    nullable: true
                    example: 2025-01-15T10:30:00Z
                  createdAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  message:
                    type: string
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
    get:
      operationId: listApiKeys
      summary: List API keys
      tags:
        - API Keys
      description: List all API keys scoped to the specified organization.
      parameters:
        - schema:
            type: string
            format: uuid
          in: query
          name: organizationId
          required: true
          description: "Organization ID — only keys belonging to this organization are
            returned. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - keys
                properties:
                  keys:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - keyPrefix
                        - name
                        - createdAt
                        - updatedAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        keyPrefix:
                          type: string
                          example: cc_abc123
                        name:
                          type: string
                        lastUsedAt:
                          type: string
                          format: date-time
                          nullable: true
                          example: 2025-01-15T10:30:00Z
                        expiresAt:
                          type: string
                          format: date-time
                          nullable: true
                          example: 2025-01-15T10:30:00Z
                        revokedAt:
                          type: string
                          format: date-time
                          nullable: true
                          example: 2025-01-15T10:30:00Z
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        updatedAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/api-keys/{apiKeyId}:
    delete:
      operationId: revokeApiKey
      summary: Revoke an API key
      tags:
        - API Keys
      description: Revoke an API key. The organization is derived from the key itself.
      security: *a2
      parameters:
        - schema:
            type: string
          in: path
          name: apiKeyId
          required: true
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/ledger/borrows:
    get:
      operationId: listBorrows
      summary: List credit facility borrow events
      tags:
        - Ledger
      description: |-
        Get on-chain borrow events for an organization. Each row represents a single `Borrow` event emitted by a SecuredLine credit facility — the moment outstanding principal was drawn against the line.

        Results are sorted by `occurredAt` (descending — newest first). Ordering is not configurable from the query string.

        Supports three response formats via the `format` query parameter:
        - **json** (default) — paginated JSON (default limit 100, max 1000).
        - **csv** — streamed CSV file download (up to 1,000,000 rows). Columns: inflow, transaction, type, timestamp, amount, usdValue, tokenAddress, tokenIcon, tokenSymbol.
        - **event-stream** — Server-Sent Events stream (up to 1,000,000 rows). Each entry is emitted as a named `entry` event with JSON data. A final `done` event carries `{"total": N}`. Connect with `EventSource` or `fetch`:

        ```js
        const es = new EventSource('/v3/ledger/borrows?organizationId={id}&format=event-stream', {
          headers: { 'x-api-key': 'cc_...' },
        });
        es.addEventListener('entry', (e) => console.log(JSON.parse(e.data)));
        es.addEventListener('done', (e) => { console.log('total:', JSON.parse(e.data).total); es.close(); });
        ```

        Requires org membership or vault curator role (public orgs only).
      parameters:
        - schema:
            type: string
            format: uuid
            maxLength: 36
            example: 550e8400-e29b-41d4-a716-446655440000
          in: query
          name: organizationId
          required: true
          description: Organization ID (must be an org the caller is a member of, or a
            public org if caller is a vault curator).
        - schema:
            type: string
            format: date
            example: 2025-01-15
          in: query
          name: startDate
          required: false
          description: Optional filter. Inclusive start date (YYYY-MM-DD); restricts
            results to `occurredAt >= startDate` (or `snapshotDate` for
            collateral-snapshots). Omit to leave the start unbounded.
        - schema:
            type: string
            format: date
            example: 2025-01-31
          in: query
          name: endDate
          required: false
          description: Optional filter. Inclusive end date (YYYY-MM-DD). Omit to leave the
            end unbounded.
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum records returned. Format-dependent: `format=json` capped
            at 1000 (default 100); `format=csv|event-stream` capped at 1,000,000
            (default 1,000,000). Values outside these caps are silently clamped
            server-side."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
          description: Number of records to skip from the start (JSON pagination only —
            ignored for csv/event-stream).
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. `json` returns paginated JSON. `csv` streams a
            CSV file download. `event-stream` returns Server-Sent Events: each
            row is a named `entry` event; a final `done` event carries
            `{"total": N}`.'
        - schema:
            type: string
            maxLength: 50
            example: eip155:1
          in: query
          name: networkId
          required: false
          description: Optional filter. CAIP-2 network identifier; restricts results to a
            single chain. Omit to return all networks.
        - schema:
            type: string
            maxLength: 42
            pattern: ^0x[0-9a-fA-F]{40}$
            example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
          in: query
          name: facilityAddress
          required: false
          description: Optional filter. Credit facility (SecuredLine) contract address;
            restricts results to a single facility. Omit to return all
            facilities for the organization.
      security: *a2
      responses:
        "200":
          description: Credit facility borrow events.
          content:
            application/json:
              schema:
                type: object
                required:
                  - entries
                  - pagination
                properties:
                  entries:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - evmLogId
                        - facilityAddress
                        - amount
                        - currency
                        - occurredAt
                        - dataSource
                        - networkId
                        - transactionHash
                        - logIndex
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        evmLogId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        facilityAddress:
                          type: string
                          maxLength: 42
                          pattern: ^0x[0-9a-fA-F]{40}$
                          description: Credit facility (SecuredLine) contract address.
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        amount:
                          type: string
                          description: Token amount with full decimal precision. Returned as a string to
                            avoid floating-point precision loss.
                        amountUsd:
                          type: string
                          nullable: true
                          description: USD value at time of entry. Returned as a string. May be `null`
                            when no historical price is available for the
                            currency.
                          example: "1234567.890000"
                        currency:
                          type: string
                          description: Token symbol stored verbatim from source.
                        occurredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        dataSource:
                          type: string
                          description: Origin of the data, e.g. `blockchain:ethereum`, `blockchain:base`.
                        networkId:
                          type: string
                          description: CAIP-2 network identifier.
                          example: eip155:1
                        transactionHash:
                          type: string
                          description: 0x-prefixed transaction hash.
                        logIndex:
                          type: integer
                          description: Position of the log within the transaction.
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        organizationName:
                          type: string
                          nullable: true
                          description: Display name of the owning organization.
                        organizationSlug:
                          type: string
                          nullable: true
                          description: URL-safe slug of the owning organization.
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: inflow, transaction, type, timestamp,
                  amount, usdValue, tokenAddress, tokenIcon, tokenSymbol."
            text/event-stream:
              schema:
                type: string
                description: 'SSE stream. Named `entry` events carry one row each; a final
                  `done` event carries `{"total": N}`.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/ledger/repays:
    get:
      operationId: listRepays
      summary: List credit facility repayment events
      tags:
        - Ledger
      description: >-
        Get on-chain repayment events for an organization. Each row represents a
        `RepayPrincipal` or `RepayInterest` event emitted by a SecuredLine
        credit facility. Filter by `repaymentType` to restrict to one subtype.


        Results are sorted by `occurredAt` (descending — newest first). Ordering
        is not configurable from the query string.


        Supports three response formats via the `format` query parameter:

        - **json** (default) — paginated JSON (default limit 100, max 1000).

        - **csv** — streamed CSV file download (up to 1,000,000 rows). Columns:
        inflow, transaction, type, timestamp, amount, usdValue, tokenAddress,
        tokenIcon, tokenSymbol.

        - **event-stream** — Server-Sent Events stream (up to 1,000,000 rows).
        Each entry is emitted as a named `entry` event with JSON data. A final
        `done` event carries `{"total": N}`. Connect with `EventSource` or
        `fetch`:


        ```js

        const es = new
        EventSource('/v3/ledger/repays?organizationId={id}&format=event-stream',
        {
          headers: { 'x-api-key': 'cc_...' },
        });

        es.addEventListener('entry', (e) => console.log(JSON.parse(e.data)));

        es.addEventListener('done', (e) => { console.log('total:',
        JSON.parse(e.data).total); es.close(); });

        ```


        Requires org membership or vault curator role (public orgs only).
      parameters:
        - schema:
            type: string
            format: uuid
            maxLength: 36
            example: 550e8400-e29b-41d4-a716-446655440000
          in: query
          name: organizationId
          required: true
          description: Organization ID (must be an org the caller is a member of, or a
            public org if caller is a vault curator).
        - schema:
            type: string
            format: date
            example: 2025-01-15
          in: query
          name: startDate
          required: false
          description: Optional filter. Inclusive start date (YYYY-MM-DD); restricts
            results to `occurredAt >= startDate` (or `snapshotDate` for
            collateral-snapshots). Omit to leave the start unbounded.
        - schema:
            type: string
            format: date
            example: 2025-01-31
          in: query
          name: endDate
          required: false
          description: Optional filter. Inclusive end date (YYYY-MM-DD). Omit to leave the
            end unbounded.
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum records returned. Format-dependent: `format=json` capped
            at 1000 (default 100); `format=csv|event-stream` capped at 1,000,000
            (default 1,000,000). Values outside these caps are silently clamped
            server-side."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
          description: Number of records to skip from the start (JSON pagination only —
            ignored for csv/event-stream).
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. `json` returns paginated JSON. `csv` streams a
            CSV file download. `event-stream` returns Server-Sent Events: each
            row is a named `entry` event; a final `done` event carries
            `{"total": N}`.'
        - schema:
            type: string
            enum:
              - principal
              - interest
          in: query
          name: repaymentType
          required: false
          description: "Optional filter. Restricts results to a single repayment subtype:
            `principal` (reduces outstanding principal) or `interest` (paid to
            depositors). Omit to return both."
        - schema:
            type: string
            maxLength: 50
            example: eip155:1
          in: query
          name: networkId
          required: false
          description: Optional filter. CAIP-2 network identifier; restricts results to a
            single chain. Omit to return all networks.
        - schema:
            type: string
            maxLength: 42
            pattern: ^0x[0-9a-fA-F]{40}$
            example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
          in: query
          name: facilityAddress
          required: false
          description: Optional filter. Credit facility (SecuredLine) contract address;
            restricts results to a single facility. Omit to return all
            facilities for the organization.
      security: *a2
      responses:
        "200":
          description: Credit facility repayment events.
          content:
            application/json:
              schema:
                type: object
                required:
                  - entries
                  - pagination
                properties:
                  entries:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - evmLogId
                        - repaymentType
                        - facilityAddress
                        - amount
                        - currency
                        - occurredAt
                        - dataSource
                        - networkId
                        - transactionHash
                        - logIndex
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        evmLogId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        repaymentType:
                          type: string
                          enum:
                            - principal
                            - interest
                          description: "Repayment subtype: `principal` reduces outstanding principal;
                            `interest` is paid to depositors."
                        facilityAddress:
                          type: string
                          maxLength: 42
                          pattern: ^0x[0-9a-fA-F]{40}$
                          description: Credit facility (SecuredLine) contract address.
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        amount:
                          type: string
                          description: Token amount with full decimal precision. Returned as a string to
                            avoid floating-point precision loss.
                        amountUsd:
                          type: string
                          nullable: true
                          description: USD value at time of entry. Returned as a string. May be `null`
                            when no historical price is available for the
                            currency.
                          example: "1234567.890000"
                        currency:
                          type: string
                        occurredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        dataSource:
                          type: string
                        networkId:
                          type: string
                          example: eip155:1
                        transactionHash:
                          type: string
                        logIndex:
                          type: integer
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        organizationName:
                          type: string
                          nullable: true
                          description: Display name of the owning organization.
                        organizationSlug:
                          type: string
                          nullable: true
                          description: URL-safe slug of the owning organization.
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: inflow, transaction, type, timestamp,
                  amount, usdValue, tokenAddress, tokenIcon, tokenSymbol."
            text/event-stream:
              schema:
                type: string
                description: 'SSE stream. Named `entry` events carry one row each; a final
                  `done` event carries `{"total": N}`.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/ledger/transfers:
    get:
      operationId: listCashflowTransfers
      summary: List individual cashflow transfer events
      tags:
        - Ledger
      description: |-
        Get individual cashflow transfer events for an organization. Each row is a single movement of value (on-chain `Transfer`, off-chain wire/ACH, swap leg, etc.) classified by stage (`external` → `in_transit` → `secured` → `settled`) and direction (inflow / outflow). Set `excludeLinkedTransfers=true` to drop transfers whose tx hash matches a known borrow/repay and avoid double-counting against `/v3/ledger/borrows` and `/v3/ledger/repays`.

        Results are sorted by `occurredAt` (descending — newest first). Ordering is not configurable from the query string.

        Supports three response formats via the `format` query parameter:
        - **json** (default) — paginated JSON (default limit 100, max 1000).
        - **csv** — streamed CSV file download (up to 1,000,000 rows). Columns: inflow, transaction, type, timestamp, amount, usdValue, tokenAddress, tokenIcon, tokenSymbol.
        - **event-stream** — Server-Sent Events stream (up to 1,000,000 rows). Each entry is emitted as a named `entry` event with JSON data. A final `done` event carries `{"total": N}`. Connect with `EventSource` or `fetch`:

        ```js
        const es = new EventSource('/v3/ledger/transfers?organizationId={id}&format=event-stream', {
          headers: { 'x-api-key': 'cc_...' },
        });
        es.addEventListener('entry', (e) => console.log(JSON.parse(e.data)));
        es.addEventListener('done', (e) => { console.log('total:', JSON.parse(e.data).total); es.close(); });
        ```

        Requires org membership or vault curator role (public orgs only).
      parameters:
        - schema:
            type: string
            format: uuid
            maxLength: 36
            example: 550e8400-e29b-41d4-a716-446655440000
          in: query
          name: organizationId
          required: true
          description: Organization ID (must be an org the caller is a member of, or a
            public org if caller is a vault curator).
        - schema:
            type: string
            format: date
            example: 2025-01-15
          in: query
          name: startDate
          required: false
          description: Optional filter. Inclusive start date (YYYY-MM-DD); restricts
            results to `occurredAt >= startDate` (or `snapshotDate` for
            collateral-snapshots). Omit to leave the start unbounded.
        - schema:
            type: string
            format: date
            example: 2025-01-31
          in: query
          name: endDate
          required: false
          description: Optional filter. Inclusive end date (YYYY-MM-DD). Omit to leave the
            end unbounded.
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum records returned. Format-dependent: `format=json` capped
            at 1000 (default 100); `format=csv|event-stream` capped at 1,000,000
            (default 1,000,000). Values outside these caps are silently clamped
            server-side."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
          description: Number of records to skip from the start (JSON pagination only —
            ignored for csv/event-stream).
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. `json` returns paginated JSON. `csv` streams a
            CSV file download. `event-stream` returns Server-Sent Events: each
            row is a named `entry` event; a final `done` event carries
            `{"total": N}`.'
        - schema:
            type: string
            maxLength: 50
            example: eip155:1
          in: query
          name: networkId
          required: false
          description: Optional filter. CAIP-2 network identifier; restricts results to a
            single chain. Omit to return all networks.
        - schema:
            type: string
            maxLength: 255
          in: query
          name: accountId
          required: false
          description: Optional filter. Wallet address (on-chain) or bank account
            identifier (off-chain); restricts results to a single account. Omit
            to return all accounts.
        - schema:
            type: string
            enum:
              - external
              - in_transit
              - secured
              - settled
          in: query
          name: stage
          required: false
          description: Optional filter. Cash-flow stage (`external` → `in_transit` →
            `secured` → `settled`); restricts results to a single stage. Omit to
            return all stages.
        - schema:
            type: string
            maxLength: 20
          in: query
          name: type
          required: false
          description: "Optional filter. Transfer mechanism; restricts results to a single
            mechanism (common values: `swap`, `bridge`, `onramp`, `wire`, `ach`,
            `direct`). Omit to return all mechanisms."
        - schema:
            type: boolean
          in: query
          name: inflow
          required: false
          description: Optional filter. `true` = arriving only, `false` = leaving only.
            Omit to return both directions.
        - schema:
            type: boolean
            default: false
          in: query
          name: excludeLinkedTransfers
          required: false
          description: Optional. When `true`, excludes transfers whose tx hash matches a
            known borrow/repay event, to avoid double-counting with
            /v3/ledger/borrows and /v3/ledger/repays. Defaults to `false`.
      security: *a2
      responses:
        "200":
          description: Individual cashflow transfer events.
          content:
            application/json:
              schema:
                type: object
                required:
                  - entries
                  - pagination
                properties:
                  entries:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - inflow
                        - stage
                        - accountId
                        - amount
                        - currency
                        - occurredAt
                        - dataSource
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        webCaptureId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                          nullable: true
                        evmLogId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                          nullable: true
                        inflow:
                          type: boolean
                          description: true = arriving, false = leaving.
                        stage:
                          type: string
                          enum:
                            - external
                            - in_transit
                            - secured
                            - settled
                          description: Cash-flow stage at time of capture (`external` → `in_transit` →
                            `secured` → `settled`).
                        type:
                          type: string
                          nullable: true
                          description: "Transfer mechanism (common values: `swap`, `bridge`, `onramp`,
                            `wire`, `ach`, `direct`)."
                        accountId:
                          type: string
                          description: Wallet address (on-chain) or bank account identifier (off-chain).
                        institutionId:
                          type: string
                          nullable: true
                          description: Source institution that reported this transfer (e.g. `self_report`,
                            `visa`).
                        externalTransactionId:
                          type: string
                          nullable: true
                          description: Source-system identifier for the transaction.
                        amount:
                          type: string
                          description: Token amount with full decimal precision. Returned as a string to
                            avoid floating-point precision loss.
                        amountUsd:
                          type: string
                          nullable: true
                          description: USD value at time of entry. Returned as a string. May be `null`
                            when no historical price is available for the
                            currency.
                          example: "1234567.890000"
                        currency:
                          type: string
                        occurredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        dataSource:
                          type: string
                        networkId:
                          type: string
                          nullable: true
                          example: eip155:1
                        transactionHash:
                          type: string
                          nullable: true
                        logIndex:
                          type: integer
                          nullable: true
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        organizationName:
                          type: string
                          nullable: true
                          description: Display name of the owning organization.
                        organizationSlug:
                          type: string
                          nullable: true
                          description: URL-safe slug of the owning organization.
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: inflow, transaction, type, timestamp,
                  amount, usdValue, tokenAddress, tokenIcon, tokenSymbol."
            text/event-stream:
              schema:
                type: string
                description: 'SSE stream. Named `entry` events carry one row each; a final
                  `done` event carries `{"total": N}`.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/ledger/cumulative-cashflows:
    get:
      operationId: listCumulativeCashflows
      summary: List aggregate daily cashflow snapshots
      tags:
        - Ledger
      description: |-
        Get daily aggregate cashflow snapshots reported by an institution (e.g. `self_report`, `visa`) on behalf of an organization. Unlike `/v3/ledger/transfers`, each row is a *period summary* — typically one row per (institution, day, direction) — not an individual transaction. Use this endpoint when you want pre-aggregated totals; use `/v3/ledger/transfers` for line-item activity.

        Results are sorted by `occurredAt` (descending — newest first). Ordering is not configurable from the query string.

        Supports three response formats via the `format` query parameter:
        - **json** (default) — paginated JSON (default limit 100, max 1000).
        - **csv** — streamed CSV file download (up to 1,000,000 rows). Columns: inflow, transaction, type, timestamp, amount, usdValue, tokenAddress, tokenIcon, tokenSymbol.
        - **event-stream** — Server-Sent Events stream (up to 1,000,000 rows). Each entry is emitted as a named `entry` event with JSON data. A final `done` event carries `{"total": N}`. Connect with `EventSource` or `fetch`:

        ```js
        const es = new EventSource('/v3/ledger/cumulative-cashflows?organizationId={id}&format=event-stream', {
          headers: { 'x-api-key': 'cc_...' },
        });
        es.addEventListener('entry', (e) => console.log(JSON.parse(e.data)));
        es.addEventListener('done', (e) => { console.log('total:', JSON.parse(e.data).total); es.close(); });
        ```

        Requires org membership or vault curator role (public orgs only).
      parameters:
        - schema:
            type: string
            format: uuid
            maxLength: 36
            example: 550e8400-e29b-41d4-a716-446655440000
          in: query
          name: organizationId
          required: true
          description: Organization ID (must be an org the caller is a member of, or a
            public org if caller is a vault curator).
        - schema:
            type: string
            format: date
            example: 2025-01-15
          in: query
          name: startDate
          required: false
          description: Optional filter. Inclusive start date (YYYY-MM-DD); restricts
            results to `occurredAt >= startDate` (or `snapshotDate` for
            collateral-snapshots). Omit to leave the start unbounded.
        - schema:
            type: string
            format: date
            example: 2025-01-31
          in: query
          name: endDate
          required: false
          description: Optional filter. Inclusive end date (YYYY-MM-DD). Omit to leave the
            end unbounded.
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum records returned. Format-dependent: `format=json` capped
            at 1000 (default 100); `format=csv|event-stream` capped at 1,000,000
            (default 1,000,000). Values outside these caps are silently clamped
            server-side."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
          description: Number of records to skip from the start (JSON pagination only —
            ignored for csv/event-stream).
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. `json` returns paginated JSON. `csv` streams a
            CSV file download. `event-stream` returns Server-Sent Events: each
            row is a named `entry` event; a final `done` event carries
            `{"total": N}`.'
        - schema:
            type: string
            maxLength: 100
            example: self_report
          in: query
          name: institutionId
          required: false
          description: Optional filter. Source institution that reported the aggregate
            (e.g. `self_report`, `visa`); restricts results to a single
            institution. Omit to return all institutions.
        - schema:
            type: string
            enum:
              - external
              - in_transit
              - secured
              - settled
          in: query
          name: stage
          required: false
          description: Optional filter. Cash-flow stage (`external` → `in_transit` →
            `secured` → `settled`); restricts results to a single stage. Omit to
            return all stages.
        - schema:
            type: boolean
          in: query
          name: inflow
          required: false
          description: Optional filter. `true` = arriving only, `false` = leaving only.
            Omit to return both directions.
      security: *a2
      responses:
        "200":
          description: Aggregate daily cashflow snapshots.
          content:
            application/json:
              schema:
                type: object
                required:
                  - entries
                  - pagination
                properties:
                  entries:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - webCaptureId
                        - inflow
                        - stage
                        - institutionId
                        - externalTransactionId
                        - amount
                        - currency
                        - occurredAt
                        - dataSource
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        webCaptureId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        inflow:
                          type: boolean
                        stage:
                          type: string
                          enum:
                            - external
                            - in_transit
                            - secured
                            - settled
                          description: Cash-flow stage at time of capture (`external` → `in_transit` →
                            `secured` → `settled`).
                        accountId:
                          type: string
                          nullable: true
                        institutionId:
                          type: string
                          description: Source institution that reported this aggregate (e.g.
                            `self_report`, `visa`).
                        externalTransactionId:
                          type: string
                          description: Source-system identifier for the aggregate.
                        amount:
                          type: string
                          description: Token amount with full decimal precision. Returned as a string to
                            avoid floating-point precision loss.
                        amountUsd:
                          type: string
                          nullable: true
                          description: USD value at time of entry. Returned as a string. May be `null`
                            when no historical price is available for the
                            currency.
                          example: "1234567.890000"
                        currency:
                          type: string
                        occurredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        dataSource:
                          type: string
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        organizationName:
                          type: string
                          nullable: true
                          description: Display name of the owning organization.
                        organizationSlug:
                          type: string
                          nullable: true
                          description: URL-safe slug of the owning organization.
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: inflow, transaction, type, timestamp,
                  amount, usdValue, tokenAddress, tokenIcon, tokenSymbol."
            text/event-stream:
              schema:
                type: string
                description: 'SSE stream. Named `entry` events carry one row each; a final
                  `done` event carries `{"total": N}`.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/ledger/cumulative-collateral:
    get:
      operationId: listCumulativeCollateral
      summary: List point-in-time collateral USD snapshots
      tags:
        - Ledger
      description: |-
        Get daily collateral USD snapshots for an organization. Each row is the total USD value of collateral held on a given calendar day — one row per organization per day. Use this for time-series collateral charts and coverage ratios; combine with `/v3/ledger/borrows` + `/v3/ledger/repays` to compute net leverage over time.

        Results are sorted by `snapshotDate` (descending — newest first). Ordering is not configurable from the query string.

        Supports three response formats via the `format` query parameter:
        - **json** (default) — paginated JSON (default limit 100, max 1000).
        - **csv** — streamed CSV file download (up to 1,000,000 rows). Columns: snapshotDate, amountUsd, organizationId, organizationName, createdAt.
        - **event-stream** — Server-Sent Events stream (up to 1,000,000 rows). Each entry is emitted as a named `entry` event with JSON data. A final `done` event carries `{"total": N}`. Connect with `EventSource` or `fetch`:

        ```js
        const es = new EventSource('/v3/ledger/cumulative-collateral?organizationId={id}&format=event-stream', {
          headers: { 'x-api-key': 'cc_...' },
        });
        es.addEventListener('entry', (e) => console.log(JSON.parse(e.data)));
        es.addEventListener('done', (e) => { console.log('total:', JSON.parse(e.data).total); es.close(); });
        ```

        Requires org membership or vault curator role (public orgs only).
      parameters:
        - schema:
            type: string
            format: uuid
            maxLength: 36
            example: 550e8400-e29b-41d4-a716-446655440000
          in: query
          name: organizationId
          required: true
          description: Organization ID (must be an org the caller is a member of, or a
            public org if caller is a vault curator).
        - schema:
            type: string
            format: date
            example: 2025-01-15
          in: query
          name: startDate
          required: false
          description: Optional filter. Inclusive start date (YYYY-MM-DD); restricts
            results to `occurredAt >= startDate` (or `snapshotDate` for
            collateral-snapshots). Omit to leave the start unbounded.
        - schema:
            type: string
            format: date
            example: 2025-01-31
          in: query
          name: endDate
          required: false
          description: Optional filter. Inclusive end date (YYYY-MM-DD). Omit to leave the
            end unbounded.
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum records returned. Format-dependent: `format=json` capped
            at 1000 (default 100); `format=csv|event-stream` capped at 1,000,000
            (default 1,000,000). Values outside these caps are silently clamped
            server-side."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
          description: Number of records to skip from the start (JSON pagination only —
            ignored for csv/event-stream).
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. `json` returns paginated JSON. `csv` streams a
            CSV file download. `event-stream` returns Server-Sent Events: each
            row is a named `entry` event; a final `done` event carries
            `{"total": N}`.'
      security: *a2
      responses:
        "200":
          description: Point-in-time collateral USD snapshots (one row per org per day).
          content:
            application/json:
              schema:
                type: object
                required:
                  - entries
                  - pagination
                properties:
                  entries:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - organizationId
                        - webCaptureId
                        - amountUsd
                        - snapshotDate
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        organizationName:
                          type: string
                          nullable: true
                        webCaptureId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        amountUsd:
                          type: string
                          description: USD value (6 fractional digits). Returned as a string to avoid
                            floating-point precision loss.
                          example: "1234567.890000"
                        snapshotDate:
                          type: string
                          format: date
                          example: 2025-01-15
                        createdAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: snapshotDate, amountUsd,
                  organizationId, organizationName, createdAt."
            text/event-stream:
              schema:
                type: string
                description: 'SSE stream. Named `entry` events carry one row each; a final
                  `done` event carries `{"total": N}`.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/self-report/cashflows:
    post:
      operationId: submitSelfReportCashflows
      summary: Submit self-reported cashflows
      tags:
        - Self Report
      description: >-
        Submit cashflow items for the authenticated organization. Each entry in
        `items` takes one of three shapes, selected by its `type` field:


        - `transaction` — an individual transaction with a precise `datetime`
        and a required `externalId` for deduplication.

        - `aggregate` — a daily total for a `date` (zero allowed for no-activity
        days).

        - `collateral` — a cumulative collateral snapshot for a `date`.


        Items flow through the standard capture → normalize pipeline.
        Transactions and aggregates become ledger entries; collateral snapshots
        are stored in the dedicated collateral_snapshots table.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  type: array
                  minItems: 1
                  items:
                    description: "A single cashflow item. Its shape is selected by the `type` field:
                      transaction, aggregate, or collateral."
                    oneOf:
                      - title: Transaction
                        description: Individual transaction (type=transaction). Requires a precise
                          datetime and an externalId for deduplication.
                        type: object
                        required:
                          - type
                          - amount
                          - currency
                          - datetime
                          - direction
                          - externalId
                        properties:
                          type:
                            type: string
                            enum:
                              - transaction
                          amount:
                            type: number
                            exclusiveMinimum: 0
                            description: Transaction amount (positive)
                          currency:
                            type: string
                            minLength: 1
                            maxLength: 20
                            description: Currency code (stored as-is)
                          datetime:
                            type: string
                            format: date-time
                            description: ISO 8601 datetime (e.g. 2026-03-01T14:30:00Z)
                          direction:
                            type: string
                            enum:
                              - inflow
                              - outflow
                            description: Cashflow direction
                          externalId:
                            type: string
                            minLength: 1
                            maxLength: 255
                            description: Customer transaction ID (required for deduplication)
                          category:
                            type: string
                            maxLength: 100
                      - title: Aggregate
                        description: Daily aggregate total (type=aggregate). Zero allowed for
                          no-activity days.
                        type: object
                        required:
                          - type
                          - amount
                          - currency
                          - date
                          - direction
                        properties:
                          type:
                            type: string
                            enum:
                              - aggregate
                          amount:
                            type: number
                            minimum: 0
                            description: Aggregate amount (zero allowed for no-activity days)
                          currency:
                            type: string
                            minLength: 1
                            maxLength: 20
                            description: Currency code (stored as-is)
                          date:
                            type: string
                            format: date
                            description: ISO 8601 date (YYYY-MM-DD)
                          direction:
                            type: string
                            enum:
                              - inflow
                              - outflow
                            description: Cashflow direction
                          category:
                            type: string
                            maxLength: 100
                      - title: Collateral
                        description: Cumulative collateral snapshot (type=collateral).
                        type: object
                        required:
                          - type
                          - amount
                          - currency
                          - date
                        properties:
                          type:
                            type: string
                            enum:
                              - collateral
                          amount:
                            type: number
                            minimum: 0
                            description: Cumulative collateral amount (zero allowed)
                          currency:
                            type: string
                            minLength: 1
                            maxLength: 20
                            description: Currency code (stored as-is)
                          date:
                            type: string
                            format: date
                            description: Snapshot date (YYYY-MM-DD)
                          category:
                            type: string
                            maxLength: 100
              additionalProperties: false
      security:
        - ApiKeyAuth: []
      responses:
        "202":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - message
                  - captureId
                  - jobId
                  - itemCount
                properties:
                  message:
                    type: string
                  captureId:
                    type: string
                    format: uuid
                  jobId:
                    type: string
                  itemCount:
                    type: integer
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults:
    get:
      operationId: listVaults
      summary: List vaults
      tags:
        - Vaults
      description: "List enabled vaults with organization info. Authentication is
        optional but affects results: unauthenticated requests only see vaults
        with public organizations, authenticated users see vaults with public
        orgs plus private orgs they have access to."
      parameters:
        - schema:
            type: string
            maxLength: 36
            format: uuid
          in: query
          name: organizationId
          required: false
          description: "Filter by vault curator organization ID. Example:
            550e8400-e29b-41d4-a716-446655440000"
        - schema:
            type: string
            maxLength: 100
          in: query
          name: address
          required: false
          description: "Filter by vault address. Case-insensitive when networkId is
            omitted or is an EVM chain (eip155:*), case-sensitive otherwise.
            Example: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 50
          in: query
          name: networkId
          required: false
          description: Filter by network ID (CAIP-2 blockchain ID), e.g., `eip155:1`
            (Ethereum), `eip155:137` (Polygon),
            `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` (Solana)
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          in: query
          name: limit
          required: false
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - assets
                - organization
                - apy
                - fees
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (fetches on-chain addresses: creditStrategy,
            liquidStrategy, vaultCurator), "assets" (fetches asset info:
            assetToken, shareToken, decimals, totalAssets, totalLiquidAssets,
            totalSupply, sharePrice, baseUnit, totalActiveCredit,
            uninvestedCreditAssets), "organization" (includes full organization
            object with links), "apy" (fetches 30-day APY from historical
            sharePrice snapshots), "fees" (fetches managementFee and
            performanceFee from creditStrategy in basis points).'
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaults
                  - pagination
                properties:
                  vaults:
                    type: array
                    items:
                      $ref: "#/components/schemas/Vault"
                  pagination:
                    $ref: "#/components/schemas/Pagination"
  /v3/vaults/{id}:
    get:
      operationId: getVault
      summary: Get vault by ID
      tags:
        - Vaults
      description: Get a single vault by ID with organization info. Authentication is
        optional but required to view vaults with private organizations. Vaults
        with public organizations are visible to everyone.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - assets
                - organization
                - apy
                - fees
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (fetches on-chain addresses: creditStrategy,
            liquidStrategy, vaultCurator), "assets" (fetches asset info:
            assetToken, shareToken, decimals, totalAssets, totalLiquidAssets,
            totalSupply, sharePrice, baseUnit, totalActiveCredit,
            uninvestedCreditAssets), "organization" (includes full organization
            object with links), "apy" (fetches 30-day APY from historical
            sharePrice snapshots), "fees" (fetches managementFee and
            performanceFee from creditStrategy in basis points).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Vault"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/logs:
    get:
      operationId: getVaultLogs
      summary: Get vault event logs
      tags:
        - Vaults
      description: >-
        Get on-chain event logs for a vault.


        Supports three response formats via the `format` query parameter:

        - **json** (default) — paginated JSON (default limit 20, max 1000).

        - **csv** — streamed CSV file download (up to 1 000 000 rows).

        - **event-stream** — Server-Sent Events stream (up to 1 000 000 rows).
        Each log is emitted as a named `log` event with JSON data. A final
        `done` event carries `{"total": N}`. Connect with `EventSource` or
        `fetch`:


        ```js

        const es = new EventSource('/v3/vaults/{id}/logs?format=event-stream');

        es.addEventListener('log', (e) => console.log(JSON.parse(e.data)));

        es.addEventListener('done', (e) => { console.log('total:',
        JSON.parse(e.data).total); es.close(); });

        ```


        Authentication is optional but required for vaults with private
        organizations. Returns events from the vault contract, its credit
        strategy, and liquid strategy, ordered by most recent first.


        Event types: AddCredit, CancelDepositRequest, CancelRedeemRequest,
        Deposit, DepositRequest, IncreaseCredit, ManagerDeposit,
        ManagerWithdraw, MintManagementShares, MintPerformanceShares,
        ProcessDepositRequest, ProcessRedeemRequest, RedeemRequest, SetFee,
        SetManager, StrategyDeposit, StrategyWithdraw,
        SwapCreditPositionForTokens, VaultDeposit, VaultWithdraw, Withdraw,
        WithdrawDeposit, WithdrawProfit.
      parameters:
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. "json" returns paginated JSON (default 20, max
            1000). "csv" returns a streamed CSV file download. "event-stream"
            returns Server-Sent Events with each log as a named "log" event and
            a final "done" event. Event types: AddCredit, CancelDepositRequest,
            CancelRedeemRequest, Deposit, DepositRequest, IncreaseCredit,
            ManagerDeposit, ManagerWithdraw, MintManagementShares,
            MintPerformanceShares, ProcessDepositRequest, ProcessRedeemRequest,
            RedeemRequest, SetFee, SetManager, StrategyDeposit,
            StrategyWithdraw, SwapCreditPositionForTokens, VaultDeposit,
            VaultWithdraw, Withdraw, WithdrawDeposit, WithdrawProfit.'
        - schema:
            type: string
            format: date
          in: query
          name: startDate
          required: false
          description: "Start date (YYYY-MM-DD). Example: 2025-01-15"
        - schema:
            type: string
            format: date
          in: query
          name: endDate
          required: false
          description: "End date, inclusive (YYYY-MM-DD). Example: 2025-01-15"
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum number of results. For json: default 20, max 1000. For
            csv/event-stream: default 1000000, max 1000000."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Vault event logs. Response format depends on the `format` query
            parameter.
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultAddress
                  - networkId
                  - logs
                  - pagination
                properties:
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    nullable: true
                    description: CAIP-2 network identifier (e.g. eip155:1)
                    example: eip155:1
                  logs:
                    type: array
                    items:
                      type: object
                      required:
                        - timestamp
                        - eventType
                        - contractAddress
                        - txHash
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                          description: Block timestamp
                          example: 2025-01-15T10:30:00Z
                        eventType:
                          type: string
                          description: Event name
                        address:
                          type: string
                          nullable: true
                          description: "Event-specific principal address. Semantics vary by eventType:
                            ERC-7540 request events (DepositRequest,
                            RedeemRequest, ProcessDepositRequest,
                            ProcessRedeemRequest, CancelDepositRequest,
                            CancelRedeemRequest) → controller; Deposit → owner
                            (ERC-4626 share recipient); Withdraw → receiver
                            (asset recipient); ManagerDeposit, ManagerWithdraw,
                            StrategyDeposit, StrategyWithdraw → sender;
                            MintManagementShares, MintPerformanceShares →
                            manager; VaultDeposit, VaultWithdraw → external
                            vault address; WithdrawDeposit, WithdrawProfit →
                            credit line; SwapCreditPositionForTokens → buyer;
                            SetManager → newManager; CreditLineDeposit → credit
                            facility; SetFee → null. Refer to eventType to
                            interpret."
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        amount:
                          type: string
                          nullable: true
                          description: Raw uint256 asset amount (use decimals field to interpret). Set for
                            asset-denominated events. Null for share-only events
                            (RedeemRequest, CancelRedeemRequest,
                            MintManagementShares, MintPerformanceShares).
                        decimals:
                          type: integer
                          nullable: true
                          description: Token decimals for the amount field
                        token:
                          type: string
                          nullable: true
                          description: Asset token address for the amount field (when available)
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        shares:
                          type: string
                          nullable: true
                          description: "Raw uint256 vault share count. Set for: Deposit, Withdraw,
                            ProcessDepositRequest, ProcessRedeemRequest
                            (alongside amount), and RedeemRequest,
                            CancelRedeemRequest, MintManagementShares,
                            MintPerformanceShares (shares only, amount is
                            null)."
                        shareToken:
                          type: string
                          nullable: true
                          description: Vault share token address (the vault contract itself). Set whenever
                            shares is non-null.
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        contractAddress:
                          type: string
                          description: Contract that emitted the event
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        txHash:
                          type: string
                          description: Transaction hash
                        lineTokenId:
                          type: string
                          nullable: true
                          description: Credit line token ID (for CreditLineDeposit events)
                        feeType:
                          type: string
                          nullable: true
                          description: 'Fee type: "management" or "performance" (for SetFee events)'
                        managerShares:
                          type: string
                          nullable: true
                          description: Manager share amount (raw uint256, for
                            MintManagementShares/MintPerformanceShares events
                            only)
                        protocolShares:
                          type: string
                          nullable: true
                          description: Protocol share amount (raw uint256, for
                            MintManagementShares/MintPerformanceShares events
                            only)
                        protocolTreasury:
                          type: string
                          nullable: true
                          description: Protocol treasury address (for
                            MintManagementShares/MintPerformanceShares events
                            only)
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  pagination:
                    type: object
                    required:
                      - total
                      - limit
                      - offset
                    properties:
                      total:
                        type: integer
                      limit:
                        type: integer
                      offset:
                        type: integer
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: timestamp, eventType, address, amount,
                  decimals, token, shares, shareToken, contractAddress,
                  networkId, txHash, lineTokenId, feeType, managerShares,
                  protocolShares, protocolTreasury."
            text/event-stream:
              schema:
                type: string
                description: 'Server-Sent Events stream. Each log is emitted as a named "log"
                  event with JSON data. A final "done" event carries {"total":
                  N}.'
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/historical/assets:
    get:
      operationId: getVaultHistoricalAssets
      summary: Get vault historical asset metrics
      tags:
        - Vaults
      description: Get a daily timeseries of vault asset metrics derived from on-chain
        snapshots. Returns totalAssets, totalLiquidAssets, sharePrice, and a
        30-day rolling APY for each calendar day in the requested range.
        Authentication is optional but required for vaults with private
        organizations and may increase rate limits.
      parameters:
        - schema:
            type: string
            format: date
          in: query
          name: startDate
          required: false
          description: Start date (YYYY-MM-DD, UTC). Defaults to the earliest available
            snapshot date.
        - schema:
            type: string
            format: date
          in: query
          name: endDate
          required: false
          description: End date, inclusive (YYYY-MM-DD, UTC). Defaults to the latest
            available snapshot date.
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultAddress
                  - networkId
                  - assetToken
                  - shareToken
                  - decimals
                  - data
                properties:
                  vaultAddress:
                    type: string
                    description: Vault contract address
                  networkId:
                    type: string
                    nullable: true
                    description: CAIP-2 network identifier
                  assetToken:
                    type: string
                    nullable: true
                    description: Underlying asset token address (ERC-4626 asset())
                  shareToken:
                    type: string
                    nullable: true
                    description: Vault share token address (ERC-4626 share())
                  decimals:
                    type: number
                    nullable: true
                    description: Asset token decimals (shared by asset and share tokens)
                  data:
                    type: array
                    items:
                      type: object
                      required:
                        - date
                        - totalAssets
                        - totalLiquidAssets
                        - sharePrice
                        - apyPct30D
                      properties:
                        date:
                          type: string
                          description: Calendar day (YYYY-MM-DD, UTC)
                        totalAssets:
                          type: string
                          nullable: true
                          description: Total vault assets (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        totalLiquidAssets:
                          type: string
                          nullable: true
                          description: Total liquid assets (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        sharePrice:
                          type: string
                          nullable: true
                          description: Share price (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        apyPct30D:
                          type: number
                          nullable: true
                          description: 30-day rolling APY in percent (e.g. 5.25 = 5.25%). Null when fewer
                            than 30 days of snapshot data exist.
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/credit-lines:
    get:
      operationId: getVaultCreditLines
      summary: Get vault credit lines
      tags:
        - Vaults
      description: Get credit lines for a vault by querying on-chain data from the
        creditStrategy contract. Authentication is optional but required to view
        vaults with private organizations. Vaults with public organizations are
        visible to everyone.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - fees
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (includes relatedAddresses with facility address
            on each credit line), "fees" (includes fees with originationFees on
            each credit line).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultId
                  - vaultAddress
                  - networkId
                  - creditLines
                  - totals
                properties:
                  vaultId:
                    type: string
                    format: uuid
                    description: Vault ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier
                    example: eip155:1
                  creditLines:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/CreditLine"
                        - type: object
                          properties:
                            relatedAddresses:
                              nullable: true
                              description: Present when expand=related-addresses
                              allOf:
                                - $ref: "#/components/schemas/VaultCreditLineRelatedAddresses"
                  totals:
                    type: object
                    required:
                      - deposit
                      - principal
                      - interestAccrued
                      - interestRepaid
                      - interestBalance
                      - decimals
                    description: Aggregated totals. Values are normalized to the highest decimals
                      across all credit lines. All monetary fields sum across
                      all non-errored lines (open + closed); closed credit lines
                      on-chain can still hold non-zero values.
                    properties:
                      deposit:
                        type: string
                        description: Sum across all non-errored credit lines (open + closed) of deposit,
                          normalized to totals.decimals precision
                      principal:
                        type: string
                        description: Sum across all non-errored credit lines (open + closed) of
                          principal, normalized to totals.decimals precision
                      interestAccrued:
                        type: string
                        description: Sum across all non-errored credit lines (open + closed) of interest
                          accrued, normalized to totals.decimals precision
                      interestRepaid:
                        type: string
                        description: Sum across all non-errored credit lines (open + closed) of interest
                          repaid, normalized to totals.decimals precision
                      interestBalance:
                        type: string
                        description: Sum across all non-errored credit lines (open + closed) of interest
                          balance, normalized to totals.decimals precision
                      decimals:
                        type: integer
                        description: Decimal precision of the totals values
                      depositUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored credit lines (open + closed) of deposit
                          converted to USD. Null if any contributing line lacks
                          a USD price.
                      principalUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored credit lines (open + closed) of
                          outstanding principal converted to USD. Null if any
                          contributing line lacks a USD price.
                      interestAccruedUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored credit lines (open + closed) of accrued
                          interest converted to USD. Null if any contributing
                          line lacks a USD price.
                      interestRepaidUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored credit lines (open + closed) of repaid
                          interest converted to USD. Null if any contributing
                          line lacks a USD price.
                      interestBalanceUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored credit lines (open + closed) of interest
                          balance converted to USD. Null if any contributing
                          line lacks a USD price.
                      creditLimitUsd:
                        type: string
                        nullable: true
                        description: Sum across OPEN credit lines only of creditLimit converted to USD.
                          Closed lines are excluded because their creditLimit is
                          the historical authorised credit at close, not an
                          active obligation.
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/liquid-strategy:
    get:
      operationId: getVaultLiquidStrategy
      summary: Get vault liquid strategy
      tags:
        - Vaults
      description: Get liquid strategy details for a vault. Authentication is optional
        but required to view vaults with private organizations. Returns external
        ERC4626 vault positions with share balances and their underlying asset
        values.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - apy
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values: "apy"
            (fetches 30-day APY for each external vault from historical
            convertToAssets snapshots, and a weighted-average APY in totals).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultId
                  - vaultAddress
                  - networkId
                  - liquidStrategyAddress
                  - assetToken
                  - decimals
                  - vaults
                  - totals
                properties:
                  vaultId:
                    type: string
                    format: uuid
                    description: Vault ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    nullable: true
                    description: CAIP-2 network identifier
                    example: eip155:1
                  liquidStrategyAddress:
                    type: string
                    nullable: true
                    description: Liquid strategy contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  assetToken:
                    type: string
                    nullable: true
                    description: Underlying asset token address shared by all external vaults
                    example: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
                  decimals:
                    type: integer
                    nullable: true
                    description: "Decimal precision of the underlying asset token. Applies to
                      asset-denominated values: totalAssets, uninvestedAssets,
                      vaultAssets, and assetsValue."
                  vaults:
                    type: array
                    items:
                      type: object
                      required:
                        - address
                        - shares
                      properties:
                        address:
                          type: string
                          description: External vault contract address
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        name:
                          type: string
                          nullable: true
                          description: External vault name
                        symbol:
                          type: string
                          nullable: true
                          description: External vault token symbol
                        shares:
                          type: string
                          description: Share balance held by liquid strategy (raw uint256, use
                            shareDecimals for precision)
                        shareDecimals:
                          type: integer
                          nullable: true
                          description: Decimal precision of the external vault share token. Applies to
                            shares.
                        assetsValue:
                          type: string
                          nullable: true
                          description: Underlying asset value via previewRedeem (raw uint256, use
                            top-level decimals for precision), null if
                            unavailable
                        apy:
                          type: object
                          nullable: true
                          description: APY data (only present when expand=apy)
                          properties:
                            apyPct30D:
                              type: number
                              nullable: true
                              description: 30-day annualized APY in percent (e.g. 5.25 = 5.25%)
                  totals:
                    type: object
                    properties:
                      totalAssets:
                        type: string
                        nullable: true
                        description: Total assets managed by liquid strategy (raw uint256, use top-level
                          decimals for precision)
                      uninvestedAssets:
                        type: string
                        nullable: true
                        description: Uninvested asset tokens held by liquid strategy (raw uint256, use
                          top-level decimals for precision)
                      vaultAssets:
                        type: string
                        nullable: true
                        description: Sum of assets deployed in external vaults (raw uint256, use
                          top-level decimals for precision)
                      apy:
                        type: object
                        nullable: true
                        description: Weighted average APY across the entire liquid strategy (only
                          present when expand=apy). The denominator is
                          totalAssets (which includes uninvestedAssets at 0%
                          APY), so the figure reflects the strategy's blended
                          return, not just the invested portion.
                        properties:
                          apyPct30D:
                            type: number
                            nullable: true
                            description: 30-day weighted average annualized APY in percent
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/whitelist-check:
    get:
      operationId: checkVaultWhitelist
      summary: Check vault whitelist status
      tags:
        - Vaults
      description: Check if an address is whitelisted on the vault's credit strategy
        contract (requires authentication)
      parameters:
        - schema:
            type: string
            maxLength: 255
          in: query
          name: address
          required: true
          description: "The address to check for whitelisting. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultId
                  - vaultAddress
                  - networkId
                  - address
                  - isWhitelisted
                properties:
                  vaultId:
                    type: string
                    format: uuid
                    description: Vault ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier
                    example: eip155:1
                  address:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  isWhitelisted:
                    type: boolean
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/pending-deposits:
    get:
      operationId: getVaultPendingDeposits
      summary: Get vault pending deposits
      tags:
        - Vaults
      description: Get pending deposit requests for a vault. Requires a role for the
        vault's organization.
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultId
                  - vaultAddress
                  - networkId
                  - pendingDeposits
                  - decimals
                properties:
                  vaultId:
                    type: string
                    format: uuid
                    description: Vault ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier
                    example: eip155:1
                  pendingDeposits:
                    type: array
                    items:
                      type: object
                      required:
                        - controller
                        - pendingAssets
                      properties:
                        controller:
                          type: string
                          description: ERC-7540 controller address — the account that initiated the async
                            deposit/redeem request. May differ from the eventual
                            share owner.
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        pendingAssets:
                          type: string
                  decimals:
                    type: integer
                    nullable: true
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vaults/{id}/pending-redemptions:
    get:
      operationId: getVaultPendingRedemptions
      summary: Get vault pending redemptions
      tags:
        - Vaults
      description: Get pending redemption requests for a vault. Requires a role for
        the vault's organization.
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultId
                  - vaultAddress
                  - networkId
                  - pendingRedemptions
                  - decimals
                properties:
                  vaultId:
                    type: string
                    format: uuid
                    description: Vault ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    description: Vault contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier
                    example: eip155:1
                  pendingRedemptions:
                    type: array
                    items:
                      type: object
                      required:
                        - controller
                        - pendingShares
                      properties:
                        controller:
                          type: string
                          description: ERC-7540 controller address — the account that initiated the async
                            deposit/redeem request. May differ from the eventual
                            share owner.
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        pendingShares:
                          type: string
                  decimals:
                    type: integer
                    nullable: true
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/depositors/pending-deposits:
    get:
      operationId: getDepositorPendingDeposits
      summary: Get depositor pending deposits
      tags:
        - Depositors
      description: Get pending deposit requests across all vaults for a given
        depositor controller address. If networkId is omitted, results span all
        chains. Requires authentication.
      parameters:
        - schema:
            type: string
            maxLength: 200
          in: query
          name: address
          required: true
          description: "Depositor controller address to look up pending deposits for. The
            controller is the address that initiated the ERC-7540 async request
            (pendingDepositRequest / pendingRedeemRequest) and may differ from
            the eventual share owner — e.g. a smart wallet or router acting on a
            user's behalf. Example: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 42
            pattern: ^0x[0-9a-fA-F]{40}$
          in: query
          name: vaultAddress
          required: false
          description: "Filter to a specific vault address. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 200
          in: query
          name: networkId
          required: false
          description: CAIP-2 network ID (e.g., "eip155:1", "eip155:8453"). If omitted,
            results span all chains.
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - controllerAddress
                  - pendingDeposits
                  - claimableDeposits
                properties:
                  controllerAddress:
                    type: string
                    description: ERC-7540 controller address — the account that initiated the async
                      deposit/redeem request. May differ from the eventual share
                      owner.
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  pendingDeposits:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - pendingAssets
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        vaultAddress:
                          type: string
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          example: eip155:1
                        pendingAssets:
                          type: string
                          description: Pending deposit amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        decimals:
                          type: integer
                          nullable: true
                        assetToken:
                          type: string
                          nullable: true
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  claimableDeposits:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - claimableAssets
                        - claimableShares
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        vaultAddress:
                          type: string
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          example: eip155:1
                        claimableAssets:
                          type: string
                          description: Claimable asset amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        claimableShares:
                          type: string
                          description: Claimable share amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        decimals:
                          type: integer
                          nullable: true
                        assetToken:
                          type: string
                          nullable: true
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/depositors/pending-redemptions:
    get:
      operationId: getDepositorPendingRedemptions
      summary: Get depositor pending redemptions
      tags:
        - Depositors
      description: Get pending redemption requests across all vaults for a given
        depositor controller address. If networkId is omitted, results span all
        chains. Requires authentication.
      parameters:
        - schema:
            type: string
            maxLength: 200
          in: query
          name: address
          required: true
          description: "Depositor controller address to look up pending redemptions for.
            The controller is the address that initiated the ERC-7540 async
            request (pendingDepositRequest / pendingRedeemRequest) and may
            differ from the eventual share owner — e.g. a smart wallet or router
            acting on a user's behalf. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 42
            pattern: ^0x[0-9a-fA-F]{40}$
          in: query
          name: vaultAddress
          required: false
          description: "Filter to a specific vault address. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 200
          in: query
          name: networkId
          required: false
          description: CAIP-2 network ID (e.g., "eip155:1", "eip155:8453"). If omitted,
            results span all chains.
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - controllerAddress
                  - pendingRedemptions
                  - claimableRedemptions
                properties:
                  controllerAddress:
                    type: string
                    description: ERC-7540 controller address — the account that initiated the async
                      deposit/redeem request. May differ from the eventual share
                      owner.
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  pendingRedemptions:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - pendingShares
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        vaultAddress:
                          type: string
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          example: eip155:1
                        pendingShares:
                          type: string
                          description: Pending share amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        decimals:
                          type: integer
                          nullable: true
                        shareToken:
                          type: string
                          nullable: true
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  claimableRedemptions:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - claimableShares
                        - claimableAssets
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                          example: 550e8400-e29b-41d4-a716-446655440000
                        vaultAddress:
                          type: string
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          example: eip155:1
                        claimableShares:
                          type: string
                          description: Claimable share amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        claimableAssets:
                          type: string
                          description: Claimable asset amount (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        decimals:
                          type: integer
                          nullable: true
                        shareToken:
                          type: string
                          nullable: true
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/depositors/balances:
    get:
      operationId: getDepositorBalances
      summary: Get depositor vault balances
      tags:
        - Depositors
      description: Get vault share balances for a depositor address. Returns vaults
        where the address holds shares, with current balance and asset value. If
        networkId is omitted, results span all chains. Requires authentication.
      parameters:
        - schema:
            type: string
            maxLength: 200
          in: query
          name: address
          required: true
          description: "Depositor owner address — the ERC-4626 holder of vault shares (per
            balanceOf). Returns balances for shares currently owned by this
            address. Example: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 200
          in: query
          name: networkId
          required: false
          description: CAIP-2 network ID (e.g., "eip155:1", "eip155:8453"). If omitted,
            results span all chains.
        - schema:
            type: boolean
          in: query
          name: includeZeroBalances
          required: false
          description: If true, include vaults where the address has historical transfer
            activity but current balance is 0. Defaults to false.
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - address
                  - vaults
                properties:
                  address:
                    type: string
                    description: Depositor owner address queried — the ERC-4626 share holder.
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  vaults:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - shares
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                          description: Vault ID
                          example: 550e8400-e29b-41d4-a716-446655440000
                        vaultAddress:
                          type: string
                          description: Vault contract address
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          description: CAIP-2 network ID
                          example: eip155:1
                        shares:
                          type: string
                          description: Current share balance (raw uint256 — divide by 10^decimals to get
                            human-readable value)
                        assetsValue:
                          type: string
                          nullable: true
                          description: Shares converted to underlying assets (raw uint256 — divide by
                            10^decimals to get human-readable value)
                        assetsValueUsd:
                          type: string
                          nullable: true
                          description: USD value of the depositor's vault position (null if price
                            unavailable)
                        decimals:
                          type: integer
                          nullable: true
                          description: Token decimals
                        assetToken:
                          type: string
                          nullable: true
                          description: Underlying asset token address
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/depositors/portfolio:
    get:
      operationId: getDepositorPortfolio
      summary: Get depositor portfolio
      tags:
        - Depositors
      description: "Returns a depositor's portfolio broken down by vault and
        aggregated at the portfolio level. Per-vault data includes: annualized
        yield (APY calculated as IRR/money-weighted return), holding period,
        interest earned, start/end position values, total deposited/withdrawn,
        share balances, and deposit/withdraw counts — all in both native token
        amounts (raw integer strings) and USD where pricing is available. The
        portfolio-level summary aggregates these metrics across all vaults in
        USD, including a combined APY. Use the expand parameter to include
        per-vault transaction timelines (with running balances), organization
        details, and daily time series (vault-daily-stats for per-vault,
        portfolio-daily-stats for portfolio-level, or daily-stats for both).
        Uses FIFO accounting for cost basis tracking. Supports optional date
        range filtering — when startDate is provided, all prior transactions are
        used to compute the opening position. Requires authentication."
      parameters:
        - schema:
            type: string
            maxLength: 200
          in: query
          name: address
          required: true
          description: "Depositor owner address — the ERC-4626 holder of vault shares (per
            balanceOf). Returns portfolio performance for shares currently owned
            by this address. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: string
            maxLength: 200
          in: query
          name: networkId
          required: false
          description: CAIP-2 network ID (e.g., "eip155:1", "eip155:8453"). If omitted,
            results span all chains.
        - schema:
            type: string
            example: 2025-01-01
          in: query
          name: startDate
          required: false
          description: "ISO 8601 date for the start of the measurement window (earliest:
            2020-01-01). Prior transactions are used to compute the opening
            position."
        - schema:
            type: string
            example: 2025-03-19
          in: query
          name: endDate
          required: false
          description: ISO 8601 date for the end of the measurement window (inclusive).
            Defaults to now.
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - transactions
                - organization
                - vault-daily-stats
                - portfolio-daily-stats
                - daily-stats
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "transactions" (includes per-vault transaction timelines (with
            running balances)), "organization" (includes full organization
            object with links for each vault), "vault-daily-stats" (includes
            per-vault daily stats timeseries), "portfolio-daily-stats" (includes
            portfolio-level daily stats timeseries (USD-denominated, summed
            across vaults)), "daily-stats" (alias — expands to both
            vault-daily-stats and portfolio-daily-stats).'
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - address
                  - networkId
                  - startDate
                  - endDate
                  - vaults
                  - portfolio
                properties:
                  address:
                    type: string
                    description: Depositor owner address queried — the ERC-4626 share holder.
                  networkId:
                    type: string
                    nullable: true
                    description: CAIP-2 network filter applied (null if querying all chains)
                  startDate:
                    type: string
                    nullable: true
                    format: date-time
                    description: Start of measurement window (resolved from param or earliest
                      activity; null if no activity)
                  endDate:
                    type: string
                    nullable: true
                    format: date-time
                    description: End of measurement window (resolved from param or current time;
                      null if no activity)
                  vaults:
                    type: array
                    items:
                      type: object
                      required:
                        - vaultId
                        - vaultAddress
                        - networkId
                        - decimals
                        - holdingPeriodDays
                        - totalInterestEarned
                        - startValue
                        - endValue
                        - totalDeposited
                        - totalWithdrawn
                        - startShares
                        - endShares
                        - depositCount
                        - withdrawCount
                      properties:
                        vaultId:
                          type: string
                          format: uuid
                        vaultAddress:
                          type: string
                        networkId:
                          type: string
                        apyPct:
                          type: number
                          nullable: true
                          description: Annualized money-weighted return as percent (10.00 = 10%). Null if
                            holding period < 24h.
                        holdingPeriodDays:
                          type: number
                          description: Holding period in days (rounded to 2 decimal places)
                        assetToken:
                          type: string
                          nullable: true
                          description: Underlying asset token address
                        assetTokenSymbol:
                          type: string
                          nullable: true
                          description: Underlying asset token symbol (e.g., USDC)
                        decimals:
                          type: integer
                          description: Asset token decimals — divide raw integer values by 10^decimals for
                            human-readable amounts. Share amounts currently use
                            the same decimals (our vaults have ERC-4626 parity)
                            but the spec only recommends this.
                        organization:
                          nullable: true
                          allOf:
                            - $ref: "#/components/schemas/Organization"
                          description: Organization details with links. Only included when expand includes
                            "organization".
                        totalInterestEarned:
                          type: string
                          description: Total interest earned (realized + unrealized) as raw integer string
                            — divide by 10^decimals for human-readable value
                        startValue:
                          type: string
                          description: Position value at start of measurement window as raw integer string
                            — divide by 10^decimals for human-readable value
                        endValue:
                          type: string
                          description: Position value at end of measurement window as raw integer string —
                            divide by 10^decimals for human-readable value
                        totalDeposited:
                          type: string
                          description: Total deposited as raw integer string — divide by 10^decimals for
                            human-readable value
                        totalWithdrawn:
                          type: string
                          description: Total withdrawn as raw integer string — divide by 10^decimals for
                            human-readable value
                        totalInterestEarnedUsd:
                          type: string
                          nullable: true
                          description: Total interest earned in USD (null if price unavailable)
                        startValueUsd:
                          type: string
                          nullable: true
                          description: Start value in USD (null if price unavailable)
                        endValueUsd:
                          type: string
                          nullable: true
                          description: End value in USD (null if price unavailable)
                        totalDepositedUsd:
                          type: string
                          nullable: true
                          description: Total deposited in USD (null if price unavailable)
                        totalWithdrawnUsd:
                          type: string
                          nullable: true
                          description: Total withdrawn in USD (null if price unavailable)
                        totalTransferredIn:
                          type: string
                          description: Total transferred in via peer-to-peer share transfers as raw
                            integer string — divide by 10^decimals for
                            human-readable value
                        totalTransferredOut:
                          type: string
                          description: Total transferred out via peer-to-peer share transfers as raw
                            integer string — divide by 10^decimals for
                            human-readable value
                        totalTransferredInUsd:
                          type: string
                          nullable: true
                          description: Total transferred in USD (null if price unavailable)
                        totalTransferredOutUsd:
                          type: string
                          nullable: true
                          description: Total transferred out in USD (null if price unavailable)
                        totalSharesDeposited:
                          type: string
                          description: Total shares deposited as raw integer string — divide by
                            10^decimals for human-readable value
                        totalSharesWithdrawn:
                          type: string
                          description: Total shares withdrawn as raw integer string — divide by
                            10^decimals for human-readable value
                        totalSharesTransferredIn:
                          type: string
                          description: Total shares received via peer-to-peer transfers as raw integer
                            string — divide by 10^decimals for human-readable
                            value
                        totalSharesTransferredOut:
                          type: string
                          description: Total shares sent via peer-to-peer transfers as raw integer string
                            — divide by 10^decimals for human-readable value
                        startShares:
                          type: string
                          description: Share balance at start of measurement window as raw integer string
                            — divide by 10^decimals for human-readable value
                        endShares:
                          type: string
                          description: Share balance at end of measurement window as raw integer string —
                            divide by 10^decimals for human-readable value
                        depositCount:
                          type: integer
                        withdrawCount:
                          type: integer
                        transferInCount:
                          type: integer
                        transferOutCount:
                          type: integer
                        dailyStats:
                          type: array
                          description: Daily timeseries with share balances, asset values, and cumulative
                            interest. Only included when expand includes
                            "vault-daily-stats" or "daily-stats".
                          items:
                            type: object
                            required:
                              - date
                              - shares
                            properties:
                              date:
                                type: string
                                description: UTC date (YYYY-MM-DD)
                                example: 2025-01-15
                              shares:
                                type: string
                                description: Share balance at end of day as raw integer string — divide by
                                  10^decimals for human-readable value
                              balance:
                                type: string
                                nullable: true
                                description: Asset value at end of day (shares × sharePrice) as raw integer
                                  string — null if no share price snapshot
                                  available
                              balanceUsd:
                                type: string
                                nullable: true
                                description: USD value of position at end of day (null if price unavailable)
                              totalInterestEarned:
                                type: string
                                nullable: true
                                description: Cumulative interest earned up to this day as raw integer string —
                                  null if balance is null
                              totalInterestEarnedUsd:
                                type: string
                                nullable: true
                                description: Cumulative interest earned up to this day in USD (null if price
                                  unavailable)
                        transactions:
                          type: array
                          description: Ordered transaction timeline (real on-chain events only)
                          items:
                            type: object
                            required:
                              - type
                              - timestamp
                              - amount
                              - amountUsd
                              - balance
                              - balanceUsd
                              - shares
                              - sharesBalance
                            properties:
                              type:
                                type: string
                                enum:
                                  - deposit
                                  - withdraw
                                  - transfer-in
                                  - transfer-out
                              timestamp:
                                type: string
                                format: date-time
                              amount:
                                type: string
                                description: Native asset amount as raw integer string — divide by 10^decimals
                                  for human-readable value.
                              amountUsd:
                                type: string
                                nullable: true
                                description: USD amount at transaction time (null if price unavailable)
                              balance:
                                type: string
                                description: "Running balance (mark-to-market: sharesBalance * sharePrice) as
                                  raw integer string — divide by 10^decimals for
                                  human-readable value"
                              shares:
                                type: string
                                description: Share amount for this event as raw integer string — divide by
                                  10^decimals for human-readable value.
                              sharesBalance:
                                type: string
                                description: Running share count after this event as raw integer string — divide
                                  by 10^decimals for human-readable value
                              balanceUsd:
                                type: string
                                nullable: true
                                description: Running balance in USD at transaction time (null if price
                                  unavailable)
                              txHash:
                                type: string
                                nullable: true
                                description: Transaction hash
                  portfolio:
                    type: object
                    required:
                      - apyPct
                      - holdingPeriodDays
                      - startValueUsd
                      - endValueUsd
                      - totalDepositedUsd
                      - totalWithdrawnUsd
                      - totalInterestEarnedUsd
                    properties:
                      apyPct:
                        type: number
                        nullable: true
                        description: Portfolio-level annualized money-weighted return as percent (10.00
                          = 10%). Null if holding period < 24h.
                      holdingPeriodDays:
                        type: number
                        description: Total days invested in at least one vault
                      startValueUsd:
                        type: string
                        nullable: true
                        description: Portfolio start value in USD (null if no vaults have pricing)
                      endValueUsd:
                        type: string
                        nullable: true
                        description: Portfolio end value in USD (null if no vaults have pricing)
                      totalDepositedUsd:
                        type: string
                        nullable: true
                        description: Total deposited across all vaults in USD (null if no vaults have
                          pricing)
                      totalWithdrawnUsd:
                        type: string
                        nullable: true
                        description: Total withdrawn across all vaults in USD (null if no vaults have
                          pricing)
                      totalTransferredInUsd:
                        type: string
                        nullable: true
                        description: Total transferred in across all vaults in USD (null if no vaults
                          have pricing)
                      totalTransferredOutUsd:
                        type: string
                        nullable: true
                        description: Total transferred out across all vaults in USD (null if no vaults
                          have pricing)
                      transferInCount:
                        type: integer
                        description: Total transfer-in count across all vaults
                      transferOutCount:
                        type: integer
                        description: Total transfer-out count across all vaults
                      totalInterestEarnedUsd:
                        type: string
                        nullable: true
                        description: Total interest earned across all vaults in USD (null if no vaults
                          have pricing)
                      dailyStats:
                        type: array
                        description: Portfolio-level daily stats timeseries (USD-denominated, summed
                          across vaults). Only included when expand includes
                          "portfolio-daily-stats" or "daily-stats".
                        items:
                          type: object
                          required:
                            - date
                          properties:
                            date:
                              type: string
                              description: UTC date (YYYY-MM-DD)
                              example: 2025-01-15
                            balanceUsd:
                              type: string
                              nullable: true
                              description: Portfolio USD balance at end of day (null if no priced vaults)
                            totalInterestEarnedUsd:
                              type: string
                              nullable: true
                              description: Portfolio cumulative interest earned in USD up to this day (null if
                                no priced vaults)
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/benchmarks/vault-apy:
    get:
      operationId: getBenchmarkVaultApy
      summary: Get historical vault APY
      tags:
        - Benchmarks
      description: Returns a daily timeseries of rolling 7-day APY for any vault with
        on-chain snapshots. Works with both internal vaults (sharePrice) and
        ERC-4626 vaults (convertToAssets). Specify the vault by address or token
        symbol.
      parameters:
        - schema:
            type: string
          in: query
          name: address
          required: false
          description: Vault contract address (e.g., 0xabc...)
        - schema:
            type: string
          in: query
          name: symbol
          required: false
          description: Token symbol to look up the vault (e.g., stataEthUSDC)
        - schema:
            type: string
            example: eip155:1
          in: query
          name: networkId
          required: true
          description: CAIP-2 network identifier (e.g., eip155:1 for Ethereum, eip155:8453
            for Base)
        - schema:
            type: string
            format: date
            example: 2025-01-01
          in: query
          name: from
          required: false
          description: Start date (YYYY-MM-DD). Defaults to earliest available data.
        - schema:
            type: string
            format: date
            example: 2025-12-31
          in: query
          name: to
          required: false
          description: End date (YYYY-MM-DD). Defaults to latest available data.
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - address
                  - networkId
                  - data
                properties:
                  address:
                    type: string
                  networkId:
                    type: string
                  symbol:
                    type: string
                  data:
                    type: array
                    items:
                      type: object
                      required:
                        - date
                        - apyPct7D
                      properties:
                        date:
                          type: string
                          format: date
                          example: 2025-06-15
                        apyPct7D:
                          type:
                            - "null"
                            - number
                          description: Rolling 7-day APY in percent (e.g., 5.25 = 5.25%)
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/benchmarks/rate:
    get:
      operationId: getBenchmarkRate
      summary: Get historical benchmark rate
      tags:
        - Benchmarks
      description: Returns a daily timeseries of a benchmark rate from the prices
        table. Use symbol FED_FUNDS_RATE for the Federal Funds Effective Rate.
      parameters:
        - schema:
            type: string
            default: FED_FUNDS_RATE
          in: query
          name: symbol
          required: false
          description: Rate symbol (e.g., FED_FUNDS_RATE). Defaults to FED_FUNDS_RATE.
        - schema:
            type: string
            format: date
            example: 2025-01-01
          in: query
          name: from
          required: false
          description: Start date (YYYY-MM-DD). Defaults to earliest available.
        - schema:
            type: string
            format: date
            example: 2025-12-31
          in: query
          name: to
          required: false
          description: End date (YYYY-MM-DD). Defaults to latest available.
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - symbol
                  - data
                properties:
                  symbol:
                    type: string
                  data:
                    type: array
                    items:
                      type: object
                      required:
                        - date
                        - rate
                      properties:
                        date:
                          type: string
                          format: date
                          example: 2025-06-15
                        rate:
                          type: number
                          description: Rate value (e.g., 4.33 = 4.33%)
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/credit-facilities:
    get:
      operationId: listCreditFacilities
      summary: List credit facilities
      tags:
        - Credit Facilities
      description: List enabled Credit Facilities. Authentication is required. Users
        see credit facilities for public orgs plus private orgs they have access
        to.
      parameters:
        - schema:
            type: string
            maxLength: 36
            format: uuid
          in: query
          name: organizationId
          required: false
          description: "Filter by borrower organization ID. Example:
            550e8400-e29b-41d4-a716-446655440000"
        - schema:
            type: string
            maxLength: 100
          in: query
          name: address
          required: false
          description: Filter by credit facility address. Case-insensitive when networkId
            is omitted or is an EVM chain (eip155:*), case-sensitive otherwise.
        - schema:
            type: string
            maxLength: 50
          in: query
          name: networkId
          required: false
          description: Filter by network ID (CAIP-2 blockchain ID), e.g., `eip155:1`
            (Ethereum), `eip155:137` (Polygon),
            `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` (Solana)
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          in: query
          name: limit
          required: false
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - fees
                - organization
                - counts
                - status
                - collateral
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (fetches on-chain addresses: spigot, borrower,
            admin, spigotOperator, escrow), "fees" (fetches fee configuration:
            originationFee, swapFee, servicingFee), "organization" (includes
            full organization object with links), "counts" (fetches
            activeCreditLines and openProposals), "status" (fetches on-chain
            contract status), "collateral" (fetches on-chain collateral state:
            maxLtvBps, collateralValue, totalOutstandingDebt, ltvBps,
            collateralTokens[]).'
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - creditFacilities
                  - pagination
                properties:
                  creditFacilities:
                    type: array
                    items:
                      $ref: "#/components/schemas/CreditFacility"
                  pagination:
                    $ref: "#/components/schemas/Pagination"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/credit-facilities/{id}:
    get:
      operationId: getCreditFacility
      summary: Get credit facility by ID
      tags:
        - Credit Facilities
      description: Get a single Credit Facility by ID. Authentication is required.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - fees
                - organization
                - counts
                - status
                - collateral
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (fetches on-chain addresses: spigot, borrower,
            admin, spigotOperator, escrow), "fees" (fetches fee configuration:
            originationFee, swapFee, servicingFee), "organization" (includes
            full organization object with links), "counts" (fetches
            activeCreditLines and openProposals), "status" (fetches on-chain
            contract status), "collateral" (fetches on-chain collateral state:
            maxLtvBps, collateralValue, totalOutstandingDebt, ltvBps,
            collateralTokens[]).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Credit Facility ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditFacility"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/credit-facilities/{id}/credit-lines:
    get:
      operationId: getCreditFacilityCreditLines
      summary: Get credit facility credit lines
      tags:
        - Credit Facilities
      description: Get credit lines for a Credit Facility. Authentication is required.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - related-addresses
                - fees
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "related-addresses" (includes relatedAddresses object with lender,
            vault, vaultCurator on each credit line), "fees" (includes fees
            object with originationFees on each credit line).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Credit Facility ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - facilityId
                  - facilityAddress
                  - networkId
                  - activeCount
                  - totalCount
                  - creditLines
                  - totals
                properties:
                  facilityId:
                    type: string
                    description: Credit Facility UUID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  facilityAddress:
                    type: string
                    description: Credit facility contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier (e.g. eip155:8453)
                    example: eip155:1
                  activeCount:
                    type: integer
                    description: Number of active credit lines
                  totalCount:
                    type: integer
                    description: Total number of credit lines
                  fees:
                    type: object
                    nullable: true
                    description: Fee configuration for the credit facility. Null if fees could not
                      be fetched.
                    required:
                      - originationFee
                      - swapFee
                      - servicingFee
                    properties:
                      originationFee:
                        type: string
                        description: Origination fee (basis points)
                      swapFee:
                        type: string
                        description: Swap fee (basis points)
                      servicingFee:
                        type: string
                        description: Servicing fee (basis points)
                  creditLines:
                    type: array
                    description: Credit lines ordered by repayment queue position (first item is
                      repaid first)
                    items:
                      allOf:
                        - $ref: "#/components/schemas/CreditLine"
                        - type: object
                          properties:
                            relatedAddresses:
                              nullable: true
                              description: Only included when expand=related-addresses is specified. Contains
                                lender, vault, and vaultCurator addresses. Null
                                if fetching failed.
                              allOf:
                                - $ref: "#/components/schemas/FacilityCreditLineRelatedAddresses"
                  totals:
                    type: object
                    required:
                      - depositUsd
                      - principalUsd
                      - interestAccruedUsd
                      - interestRepaidUsd
                      - interestBalanceUsd
                      - creditLimitUsd
                    description: Aggregated totals in USD.
                      depositUsd/principalUsd/interestAccruedUsd/interestRepaidUsd/interestBalanceUsd
                      cover all non-errored credit lines (open + closed) —
                      closed lines can still hold non-zero balances on-chain.
                      creditLimitUsd covers OPEN lines only because closed-line
                      creditLimit is the historical authorised credit at close,
                      not an active obligation. apyPct is the
                      USD-deposit-weighted average across open lines. Any USD
                      field is null if a contributing line lacks a USD price.
                    properties:
                      depositUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored lines (open + closed) of deposit
                          converted to USD.
                      principalUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored lines (open + closed) of outstanding
                          principal converted to USD.
                      interestAccruedUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored lines (open + closed) of accrued
                          interest converted to USD.
                      interestRepaidUsd:
                        type: string
                        nullable: true
                        description: Sum across all non-errored lines (open + closed) of repaid interest
                          converted to USD.
                      interestBalanceUsd:
                        type: string
                        nullable: true
                        description: "Sum across all non-errored lines (open + closed) of interest
                          balance converted to USD. Open lines: accrued +
                          repaid. Closed lines: repaid only."
                      creditLimitUsd:
                        type: string
                        nullable: true
                        description: Sum across OPEN credit lines only of creditLimit converted to USD.
                          Closed lines are excluded because their creditLimit is
                          the historical authorised credit at close, not an
                          active obligation.
                      apyPct:
                        type: number
                        nullable: true
                        description: USD-deposit-weighted average APY across open lines (e.g. 5.0 =
                          5.0%). For multi-token facilities the weighting is in
                          USD so each line contributes proportionally to its USD
                          exposure. Falls back to raw-deposit-weighted APY (with
                          drawRate fallback) when no open line has a priced
                          non-zero deposit. Null if no APY can be derived.
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/credit-facilities/{id}/proposals:
    get:
      operationId: getCreditFacilityProposals
      summary: Get credit facility proposals
      tags:
        - Credit Facilities
      description: Get mutual consent proposals for a Credit Facility. Authentication
        is required.
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Credit Facility ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - facilityId
                  - facilityAddress
                  - networkId
                  - open
                  - closed
                  - revokedAllEvents
                properties:
                  facilityId:
                    type: string
                    description: Credit Facility UUID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  facilityAddress:
                    type: string
                    description: Credit facility contract address
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    description: CAIP-2 network identifier (e.g. eip155:8453)
                    example: eip155:1
                  open:
                    type: array
                    description: Proposals that are still open (pending acceptance)
                    items:
                      type: object
                      required:
                        - proposalId
                        - taker
                        - nonce
                        - proposalType
                        - status
                        - registeredAt
                        - registeredTxHash
                        - registeredBlockNumber
                      properties:
                        proposalId:
                          type: string
                          description: Unique proposal identifier (bytes32)
                        taker:
                          type: string
                          description: Address that needs to accept the proposal
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        nonce:
                          type: string
                          description: Nonce at time of registration
                        msgData:
                          type: string
                          nullable: true
                          description: Raw hex-encoded function call data from the proposal
                        proposalType:
                          type: string
                          enum:
                            - new_credit
                            - refinance
                            - set_fees
                            - unknown
                          description: "Type of proposal: new_credit for new credit lines, refinance for
                            modifications, set_fees for fee changes, unknown if
                            ABI missing or function is not recognized"
                        parameters:
                          oneOf:
                            - title: CreditProposalParameters
                              type: object
                              description: Credit proposal parameters (new_credit or refinance)
                              required:
                                - lender
                                - amount
                                - drawRate
                                - facilityRate
                                - deadline
                              properties:
                                lender:
                                  type: string
                                  description: Lender address
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                vaultCurator:
                                  type: string
                                  nullable: true
                                  description: Vault curator (manager) address for the lender
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                vault:
                                  type: string
                                  nullable: true
                                  description: Lending vault address for the lender (CreditStrategy)
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                token:
                                  type: string
                                  nullable: true
                                  description: Token address
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                amount:
                                  type: string
                                  description: Credit amount (raw uint256 — divide by the token's decimals to get
                                    human-readable value)
                                drawRate:
                                  type: string
                                  description: Draw rate in basis points
                                facilityRate:
                                  type: string
                                  description: Facility rate in basis points
                                deadline:
                                  type: string
                                  format: date-time
                                  description: Expiration
                                  example: 2025-01-15T10:30:00Z
                                isRestricted:
                                  type: boolean
                                  description: Whether credit is restricted (new_credit only)
                                earlyWithdrawalFee:
                                  type: string
                                  description: Early withdrawal fee in basis points (new_credit only)
                                lineTokenId:
                                  type: string
                                  description: Existing credit line token ID (refinance only)
                                desiredNonce:
                                  type: string
                                  description: Nonce the proposer required at acceptance, decoded from msgData
                                    (new_credit and refinance only)
                            - title: SetFeesProposalParameters
                              type: object
                              description: Fee change parameters (set_fees)
                              required:
                                - originationFee
                                - swapFee
                                - servicingFee
                              properties:
                                originationFee:
                                  type: string
                                  description: Origination fee in basis points
                                swapFee:
                                  type: string
                                  description: Swap fee in basis points
                                servicingFee:
                                  type: string
                                  description: Servicing fee in basis points
                            - type: "null"
                          description: "Decoded proposal terms. Shape depends on proposalType: credit
                            parameters for new_credit/refinance, fee parameters
                            for set_fees, null for unknown."
                        status:
                          type: string
                          enum:
                            - pending
                          description: Proposal status (always pending for open proposals)
                        registeredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        registeredTxHash:
                          type: string
                        registeredBlockNumber:
                          type: integer
                  closed:
                    type: array
                    description: Proposals that have been closed (accepted, revoked, or revoked_all)
                    items:
                      type: object
                      required:
                        - proposalId
                        - taker
                        - nonce
                        - proposalType
                        - status
                        - registeredAt
                        - registeredTxHash
                        - registeredBlockNumber
                        - closedAt
                        - closedTxHash
                        - closedBlockNumber
                      properties:
                        proposalId:
                          type: string
                          description: Unique proposal identifier (bytes32)
                        taker:
                          type: string
                          description: Address that needed to accept the proposal
                        nonce:
                          type: string
                          description: Nonce at time of registration
                        msgData:
                          type: string
                          nullable: true
                          description: Raw hex-encoded function call data from the proposal
                        proposalType:
                          type: string
                          enum:
                            - new_credit
                            - refinance
                            - set_fees
                            - unknown
                          description: "Type of proposal: new_credit for new credit lines, refinance for
                            modifications, set_fees for fee changes, unknown if
                            ABI missing or function is not recognized"
                        parameters:
                          oneOf:
                            - title: CreditProposalParameters
                              type: object
                              description: Credit proposal parameters (new_credit or refinance)
                              required:
                                - lender
                                - amount
                                - drawRate
                                - facilityRate
                                - deadline
                              properties:
                                lender:
                                  type: string
                                  description: Lender address
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                vaultCurator:
                                  type: string
                                  nullable: true
                                  description: Vault curator (manager) address for the lender
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                vault:
                                  type: string
                                  nullable: true
                                  description: Lending vault address for the lender (CreditStrategy)
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                token:
                                  type: string
                                  nullable: true
                                  description: Token address
                                  example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                                amount:
                                  type: string
                                  description: Credit amount (raw uint256 — divide by the token's decimals to get
                                    human-readable value)
                                drawRate:
                                  type: string
                                  description: Draw rate in basis points
                                facilityRate:
                                  type: string
                                  description: Facility rate in basis points
                                deadline:
                                  type: string
                                  format: date-time
                                  description: Expiration
                                  example: 2025-01-15T10:30:00Z
                                isRestricted:
                                  type: boolean
                                  description: Whether credit is restricted (new_credit only)
                                earlyWithdrawalFee:
                                  type: string
                                  description: Early withdrawal fee in basis points (new_credit only)
                                lineTokenId:
                                  type: string
                                  description: Existing credit line token ID (refinance only)
                                desiredNonce:
                                  type: string
                                  description: Nonce the proposer required at acceptance, decoded from msgData
                                    (new_credit and refinance only)
                            - title: SetFeesProposalParameters
                              type: object
                              description: Fee change parameters (set_fees)
                              required:
                                - originationFee
                                - swapFee
                                - servicingFee
                              properties:
                                originationFee:
                                  type: string
                                  description: Origination fee in basis points
                                swapFee:
                                  type: string
                                  description: Swap fee in basis points
                                servicingFee:
                                  type: string
                                  description: Servicing fee in basis points
                            - type: "null"
                          description: "Decoded proposal terms. Shape depends on proposalType: credit
                            parameters for new_credit/refinance, fee parameters
                            for set_fees, null for unknown."
                        status:
                          type: string
                          enum:
                            - accepted
                            - revoked
                            - revoked_all
                          description: How the proposal was closed
                        registeredAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        registeredTxHash:
                          type: string
                        registeredBlockNumber:
                          type: integer
                        closedAt:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        closedTxHash:
                          type: string
                        closedBlockNumber:
                          type: integer
                  revokedAllEvents:
                    type: array
                    description: All RevokedAll events that cleared proposals
                    items:
                      type: object
                      required:
                        - newNonce
                        - timestamp
                        - txHash
                        - blockNumber
                      properties:
                        newNonce:
                          type: string
                          description: New nonce after revocation
                        timestamp:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        txHash:
                          type: string
                        blockNumber:
                          type: integer
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/borrowers:
    get:
      operationId: listBorrowers
      summary: List borrowers
      tags:
        - Borrowers
      description: List enabled borrower organizations. Authentication is optional but
        affects results.
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          in: query
          name: limit
          required: false
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - organization
                - stats
                - apy
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "organization" (includes full organization object with links),
            "stats" (includes borrower statistics), "apy" (includes weighted APY
            and facilities count).'
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - borrowers
                  - pagination
                properties:
                  borrowers:
                    type: array
                    items:
                      type: object
                      required:
                        - organizationId
                        - name
                        - networkIds
                      properties:
                        organizationId:
                          type: string
                          format: uuid
                          description: Borrower organization ID
                          example: 550e8400-e29b-41d4-a716-446655440000
                        name:
                          type: string
                          description: Organization name
                        networkIds:
                          type: array
                          items:
                            type: string
                            example: eip155:1
                          description: CAIP-2 network identifiers for blockchain networks this borrower
                            has credit facilities on
                        organization:
                          nullable: true
                          allOf:
                            - $ref: "#/components/schemas/Organization"
                          description: Full organization details with links. Only included when expand
                            includes "organization".
                        stats:
                          type: object
                          nullable: true
                          description: Borrower statistics. Only included when expand includes "stats".
                          required:
                            - totalVolumeUsd
                            - activeLoansUsd
                            - totalInterestPaidUsd
                            - totalBorrowedUsd
                          properties:
                            totalVolumeUsd:
                              type: string
                              description: Total USD volume (borrows + all repayments)
                              example: "1234567.890000"
                            activeLoansUsd:
                              type: string
                              description: Current outstanding principal in USD (borrows - principal
                                repayments)
                              example: "1234567.890000"
                            totalInterestPaidUsd:
                              type: string
                              description: Cumulative interest paid in USD
                              example: "1234567.890000"
                            totalBorrowedUsd:
                              type: string
                              description: Cumulative amount borrowed in USD (regardless of repayments)
                              example: "1234567.890000"
                        apy:
                          type: object
                          nullable: true
                          description: APY and facilities data. Only included when expand includes "apy".
                          required:
                            - facilitiesCount
                            - activeCreditLinesCount
                          properties:
                            weightedApyPct:
                              type: number
                              nullable: true
                              description: Weighted average APY as a percentage (e.g., 8.5 = 8.5%). Null if no
                                credit facility or rates unavailable.
                            facilitiesCount:
                              type: number
                              description: Number of credit facilities for this borrower.
                            activeCreditLinesCount:
                              type: number
                              description: Number of open credit lines across all credit facilities for this
                                borrower.
                  pagination:
                    $ref: "#/components/schemas/Pagination"
  /v3/borrowers/{id}:
    get:
      operationId: getBorrower
      summary: Get borrower by ID
      tags:
        - Borrowers
      description: Get a single borrower organization by ID. Authentication is
        optional but required to view private borrowers.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - organization
                - stats
                - apy
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "organization" (includes full organization object with links),
            "stats" (includes borrower statistics), "apy" (includes weighted APY
            and facilities count).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Borrower organization ID. Example:
            550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizationId
                  - name
                  - networkIds
                properties:
                  organizationId:
                    type: string
                    format: uuid
                    description: Borrower organization ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  name:
                    type: string
                    description: Organization name
                  networkIds:
                    type: array
                    items:
                      type: string
                      example: eip155:1
                    description: CAIP-2 network identifiers for blockchain networks this borrower
                      has credit facilities on
                  organization:
                    nullable: true
                    allOf:
                      - $ref: "#/components/schemas/Organization"
                    description: Full organization details with links. Only included when expand
                      includes "organization".
                  stats:
                    type: object
                    nullable: true
                    description: Borrower statistics. Only included when expand includes "stats".
                    required:
                      - totalVolumeUsd
                      - activeLoansUsd
                      - totalInterestPaidUsd
                      - totalBorrowedUsd
                    properties:
                      totalVolumeUsd:
                        type: string
                        description: Total USD volume (borrows + all repayments)
                        example: "1234567.890000"
                      activeLoansUsd:
                        type: string
                        description: Current outstanding principal in USD (borrows - principal
                          repayments)
                        example: "1234567.890000"
                      totalInterestPaidUsd:
                        type: string
                        description: Cumulative interest paid in USD
                        example: "1234567.890000"
                      totalBorrowedUsd:
                        type: string
                        description: Cumulative amount borrowed in USD (regardless of repayments)
                        example: "1234567.890000"
                  apy:
                    type: object
                    nullable: true
                    description: APY and facilities data. Only included when expand includes "apy".
                    required:
                      - facilitiesCount
                      - activeCreditLinesCount
                    properties:
                      weightedApyPct:
                        type: number
                        nullable: true
                        description: Weighted average APY as a percentage (e.g., 8.5 = 8.5%). Null if no
                          credit facility or rates unavailable.
                      facilitiesCount:
                        type: number
                        description: Number of credit facilities for this borrower.
                      activeCreditLinesCount:
                        type: number
                        description: Number of open credit lines across all credit facilities for this
                          borrower.
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/borrowers/{id}/logs:
    get:
      operationId: getBorrowerLogs
      summary: Get borrower credit line logs
      tags:
        - Borrowers
      description: >-
        Get on-chain credit line logs for a borrower.


        Supports three response formats via the `format` query parameter:

        - **json** (default) — paginated JSON (default limit 20, max 1000).

        - **csv** — streamed CSV file download (up to 1 000 000 rows).

        - **event-stream** — Server-Sent Events stream (up to 1 000 000 rows).
        Each log is emitted as a named `log` event with JSON data. A final
        `done` event carries `{"total": N}`. Connect with `EventSource` or
        `fetch`:


        ```js

        const es = new
        EventSource('/v3/borrowers/{id}/logs?format=event-stream', {
          headers: { 'x-api-key': 'cc_...' },
        });

        es.addEventListener('log', (e) => console.log(JSON.parse(e.data)));

        es.addEventListener('done', (e) => { console.log('total:',
        JSON.parse(e.data).total); es.close(); });

        ```


        Event types: AddCredit, RepayPrincipal, RepayInterest, IncreaseCredit,
        ReservesChanged, Borrow, WithdrawDeposit, WithdrawProfit,
        PayServicingFee, TransferOriginationFee.
      parameters:
        - schema:
            type: string
            enum:
              - json
              - csv
              - event-stream
            default: json
          in: query
          name: format
          required: false
          description: 'Response format. "json" returns paginated JSON (default 20, max
            1000). "csv" returns a streamed CSV file download. "event-stream"
            returns Server-Sent Events with each log as a named "log" event and
            a final "done" event. Event types: AddCredit, RepayPrincipal,
            RepayInterest, IncreaseCredit, ReservesChanged, Borrow,
            WithdrawDeposit, WithdrawProfit, PayServicingFee,
            TransferOriginationFee.'
        - schema:
            type: string
          in: query
          name: networkId
          required: false
          description: "Filter logs by CAIP-2 network identifier. Example: eip155:8453"
        - schema:
            type: string
            format: date
          in: query
          name: startDate
          required: false
          description: "Start date (YYYY-MM-DD). Example: 2025-01-15"
        - schema:
            type: string
            format: date
          in: query
          name: endDate
          required: false
          description: "End date, inclusive (YYYY-MM-DD). Example: 2025-01-15"
        - schema:
            type: integer
            minimum: 1
          in: query
          name: limit
          required: false
          description: "Maximum number of results. For json: default 20, max 1000. For
            csv/event-stream: default 1000000, max 1000000."
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Borrower organization ID. Example:
            550e8400-e29b-41d4-a716-446655440000"
      security: *a2
      responses:
        "200":
          description: Borrower credit line logs. Response format depends on the `format`
            query parameter.
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizationId
                  - logs
                  - pagination
                properties:
                  organizationId:
                    type: string
                    format: uuid
                    description: Borrower organization ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  logs:
                    type: array
                    items:
                      type: object
                      required:
                        - timestamp
                        - eventType
                        - direction
                        - amount
                        - decimals
                        - token
                        - lineTokenId
                        - contractAddress
                        - networkId
                        - txHash
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                          example: 2025-01-15T10:30:00Z
                        eventType:
                          type: string
                          description: "Event type. One of: AddCredit, RepayPrincipal, RepayInterest,
                            IncreaseCredit, ReservesChanged, Borrow,
                            WithdrawDeposit, WithdrawProfit, PayServicingFee,
                            TransferOriginationFee"
                        direction:
                          type: string
                          enum:
                            - in
                            - out
                            - none
                          description: "Cash flow direction: in (deposits/repayments), out
                            (borrows/withdrawals/fees), none (admin events)"
                        amount:
                          type: string
                          description: Raw on-chain amount (smallest unit integer string)
                        decimals:
                          type: integer
                          nullable: true
                          description: Token decimals for converting amount to human-readable form
                        token:
                          type: string
                          nullable: true
                          description: Token contract address
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        lineTokenId:
                          type: string
                          nullable: true
                          description: Credit line token ID (from decodedParams)
                        contractAddress:
                          type: string
                          example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                        networkId:
                          type: string
                          description: CAIP-2 network identifier (e.g. eip155:8453)
                          example: eip155:1
                        txHash:
                          type: string
                  pagination:
                    $ref: "#/components/schemas/Pagination"
            text/csv:
              schema:
                type: string
                description: "CSV file download. Columns: timestamp, eventType, direction,
                  amount, decimals, token, lineTokenId, contractAddress,
                  networkId, txHash."
            text/event-stream:
              schema:
                type: string
                description: 'Server-Sent Events stream. Each log is emitted as a named "log"
                  event with JSON data. A final "done" event carries {"total":
                  N}.'
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/borrowers/{id}/analytics:
    get:
      operationId: getBorrowerAnalytics
      summary: Get borrower analytics time series
      tags:
        - Borrowers
      description: Get analytics time series for a borrower. Returns daily cashflow,
        trailing sums, and debt metrics. Auto-detects loan start date from the
        first borrow event if startDate is not provided.
      parameters:
        - schema:
            type: string
            format: date
          in: query
          name: startDate
          required: false
          description: Start date (YYYY-MM-DD). Defaults to auto-detected loan start.
        - schema:
            type: string
            format: date
          in: query
          name: endDate
          required: false
          description: End date, inclusive (YYYY-MM-DD). Defaults to today.
        - schema:
            type: string
          in: query
          name: trailingDays
          required: false
          description: 'Comma-separated trailing periods in days (e.g. "14,30,120"). Max:
            365. Defaults to org config or "30".'
        - schema:
            type: string
          in: query
          name: stages
          required: false
          description: 'Comma-separated stage filter for cashflow (e.g.
            "secured,settled"). Valid values: external, in_transit, secured,
            settled. Normally you do not need to specify this parameter.
            Defaults to org config or "secured".'
        - schema:
            type: string
            enum:
              - inflow
              - net
          in: query
          name: direction
          required: false
          description: Cash flow direction. "inflow" counts only inflows. "net" computes
            net flow (inflows - outflows). Defaults to org config or "inflow".
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - debt
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values: "debt"
            (adds live on-chain debt state).'
        - schema:
            type: string
            enum:
              - json
              - csv
            default: json
          in: query
          name: format
          required: false
          description: Response format. "json" (default) or "csv" file download.
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: Borrower organization ID
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizationId
                  - organizationName
                  - config
                  - timeSeries
                  - meta
                properties:
                  organizationId:
                    type: string
                    format: uuid
                  organizationName:
                    type: string
                  config:
                    type: object
                    properties:
                      trailingPeriods:
                        type: array
                        items:
                          type: integer
                      stages:
                        type: array
                        items:
                          type: string
                      direction:
                        type: string
                        enum:
                          - inflow
                          - net
                      loanStartDate:
                        type: string
                        nullable: true
                      loanEndDate:
                        type: string
                        nullable: true
                      loanTermDays:
                        type: integer
                        nullable: true
                        description: Loan term in days (loanEndDate - loanStartDate), used as trailing
                          period for SRR/WALD
                  timeSeries:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date
                        cashFlowDaily:
                          type: string
                        trailingCashFlows:
                          type: object
                          additionalProperties:
                            type: string
                          description: 'Trailing cashflow sums keyed by period (e.g. { "14": "423000.00",
                            "30": "1523450.00" })'
                        principal:
                          type: string
                        interestPaid:
                          type: string
                        debt:
                          type: string
                        creditLimit:
                          type: string
                          nullable: true
                          description: Reconstructed credit limit (sum of AddCredit deposits) as of this
                            date
                        loanTerm:
                          type: string
                          nullable: true
                          description: Deposit-weighted average loan term (days) of credit lines open on
                            this date
                        dscr:
                          type: string
                          nullable: true
                          description: "DSCR: loan-term-windowed cashflow / credit limit"
                        srr:
                          type: string
                          nullable: true
                          description: "SRR (Spigot Repayment Rate): 30d trailing cashflow / credit limit"
                        wald:
                          type: string
                          nullable: true
                          description: "WALD (Weighted Avg Liquidity Duration): 30 / SRR (days to repay at
                            current 30d rate)"
                        collateral:
                          type: string
                          nullable: true
                          description: Cumulative collateral snapshot (USD) as of this date
                  currentDebt:
                    type: object
                    nullable: true
                    description: Live on-chain debt state. Only present when expand=debt.
                    properties:
                      principal:
                        type: string
                      accruedInterest:
                        type: string
                      deposit:
                        type: string
                      totalDebt:
                        type: string
                      facilities:
                        type: array
                        items:
                          type: object
                          properties:
                            address:
                              type: string
                            networkId:
                              type: string
                            principal:
                              type: string
                            deposit:
                              type: string
                            interestAccrued:
                              type: string
                  meta:
                    type: object
                    properties:
                      dataRange:
                        type: object
                        properties:
                          from:
                            type: string
                          to:
                            type: string
                      entriesCount:
                        type: integer
                      loanStartDetected:
                        type: boolean
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/vault-curators:
    get:
      operationId: listVaultCurators
      summary: List vault curators
      tags:
        - Vault Curators
      description: List enabled vault curator organizations. Authentication is
        optional but affects results.
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          in: query
          name: limit
          required: false
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - organization
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "organization" (includes full organization object with links).'
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - vaultCurators
                  - pagination
                properties:
                  vaultCurators:
                    type: array
                    items:
                      type: object
                      required:
                        - organizationId
                        - name
                        - networkIds
                      properties:
                        organizationId:
                          type: string
                          format: uuid
                          description: Vault curator organization ID
                          example: 550e8400-e29b-41d4-a716-446655440000
                        name:
                          type: string
                          description: Organization name
                        networkIds:
                          type: array
                          items:
                            type: string
                            example: eip155:1
                          description: CAIP-2 network identifiers for blockchain networks this vault
                            curator has vaults on
                        organization:
                          nullable: true
                          allOf:
                            - $ref: "#/components/schemas/Organization"
                          description: Full organization details with links. Only included when expand
                            includes "organization".
                  pagination:
                    $ref: "#/components/schemas/Pagination"
  /v3/vault-curators/{id}:
    get:
      operationId: getVaultCurator
      summary: Get vault curator by ID
      tags:
        - Vault Curators
      description: Get a single vault curator organization by ID. Authentication is
        optional but required to view private vault curators.
      parameters:
        - schema:
            type: array
            style: form
            explode: false
            items:
              type: string
              enum:
                - organization
          in: query
          name: expand
          required: false
          description: 'Comma-separated list of fields to expand. Valid values:
            "organization" (includes full organization object with links).'
        - schema:
            type: string
            format: uuid
          in: path
          name: id
          required: true
          description: "Vault curator organization ID. Example:
            550e8400-e29b-41d4-a716-446655440000"
      security: *a1
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizationId
                  - name
                  - networkIds
                properties:
                  organizationId:
                    type: string
                    format: uuid
                    description: Vault curator organization ID
                    example: 550e8400-e29b-41d4-a716-446655440000
                  name:
                    type: string
                    description: Organization name
                  networkIds:
                    type: array
                    items:
                      type: string
                      example: eip155:1
                    description: CAIP-2 network identifiers for blockchain networks this vault
                      curator has vaults on
                  organization:
                    nullable: true
                    allOf:
                      - $ref: "#/components/schemas/Organization"
                    description: Full organization details with links. Only included when expand
                      includes "organization".
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/verified:
    get:
      operationId: checkUserVerification
      summary: Check user verification status
      tags:
        - Users
      description: Check if the authenticated user is verified (via KYC, legacy
        onboarding, KYB organization membership, or legacy KYB)
      security: &a3
        - BearerAuth: []
        - OAuth2: []
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - verified
                properties:
                  verified:
                    type: boolean
                    description: Whether the user is verified through KYC, legacy onboarding, or
                      membership in a KYB-verified or legacy KYB organization
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/consent:
    post:
      operationId: recordBiometricConsent
      summary: Record biometric consent
      tags:
        - Users
      description: Record biometric consent for the authenticated user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - biometricConsentGiven
                - biometricConsentVersion
              properties:
                biometricConsentGiven:
                  type: boolean
                  description: Whether the user has given biometric consent
                biometricConsentVersion:
                  type: string
                  description: Version of the biometric consent accepted
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - user
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  user:
                    type: object
                    required:
                      - id
                      - email
                      - createdAt
                      - updatedAt
                    properties:
                      id:
                        type: string
                        format: uuid
                        example: 550e8400-e29b-41d4-a716-446655440000
                      email:
                        type: string
                      firstName:
                        type: string
                        nullable: true
                      lastName:
                        type: string
                        nullable: true
                      metadata:
                        type: object
                        nullable: true
                        additionalProperties: true
                      createdAt:
                        type: string
                        format: date-time
                        example: 2025-01-15T10:30:00Z
                      updatedAt:
                        type: string
                        format: date-time
                        example: 2025-01-15T10:30:00Z
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/organizations:
    get:
      operationId: listMyOrganizations
      summary: List user's organizations
      tags:
        - Users
      description: List all organizations the authenticated user is a member of.
        Returns organizations, per-org functional access roles ("borrower",
        "vault-curator"), and a top-level union of all functional roles. Not all
        members receive functional roles; members without any will have an empty
        roles array for that org.
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizations
                  - organizationAccessById
                  - roles
                properties:
                  organizations:
                    type: array
                    items:
                      $ref: "#/components/schemas/Organization"
                  organizationAccessById:
                    type: object
                    additionalProperties:
                      type: object
                      required:
                        - roles
                      properties:
                        roles:
                          type: array
                          items:
                            type: string
                            enum:
                              - borrower
                              - vault-curator
                              - vault-depositor-manager
                          description: 'Functional access roles for this organization. "borrower": member
                            of a borrower org. "vault-curator": member of a
                            vault curator org. "vault-depositor-manager": admin
                            of a vault curator org. Not all members receive
                            functional roles.'
                    description: Map of organizationId to functional access roles.
                  roles:
                    type: array
                    items:
                      type: string
                      enum:
                        - borrower
                        - vault-curator
                        - vault-depositor-manager
                    description: Union of all functional roles the user has across all
                      organizations.
                example:
                  organizations:
                    - id: 550e8400-e29b-41d4-a716-446655440000
                      name: Acme Corp
                      slug: acme-corp
                      header: null
                      description: null
                      overview: null
                      links:
                        - id: a10e8400-e29b-41d4-a716-446655440000
                          label: "#logo"
                          linkText: null
                          iconUrl: null
                          url: https://example.com/acme-logo.png
                    - id: 660e8400-e29b-41d4-a716-446655440001
                      name: Beta Inc
                      slug: beta-inc
                      header: null
                      description: null
                      overview: null
                      links: []
                  organizationAccessById:
                    550e8400-e29b-41d4-a716-446655440000:
                      roles:
                        - borrower
                    660e8400-e29b-41d4-a716-446655440001:
                      roles:
                        - vault-curator
                        - vault-depositor-manager
                  roles:
                    - borrower
                    - vault-curator
                    - vault-depositor-manager
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/organizations/kyb-eligible:
    get:
      operationId: listKybEligibleOrganizations
      summary: List KYB-eligible organizations
      tags:
        - Users
      description: "List organizations where the authenticated user is an admin with
        KYB eligibility status. Returns simplified organization data: name,
        slug, and kybEligible flag."
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - organizations
                properties:
                  organizations:
                    type: array
                    items:
                      type: object
                      required:
                        - name
                        - slug
                        - kybEligible
                      properties:
                        name:
                          type: string
                          maxLength: 255
                        slug:
                          type: string
                          maxLength: 100
                        kybEligible:
                          type: boolean
                          description: Whether the organization is eligible for KYB verification (true if
                            user is admin and org is NOT yet verified)
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/whitelist-requests:
    post:
      operationId: createWhitelistRequest
      summary: Submit vault whitelist request
      tags:
        - Whitelist Requests
      description: Submit a request to be whitelisted for a private vault (requires
        verified status)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                vaultId:
                  type: string
                  format: uuid
                  description: "Vault ID. If provided, vaultAddress and networkId are derived from
                    the vault. Example: 550e8400-e29b-41d4-a716-446655440000"
                vaultAddress:
                  type: string
                  maxLength: 42
                  pattern: ^0x[0-9a-fA-F]{40}$
                  description: "The Ethereum address of the vault (required if vaultId is not
                    provided). Example:
                    0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                networkId:
                  type: string
                  maxLength: 50
                  description: The CAIP-2 network identifier, e.g. "eip155:1" (required if vaultId
                    is not provided)
                requestorAddress:
                  type: string
                  maxLength: 42
                  pattern: ^0x[0-9a-fA-F]{40}$
                  description: "Your Ethereum address to be whitelisted. Example:
                    0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
              required:
                - requestorAddress
              oneOf:
                - required:
                    - vaultId
                - required:
                    - vaultAddress
                    - networkId
      security: *a3
      responses:
        "201":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - vaultAddress
                  - networkId
                  - requestorEmail
                  - requestorAddress
                  - status
                  - requestedAt
                  - createdAt
                  - updatedAt
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    example: eip155:1
                  requestorUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  requestorEmail:
                    type: string
                  requestorAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  status:
                    type: string
                  requestedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  approverUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  approverEmail:
                    type: string
                    nullable: true
                  approverAddress:
                    type: string
                    nullable: true
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  processedAt:
                    type: string
                    format: date-time
                    nullable: true
                    example: 2025-01-15T10:30:00Z
                  createdAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  updatedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/whitelist-requests/me:
    get:
      operationId: listMyWhitelistRequests
      summary: Get my whitelist requests
      tags:
        - Whitelist Requests
      description: Get all whitelist requests submitted by the authenticated user
      parameters:
        - schema:
            type: string
            enum:
              - pending
              - approved
              - rejected
          in: query
          name: status
          required: false
          description: Filter by request status
        - schema:
            type: string
            format: uuid
          in: query
          name: vaultId
          required: false
          description: "Filter by vault ID. Takes precedence over vaultAddress. Example:
            550e8400-e29b-41d4-a716-446655440000"
        - schema:
            type: string
            maxLength: 42
            pattern: ^0x[0-9a-fA-F]{40}$
          in: query
          name: vaultAddress
          required: false
          description: "Filter by vault address. Example:
            0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          in: query
          name: limit
          required: false
        - schema:
            type: integer
            minimum: 0
            default: 0
          in: query
          name: offset
          required: false
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - requests
                  - pagination
                properties:
                  requests:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - vaultAddress
                        - networkId
                        - requestorEmail
                        - requestorAddress
                        - status
                        - requestedAt
                        - createdAt
                        - updatedAt
                      properties:
                        id:
                          type: string
                          format: uuid
                        vaultAddress:
                          type: string
                        networkId:
                          type: string
                        requestorUserId:
                          type: string
                          format: uuid
                          nullable: true
                        requestorEmail:
                          type: string
                        requestorAddress:
                          type: string
                        status:
                          type: string
                        requestedAt:
                          type: string
                          format: date-time
                        approverUserId:
                          type: string
                          format: uuid
                          nullable: true
                        approverEmail:
                          type: string
                          nullable: true
                        approverAddress:
                          type: string
                          nullable: true
                        processedAt:
                          type: string
                          format: date-time
                          nullable: true
                        createdAt:
                          type: string
                          format: date-time
                        updatedAt:
                          type: string
                          format: date-time
                  pagination:
                    type: object
                    required:
                      - total
                      - limit
                      - offset
                    properties:
                      total:
                        type: integer
                      limit:
                        type: integer
                      offset:
                        type: integer
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/whitelist-requests/{requestId}:
    get:
      operationId: getWhitelistRequest
      summary: Get whitelist request by ID
      tags:
        - Whitelist Requests
      description: Get a specific whitelist request by ID (must be owned by you)
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: requestId
          required: true
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - vaultAddress
                  - networkId
                  - requestorEmail
                  - requestorAddress
                  - status
                  - requestedAt
                  - createdAt
                  - updatedAt
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    example: eip155:1
                  requestorUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  requestorEmail:
                    type: string
                  requestorAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  status:
                    type: string
                  requestedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  approverUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  approverEmail:
                    type: string
                    nullable: true
                  approverAddress:
                    type: string
                    nullable: true
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  processedAt:
                    type: string
                    format: date-time
                    nullable: true
                    example: 2025-01-15T10:30:00Z
                  createdAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  updatedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/whitelist-requests/vault/{vaultId}:
    get:
      operationId: listVaultWhitelistRequests
      summary: Get whitelist requests for a vault
      tags:
        - Whitelist Requests
      description: Get all whitelist requests for a specific vault by vault ID.
        Requires the caller to be a member of the vault's organization.
      parameters:
        - schema:
            type: string
            enum:
              - pending
              - approved
              - rejected
          in: query
          name: status
          required: false
        - schema:
            type: string
            format: uuid
          in: path
          name: vaultId
          required: true
          description: "Vault ID. Example: 550e8400-e29b-41d4-a716-446655440000"
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - requests
                  - total
                properties:
                  requests:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - vaultAddress
                        - networkId
                        - requestorEmail
                        - requestorAddress
                        - status
                        - requestedAt
                        - createdAt
                        - updatedAt
                      properties:
                        id:
                          type: string
                          format: uuid
                        vaultAddress:
                          type: string
                        networkId:
                          type: string
                        requestorUserId:
                          type: string
                          format: uuid
                          nullable: true
                        requestorEmail:
                          type: string
                        requestorAddress:
                          type: string
                        status:
                          type: string
                        requestedAt:
                          type: string
                          format: date-time
                        approverUserId:
                          type: string
                          format: uuid
                          nullable: true
                        approverEmail:
                          type: string
                          nullable: true
                        approverAddress:
                          type: string
                          nullable: true
                        processedAt:
                          type: string
                          format: date-time
                          nullable: true
                        createdAt:
                          type: string
                          format: date-time
                        updatedAt:
                          type: string
                          format: date-time
                  total:
                    type: integer
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/whitelist-requests/{requestId}/reject:
    post:
      operationId: rejectWhitelistRequest
      summary: Reject a whitelist request
      tags:
        - Whitelist Requests
      description: Reject a whitelist request. Requires the caller to be a curator in
        the vault's organization.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                approverAddress:
                  type: string
                  maxLength: 42
                  pattern: ^0x[0-9a-fA-F]{40}$
                  description: "Optional Ethereum address of the approver. Example:
                    0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: requestId
          required: true
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - vaultAddress
                  - networkId
                  - requestorEmail
                  - requestorAddress
                  - status
                  - requestedAt
                  - createdAt
                  - updatedAt
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 550e8400-e29b-41d4-a716-446655440000
                  vaultAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  networkId:
                    type: string
                    example: eip155:1
                  requestorUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  requestorEmail:
                    type: string
                  requestorAddress:
                    type: string
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  status:
                    type: string
                  requestedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  approverUserId:
                    type: string
                    format: uuid
                    nullable: true
                    example: 550e8400-e29b-41d4-a716-446655440000
                  approverEmail:
                    type: string
                    nullable: true
                  approverAddress:
                    type: string
                    nullable: true
                    example: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
                  processedAt:
                    type: string
                    format: date-time
                    nullable: true
                    example: 2025-01-15T10:30:00Z
                  createdAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
                  updatedAt:
                    type: string
                    format: date-time
                    example: 2025-01-15T10:30:00Z
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/wallets/challenge:
    post:
      operationId: generateWalletChallenge
      summary: Generate wallet attestation challenge
      tags:
        - Wallet Attestation
      description: Generate a challenge message for the given wallet address. The user
        must sign this message to prove ownership.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - address
                - namespace
              properties:
                address:
                  type: string
                  maxLength: 42
                  pattern: ^0x[0-9a-fA-F]{40}$
                  description: EVM wallet address to attest.
                namespace:
                  type: string
                  enum:
                    - eip155
                  description: Address namespace. Currently only "eip155" (EVM) is supported.
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - message
                  - nonce
                  - expiresIn
                properties:
                  message:
                    type: string
                    description: Challenge message to sign
                  nonce:
                    type: string
                    description: Challenge nonce
                  expiresIn:
                    type: integer
                    description: Nonce TTL in seconds
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/wallets/attest:
    post:
      operationId: verifyWalletAttestation
      summary: Verify wallet attestation
      tags:
        - Wallet Attestation
      description: Submit the signed attestation message to prove wallet ownership and
        link the address to your account.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - address
                - namespace
                - signature
                - message
              properties:
                address:
                  type: string
                  maxLength: 42
                  pattern: ^0x[0-9a-fA-F]{40}$
                  description: EVM wallet address being attested.
                namespace:
                  type: string
                  enum:
                    - eip155
                  description: Network namespace the user is attesting under. The signature is NOT
                    chain-bound — for EVM ('eip155'), the same attestation
                    covers all eip155 chains.
                signature:
                  type: string
                  description: The signed message signature from the wallet.
                message:
                  type: string
                  description: The attestation message that was signed (returned from the
                    challenge endpoint).
      security: *a3
      responses:
        "201":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - address
                  - networkNamespace
                  - verifiedAt
                  - createdAt
                properties:
                  id:
                    type: string
                    format: uuid
                  address:
                    type: string
                  networkNamespace:
                    type: string
                  verifiedAt:
                    type: string
                    format: date-time
                  createdAt:
                    type: string
                    format: date-time
                  subscriptions:
                    type: array
                    items:
                      type: object
                      required:
                        - type
                        - enabled
                      properties:
                        type:
                          type: string
                          enum:
                            - wallet_transactional
                            - weekly_portfolio
                        enabled:
                          type: boolean
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/wallets:
    get:
      operationId: listAttestedWallets
      summary: List the user's wallets (optionally including org multisigs)
      tags:
        - Wallet Attestation
      description: List the user's attested EOAs. Pass `?include=multisigs` to also
        include org-owned multisigs the user has access to.
      parameters:
        - schema:
            type: string
            enum:
              - multisigs
          in: query
          name: include
          required: false
          description: Optional extras to include in the response. Currently only
            `multisigs` is supported.
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - wallets
                properties:
                  wallets:
                    type: array
                    items:
                      type: object
                      required:
                        - type
                        - address
                        - subscriptions
                      properties:
                        type:
                          type: string
                          enum:
                            - eoa
                            - multisig
                            - org_eoa
                        id:
                          type: string
                        address:
                          type: string
                        networkNamespace:
                          type: string
                        verifiedAt:
                          type: string
                          format: date-time
                        createdAt:
                          type: string
                          format: date-time
                        networkId:
                          type: string
                        organizationId:
                          type: string
                          format: uuid
                        organizationName:
                          type: string
                        subscriptions:
                          type: array
                          items:
                            type: object
                            required:
                              - type
                              - enabled
                            properties:
                              type:
                                type: string
                                enum:
                                  - wallet_transactional
                                  - weekly_portfolio
                              enabled:
                                type: boolean
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v3/users/me/email-subscriptions:
    put:
      operationId: updateEmailSubscriptions
      summary: Update email subscription preferences for the authenticated user
      tags:
        - Wallet Attestation
      description: "Subscribe or unsubscribe in bulk. Each change is identified by
        (address, networkId, type); `enabled: true` inserts a row, `enabled:
        false` deletes one. All cells are user-editable; defaults at
        wallet-create / org-join time are managed server-side."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - changes
              properties:
                changes:
                  type: array
                  items:
                    type: object
                    required:
                      - address
                      - networkId
                      - type
                      - enabled
                    properties:
                      address:
                        type: string
                        maxLength: 42
                        pattern: ^0x[0-9a-fA-F]{40}$
                        description: EVM address. The server normalizes to EIP-55 checksum form before
                          lookup, so lowercase or mixed case are accepted.
                      networkId:
                        type: string
                        maxLength: 50
                      type:
                        type: string
                        enum:
                          - wallet_transactional
                          - weekly_portfolio
                      enabled:
                        type: boolean
      security: *a3
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - wallets
                properties:
                  wallets:
                    type: array
                    items:
                      type: object
                      required:
                        - type
                        - address
                        - subscriptions
                      properties:
                        type:
                          type: string
                          enum:
                            - eoa
                            - multisig
                            - org_eoa
                        id:
                          type: string
                        address:
                          type: string
                        networkNamespace:
                          type: string
                        verifiedAt:
                          type: string
                          format: date-time
                        createdAt:
                          type: string
                          format: date-time
                        networkId:
                          type: string
                        organizationId:
                          type: string
                          format: uuid
                        organizationName:
                          type: string
                        subscriptions:
                          type: array
                          items:
                            type: object
                            required:
                              - type
                              - enabled
                            properties:
                              type:
                                type: string
                                enum:
                                  - wallet_transactional
                                  - weekly_portfolio
                              enabled:
                                type: boolean
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /email/unsubscribe:
    get:
      operationId: unsubscribeViaLink
      summary: Redirect to /account (non-destructive)
      tags:
        - Email
      description: "Non-destructive: redirects to the /account preferences page where
        the user can manually unsubscribe. We deliberately do NOT delete the
        subscription row from a GET handler because email clients (Gmail Smart
        Linking, link-safety scanners) prefetch URLs in emails — a destructive
        GET would let those prefetchers silently unsubscribe users. The actual
        unsubscribe write happens via the RFC 8058 POST endpoint (one-click from
        Gmail/Yahoo inbox UI) or by the user explicitly unticking a cell on
        /account."
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 256
          in: query
          name: token
          required: true
      responses:
        "302":
          description: Redirect to /account (always 302, never destructive).
    post:
      operationId: unsubscribeViaOneClick
      summary: RFC 8058 one-click unsubscribe (mail-provider POST)
      tags:
        - Email
      description: POST endpoint mail providers hit when the user clicks the inbox
        "Unsubscribe" button. Same effect as the GET version (delete the row)
        but returns 200 with no redirect. Per RFC 8058 we accept the token on
        the querystring and acknowledge the body `List-Unsubscribe=One-Click`
        parameter.
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 256
          in: query
          name: token
          required: true
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
  /v3/organizations/{orgId}/multisigs:
    get:
      operationId: listOrgMultisigs
      summary: List org multisig wallets
      tags:
        - Organizations
      description: List Safe multisig wallets registered to an organization, with
        on-chain owner resolution and attestation status.
      parameters:
        - schema:
            type: string
            format: uuid
          in: path
          name: orgId
          required: true
      security: *a2
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - multisigs
                properties:
                  multisigs:
                    type: array
                    items:
                      type: object
                      required:
                        - id
                        - address
                        - networkId
                        - owners
                        - createdAt
                      properties:
                        id:
                          type: string
                          format: uuid
                        address:
                          type: string
                        networkId:
                          type: string
                        name:
                          type: string
                          nullable: true
                        owners:
                          type: array
                          items:
                            type: object
                            required:
                              - address
                            properties:
                              address:
                                type: string
                              attestation:
                                nullable: true
                                type: object
                                required:
                                  - verifiedAt
                                  - userId
                                properties:
                                  verifiedAt:
                                    type: string
                                    format: date-time
                                  userId:
                                    type: string
                                  userEmail:
                                    type: string
                                    nullable: true
                                  userName:
                                    type: string
                                    nullable: true
                        createdAt:
                          type: string
                          format: date-time
        "400":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Default Response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /health:
    get:
      operationId: getHealth
      summary: Check API health
      tags:
        - Health
      description: Check API health and status
      responses:
        "200":
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: string
                    format: date-time
                  uptime:
                    type: number
                    description: Server uptime in seconds
                  version:
                    type: string
                    example: abc1234
servers:
  - url: https://api.creditcoop.xyz
tags:
  - name: Platform
    description: General platform endpoints
  - name: Borrowers
    description: Borrower management
  - name: Credit Facilities
    description: Credit facility management
  - name: Vault Curators
    description: Vault curator management
  - name: Vaults
    description: Vault management
  - name: Depositors
    description: Depositor portfolio and performance metrics
  - name: Whitelist Requests
    description: Vault whitelist request management
  - name: Ledger
    description: "Typed ledger endpoints: transfers, borrows, repays, cumulative cashflows"
  - name: Benchmarks
    description: Benchmark vault APY rates computed from on-chain snapshots
  - name: Self Report
    description: Self-reported invoice and cashflow data endpoints
  - name: Users
    description: User profile and settings management
  - name: Wallet Attestation
    description: Wallet ownership verification via message signing
  - name: API Keys
    description: API key management
  - name: Health
    description: Health check endpoints
