Euler Finance Accounts API

Account activity, discovered positions, and sub-account relationships. Legacy nested account payloads are flattened into account-vault rows in v3.

OpenAPI Specification

euler-accounts-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Euler Data API (V3) Accounts API
  version: 3.0.0
  description: "API specification for Euler Data v3. This spec defines the current\nresource-oriented contract for the platform, with emphasis on consistent\nschemas, predictable REST semantics, caching, observability, and a uniform\ndeveloper experience.\n\nMigration notes\n- Euler Data v3 is not a path-for-path clone of v1/v2. Some endpoints map\n  directly, some require multiple v3 calls, and some legacy aggregates were\n  intentionally removed.\n- The live [migration guide](/v3/docs/migration) explains how legacy v1/v2\n  endpoints and payloads map into the v3 resource model.\n- Important semantic changes:\n  - Vault base APY and rewards APY are exposed separately in v3.\n  - Account positions are flattened into account-vault rows instead of the\n    legacy nested sub-account shape.\n  - All supported API paths live under `/v3`; legacy paths return `410`.\n  - Summary endpoints prefer smaller, focused resources over large\n    BFF-style payloads.\n\nBase path: /v3\n\nConventions\n- JSON field naming: camelCase\n- Addresses: accept lowercase or checksum; responses are EIP-55 checksummed\n- Public APY values (`*Apy`, `apy*`): percent numbers with 6 decimal places (e.g., 5.123456 = 5.123456%)\n- Contract interest-rate fields (`borrowAPY`, `supplyAPY` in `interestRates`): decimal strings in contract fraction units\n- Ratios (utilization, LTV, etc.): numbers with 6 decimal places\n- Response timestamps: ISO-8601 strings (UTC). Some legacy fields still expose unix\n  seconds for compatibility and include `*Iso` companions.\n- Query time ranges: unix seconds (from/to)\n\nUnit policy\n- v3 separates market metadata from contract verdicts by both name and type.\n- Market-normalized USD prices and USD values are JSON numbers. These are values\n  derived from off-chain pricing, cached price snapshots, or API-level market math.\n  This includes `/v3/prices`, token price routes, vault/earn/protocol USD totals,\n  portfolio market values, portfolio USD liquidation/risk fields such as\n  `liabilityValueUsd`, `totalCollateralValueUsd`, `borrowLiquidationPriceUsd`,\n  and `collateralLiquidationPricesUsd`, and vault holder `assetsUsd`.\n- Contract-derived oracle and raw account-liquidity verdict values are exact strings.\n  These preserve the integer value used by contracts, normalized to 18 decimals\n  for API exposure. Oracle prices are quoted in the vault unit of account, which\n  can be USD, ETH, or another asset. This includes `/v3/oracles/prices`, raw\n  account-liquidity `liabilityValue` and `totalCollateralValue` objects,\n  `liabilityValueBorrowing`, `liabilityValueLiquidation`, and collateral verdict\n  values.\n- On-chain token quantities are bigint strings in their native unit scale. This\n  includes amounts, balances, shares, assets, borrows, reward amounts, liquidation\n  repay/yield amounts, and block numbers.\n- Caps are also bigint strings, but EVK caps are exposed as resolved underlying\n  asset-unit amounts rather than packed contract config words.\n- LTV config values use canonical basis-point strings. Legacy decimal aliases\n  may remain on config-history payloads for compatibility when explicitly named.\n\nRate limiting\n- Optional API keys for higher limits\n- Default limits are configurable; current defaults: free tier 100 req/min (IP-based)\n  and authenticated 1000 req/min (per API key), 60s window.\n- By default, proxy headers are not trusted for IP identity unless explicitly enabled.\n- Redis failures default to fail-closed (503) for strict enforcement; fail-open is opt-in.\n- RateLimit-* (IETF draft-6) and legacy X-RateLimit-* headers are returned.\n\nCORS\n- Public API responses use wildcard CORS, including preflight responses for unsafe methods.\n- Unsafe methods with request bodies must use a JSON media type.\n\nCaching\n- Cache-Control headers are returned for cacheable endpoints.\n- Defaults (may be adjusted in config):\n  - Prices: 300s\n  - APYs: 600s\n  - Rewards: 900s\n  - General responses: 60s (short 30s, long 300s)\n\nErrors\n- All errors use a standard envelope: { error: { code, message, requestId, details? } }\n- Domain error codes are documented in this spec.\n- JSON request bodies must use `Content-Type: application/json` or another `application/*+json` media type.\n- Request bodies larger than 1 MiB are rejected before route parsing with `413 PAYLOAD_TOO_LARGE`.\n"
servers:
- url: /
  description: Current environment
security: []
tags:
- name: Accounts
  description: Account activity, discovered positions, and sub-account relationships. Legacy nested account payloads are flattened into account-vault rows in v3.
paths:
  /v3/accounts/{address}/portfolio:
    get:
      tags:
      - Accounts
      summary: Account portfolio
      description: 'Returns a position-first portfolio view for an owner on a single chain.

        The backend builds SDK Account and Portfolio entities from internal V3

        account, vault, price, and label data sources; it does not recursively

        call `/v3/accounts/{address}/positions`. When `forceFresh=true`, the

        endpoint enqueues or promotes account snapshot refresh work and waits

        briefly for refreshed snapshots before falling back to the current

        indexed portfolio view. Freshness metadata indicates whether the refresh

        completed, timed out, or was rate-limited.

        '
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/AddressPath'
      - name: chainId
        in: query
        required: true
        schema:
          type: integer
        description: Chain ID. Exactly one chain is required.
      - name: labeledVaultsOnly
        in: query
        required: false
        schema:
          type: boolean
        description: Filter positions to the product-facing labeled vault universe.
      - name: includeAccount
        in: query
        required: false
        schema:
          type: boolean
        description: Include the backing SDK account-shaped payload for debugging and migration.
      - name: forceFresh
        in: query
        required: false
        schema:
          type: boolean
        description: 'When true, enqueue or promote account snapshot refresh for discovered tuples.

          The endpoint waits briefly for refreshed snapshots before falling back to

          the current indexed portfolio view. Inspect `data.freshness` for completion,

          timeout, rate-limit, and fallback metadata.

          '
      responses:
        '200':
          description: Account portfolio
          headers:
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/AccountPortfolioResponse'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '400':
          $ref: '#/components/responses/Error400'
        '404':
          $ref: '#/components/responses/Error404'
      operationId: getAccountsByAddressPortfolio
  /v3/accounts/{address}/positions:
    get:
      tags:
      - Accounts
      summary: Account positions across chains
      description: 'Returns paginated account positions across the selected chain scope.

        Uses `meta.hasMore` for pagination continuation on the hot path rather than an exact `meta.total`.

        '
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/AddressPath'
      - $ref: '#/components/parameters/ChainIdParam'
      - $ref: '#/components/parameters/OffsetParam'
      - $ref: '#/components/parameters/LimitParam'
      - name: forceFresh
        in: query
        required: false
        schema:
          type: boolean
        description: 'When true, trigger bounded synchronous account snapshot refresh for the returned tuples.

          On timeout/failure, response safely falls back to stored snapshots and indicates cached mode in freshness metadata.

          '
      responses:
        '200':
          description: Account positions
          headers:
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccountPosition'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
                  freshness:
                    type: object
                    properties:
                      latestSnapshotTimestamp:
                        type: string
                        format: date-time
                        nullable: true
                      ageSeconds:
                        type: integer
                        nullable: true
                      timestamp:
                        type: string
                        format: date-time
                      mode:
                        type: string
                        enum:
                        - fresh
                        - cached
                      forceFreshRequested:
                        type: boolean
                      refreshTriggered:
                        type: boolean
                      refreshCompleted:
                        type: boolean
                      timedOut:
                        type: boolean
                      rateLimited:
                        type: boolean
                      fallbackReason:
                        type: string
                        nullable: true
                      waitedMs:
                        type: integer
      operationId: getAccountsByAddressPositions
  /v3/accounts/{address}/activity:
    get:
      tags:
      - Accounts
      summary: Account vault activity discovery
      description: 'Discovers vault tuples an account interacts with (shares and/or controller-enabled debt),

        including sub-accounts when available.

        Uses `meta.hasMore` for pagination continuation on the hot path rather than an exact `meta.total`.

        '
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/AddressPath'
      - $ref: '#/components/parameters/ChainIdParam'
      - $ref: '#/components/parameters/OffsetParam'
      - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: Account activity
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccountActivity'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
      operationId: getAccountsByAddressActivity
  /v3/accounts/{address}/sub-accounts:
    get:
      tags:
      - Accounts
      summary: Sub-accounts for an EVC-enabled account
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/AddressPath'
      - name: chainId
        in: query
        required: true
        schema:
          type: string
        description: Comma-separated list of chain IDs (single value allowed).
        example: '1'
      - $ref: '#/components/parameters/OffsetParam'
      - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: Sub-accounts
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/SubAccount'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
      operationId: getAccountsByAddressSubAccounts
components:
  schemas:
    AccountPosition:
      type: object
      properties:
        chainId:
          type: integer
        account:
          type: string
        vault:
          type: string
        vaultType:
          type: string
          enum:
          - evk
          - earn
          - securitize
        asset:
          type: string
          nullable: true
        shares:
          type: string
          nullable: true
          description: Raw vault share amount as a bigint string.
        assets:
          type: string
          nullable: true
          description: Raw underlying asset amount as a bigint string.
        borrowed:
          type: string
          nullable: true
          description: Raw borrowed asset amount as a bigint string.
        assetsValue:
          type: string
          nullable: true
          description: Contract-derived account-liquidity asset value, raw 18-decimal bigint string.
        debtValue:
          type: string
          nullable: true
          description: Contract-derived account-liquidity debt value, raw 18-decimal bigint string.
        isCollateral:
          type: boolean
          nullable: true
        balanceForwarderEnabled:
          type: boolean
          nullable: true
        isController:
          type: boolean
          nullable: true
        liquidity:
          $ref: '#/components/schemas/AccountPositionLiquidity'
        subAccount:
          type: object
          nullable: true
          properties:
            owner:
              type: string
              nullable: true
            timestamp:
              type: string
              format: date-time
              nullable: true
            lastAccountStatusCheckTimestamp:
              type: string
              format: date-time
              nullable: true
            enabledControllers:
              type: array
              nullable: true
              items:
                type: string
            enabledCollaterals:
              type: array
              nullable: true
              items:
                type: string
            isLockdownMode:
              type: boolean
              nullable: true
            isPermitDisabledMode:
              type: boolean
              nullable: true
        snapshot:
          type: object
          properties:
            timestamp:
              type: string
              format: date-time
              nullable: true
            ageSeconds:
              type: integer
              nullable: true
            source:
              type: string
              nullable: true
            method:
              type: string
              nullable: true
    YieldApyBreakdown:
      type: object
      properties:
        lending:
          type: number
          description: Lending APY contribution as a percent number.
        borrowing:
          type: number
          description: Borrowing APY contribution as a percent number.
        rewards:
          type: number
          description: Rewards APY contribution as a percent number.
        intrinsicApy:
          type: number
          description: Intrinsic APY contribution as a percent number.
        total:
          type: number
          description: Total APY as a percent number.
    SerializedPortfolioVault:
      type: object
      properties:
        address:
          type: string
        type:
          type: string
          enum:
          - evk
          - earn
          - securitize
          - unknown
        asset:
          type: object
          properties:
            address:
              type: string
            symbol:
              type: string
            decimals:
              type: integer
            name:
              type: string
        shares:
          type: object
          properties:
            address:
              type: string
            symbol:
              type: string
            decimals:
              type: integer
            name:
              type: string
        supplyApy:
          type: number
          description: Public supply APY as a percent number.
        borrowApy:
          type: number
          description: Public borrow APY as a percent number.
        supplyApy1h:
          type: number
          description: One-hour public supply APY as a percent number.
        strategyCount:
          type: integer
    SubAccount:
      type: object
      required:
      - chainId
      - owner
      - addressPrefix
      - blockNumber
      - timestamp
      properties:
        chainId:
          type: integer
        owner:
          type: string
        addressPrefix:
          type: string
        blockNumber:
          type: string
        timestamp:
          type: string
          format: date-time
    SerializedPortfolioAccountPosition:
      type: object
      properties:
        account:
          type: string
        vaultAddress:
          type: string
        vault:
          $ref: '#/components/schemas/SerializedPortfolioVault'
        asset:
          type: string
        shares:
          type: string
          description: Raw vault share amount as a bigint string.
        assets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        borrowed:
          type: string
          description: Raw borrowed asset amount as a bigint string.
        isController:
          type: boolean
        isCollateral:
          type: boolean
        balanceForwarderEnabled:
          type: boolean
        marketPriceUsd:
          type: number
          description: Market USD price number for this position's asset.
        suppliedValueUsd:
          type: number
          description: Market USD value number for this supplied position.
        borrowedValueUsd:
          type: number
          description: Market USD value number for this borrowed position.
        liquidity:
          $ref: '#/components/schemas/AccountPositionLiquidity'
        borrowLiquidationPriceUsd:
          type: number
          description: Borrow liquidation price in USD.
        collateralLiquidationPricesUsd:
          type: object
          description: Liquidation prices in USD keyed by collateral address.
          additionalProperties:
            type: number
    ErrorResponse:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          - requestId
          properties:
            code:
              type: string
              description: 'Domain error code. Examples:

                - INVALID_ADDRESS

                - CHAIN_NOT_SUPPORTED

                - VAULT_NOT_FOUND

                - TOKEN_NOT_FOUND

                - ACCOUNT_NOT_FOUND

                - VALIDATION_ERROR

                - RATE_LIMIT_EXCEEDED

                - UNSUPPORTED_MEDIA_TYPE

                - UNAUTHORIZED

                - FORBIDDEN

                - INTERNAL_ERROR

                '
            message:
              type: string
            requestId:
              type: string
            details:
              type: object
              additionalProperties: true
    DataIssue:
      type: object
      properties:
        code:
          type: string
        severity:
          type: string
          enum:
          - info
          - warning
          - error
        message:
          type: string
        locations:
          type: array
          items:
            type: object
            properties:
              owner:
                type: object
                additionalProperties: true
              path:
                type: string
        source:
          type: string
        originalValue: {}
        normalizedValue: {}
    AccountPortfolioResponse:
      type: object
      properties:
        chainId:
          type: integer
        owner:
          type: string
        portfolio:
          type: object
          properties:
            savings:
              type: array
              items:
                $ref: '#/components/schemas/PortfolioSavingsPosition'
            borrows:
              type: array
              items:
                $ref: '#/components/schemas/PortfolioBorrowPosition'
            positions:
              type: array
              items:
                $ref: '#/components/schemas/SerializedPortfolioAccountPosition'
            managedLending:
              type: array
              items:
                $ref: '#/components/schemas/PortfolioSavingsPosition'
            directLending:
              type: array
              items:
                $ref: '#/components/schemas/PortfolioSavingsPosition'
            totals:
              type: object
              properties:
                suppliedValueUsd:
                  type: number
                  description: Market USD number for total supplied value.
                borrowedValueUsd:
                  type: number
                  description: Market USD number for total borrowed value.
                netAssetValueUsd:
                  type: number
                  description: Market USD number for supplied minus borrowed value.
                netApy:
                  type: number
                  description: Public net APY as a percent number.
                roe:
                  type: number
                  description: Return-on-equity ratio number.
                apyBreakdown:
                  $ref: '#/components/schemas/YieldApyBreakdown'
                roeBreakdown:
                  $ref: '#/components/schemas/YieldApyBreakdown'
        account:
          type: object
          nullable: true
          additionalProperties: true
        errors:
          type: array
          items:
            $ref: '#/components/schemas/DataIssue'
        freshness:
          type: object
          properties:
            latestSnapshotTimestamp:
              type: integer
              nullable: true
            ageSeconds:
              type: integer
              nullable: true
            timestamp:
              type: string
              format: date-time
            mode:
              type: string
              enum:
              - fresh
              - cached
            forceFreshRequested:
              type: boolean
            refreshTriggered:
              type: boolean
            refreshCompleted:
              type: boolean
            timedOut:
              type: boolean
            rateLimited:
              type: boolean
            fallbackReason:
              type: string
              nullable: true
            waitedMs:
              type: integer
    AccountPositionLiquidity:
      type: object
      nullable: true
      properties:
        vaultAddress:
          type: string
        unitOfAccount:
          type: string
        daysToLiquidation:
          oneOf:
          - type: integer
          - type: string
            enum:
            - Infinity
            - MoreThanAYear
        liabilityValue:
          $ref: '#/components/schemas/AccountLiquidityValue'
        totalCollateralValue:
          $ref: '#/components/schemas/AccountLiquidityValue'
        collaterals:
          type: array
          items:
            type: object
            properties:
              address:
                type: string
              value:
                $ref: '#/components/schemas/AccountLiquidityValue'
              marketPriceUsd:
                type: number
                description: Market USD price number for the collateral asset.
              valueUsd:
                type: number
                description: Market USD value number for this collateral.
        liabilityValueUsd:
          type: number
          description: Market USD liability value number.
        totalCollateralValueUsd:
          type: number
          description: Market USD collateral value number.
    PortfolioSavingsPosition:
      type: object
      properties:
        position:
          $ref: '#/components/schemas/SerializedPortfolioAccountPosition'
        vault:
          $ref: '#/components/schemas/SerializedPortfolioVault'
        subAccount:
          type: string
        shares:
          type: string
          description: Raw vault share amount as a bigint string.
        assets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        suppliedValueUsd:
          type: number
          description: Market USD value number for this savings position.
        apy:
          type: number
          description: Public APY as a percent number.
        apyBreakdown:
          $ref: '#/components/schemas/YieldApyBreakdown'
    PortfolioBorrowPosition:
      type: object
      properties:
        borrow:
          $ref: '#/components/schemas/SerializedPortfolioAccountPosition'
        collaterals:
          type: array
          items:
            $ref: '#/components/schemas/SerializedPortfolioAccountPosition'
        collateral:
          $ref: '#/components/schemas/SerializedPortfolioAccountPosition'
        borrowVault:
          $ref: '#/components/schemas/SerializedPortfolioVault'
        collateralVault:
          $ref: '#/components/schemas/SerializedPortfolioVault'
        collateralVaults:
          type: array
          items:
            type: string
        subAccount:
          type: string
        healthFactor:
          type: string
        userLTV:
          type: string
          description: Contract-derived account LTV ratio, raw 18-decimal bigint string.
        currentLTV:
          type: string
          description: Contract-derived current LTV ratio, raw 18-decimal bigint string.
        borrowed:
          type: string
          description: Raw borrowed asset amount as a bigint string.
        supplied:
          type: string
          description: Raw supplied asset amount as a bigint string.
        price:
          type: number
          description: Borrow liquidation price in USD.
        borrowLiquidationPriceUsd:
          type: number
          description: Borrow liquidation price in USD.
        collateralLiquidationPricesUsd:
          type: object
          description: Liquidation prices in USD keyed by collateral address.
          additionalProperties:
            type: number
        borrowLTV:
          type: number
          description: Borrow LTV ratio number.
        liquidationLTV:
          type: number
          description: Liquidation LTV ratio number.
        accountLiquidationLTV:
          type: number
          description: Account liquidation LTV ratio number.
        liabilityValueBorrowing:
          type: string
          description: Contract-derived liability value for borrowing, raw 18-decimal bigint string.
        liabilityValueLiquidation:
          type: string
          description: Contract-derived liability value for liquidation, raw 18-decimal bigint string.
        liabilityValueUsd:
          type: number
          description: Market USD liability value number.
        totalCollateralValueUsd:
          type: number
          description: Market USD total collateral value number.
        collateralValueLiquidation:
          type: string
          description: Contract-derived collateral liquidation value, raw 18-decimal bigint string.
        timeToLiquidation:
          oneOf:
          - type: integer
          - type: string
            enum:
            - Infinity
            - MoreThanAYear
        multiplier:
          type: number
          description: Leverage multiplier ratio number.
        netApy:
          type: number
          description: Public net APY as a percent number.
        roe:
          type: number
          description: Return-on-equity ratio number.
        apyBreakdown:
          $ref: '#/components/schemas/YieldApyBreakdown'
        roeBreakdown:
          $ref: '#/components/schemas/YieldApyBreakdown'
    AccountActivity:
      type: object
      properties:
        type:
          type: string
        chainId:
          type: integer
        vault:
          type: string
        assets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        shares:
          type: string
          description: Raw vault share amount as a bigint string.
        txHash:
          type: string
        blockNumber:
          type: string
        timestamp:
          type: string
          format: date-time
    PaginationMeta:
      type: object
      required:
      - timestamp
      properties:
        total:
          type: integer
          description: Exact total count when the endpoint provides one.
        hasMore:
          type: boolean
          description: Indicates whether another page exists beyond the current page.
        offset:
          type: integer
        limit:
          type: integer
          description: Echoed page size after endpoint-side clamping.
        timestamp:
          type: string
          format: date-time
        chainId:
          type: string
          description: Comma-separated chain IDs for multi-chain responses.
    AccountLiquidityValue:
      type: object
      description: Contract-derived account-liquidity value in unit-of-account terms; each field is a raw 18-decimal bigint string.
      properties:
        borrowing:
          type: string
          description: Borrowing value, raw 18-decimal bigint string.
        liquidation:
          type: string
          description: Liquidation value, raw 18-decimal bigint string.
        oracleMid:
          type: string
          description: Oracle midpoint value, raw 18-decimal bigint string.
  headers:
    X-Request-Id:
      description: Request identifier for tracing.
      schema:
        type: string
    Cache-Control:
      description: Cache policy for this response.
      schema:
        type: string
  parameters:
    OffsetParam:
      name: offset
      in: query
      required: false
      schema:
        type: integer
        default: 0
    AddressPath:
      name: address
      in: path
      required: true
      schema:
        type: string
    ChainIdParam:
      name: chainId
      in: query
      required: false
      schema:
        type: string
      description: Comma-separated list of chain IDs (single value allowed).
      example: 1,10,8453
    LimitParam:
      name: limit
      in: query
      required: false
      description: Requested page size. Values above the endpoint cap are clamped; the default shared cap is 100.
      schema:
        type: integer
        default: 20
        maximum: 100
  responses:
    Error400:
      description: Bad request
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Error404:
      description: Not found
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key authentication (optional; higher rate limits).
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Alternative to X-API-Key using Authorization: Bearer <key>'
    AdminSecret:
      type: apiKey
      in: header
      name: X-Admin-Secret
      description: Admin secret (server-to-server) for API key management.
    PlatformSession:
      type: apiKey
      in: cookie
      name: euler_platform_session
      description: Signed, httpOnly platform-operator browser session cookie.
    PlatformCsrf:
      type: apiKey
      in: header
      name: X-CSRF-Token
      description: Double-submit CSRF token required for unsafe cookie-authenticated methods.