Euler Finance Earn API

Euler Earn vault resources and historical data. These endpoints are separate from EVK vaults and should be modeled independently in client code.

OpenAPI Specification

euler-earn-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Euler Data API (V3) Accounts Earn 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: Earn
  description: Euler Earn vault resources and historical data. These endpoints are separate from EVK vaults and should be modeled independently in client code.
paths:
  /v3/earn/vaults:
    get:
      tags:
      - Earn
      summary: Earn vaults
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/ChainIdParam'
      - $ref: '#/components/parameters/OffsetParam'
      - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: Earn vaults
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/EarnVaultSummary'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
      operationId: getEarnVaults
  /v3/earn/vaults/batch:
    post:
      tags:
      - Earn
      summary: Earn vault batch
      description: 'Returns earn vault summaries for explicit addresses on one chain.

        Pass `include: ["strategies"]` to add the same strategy objects

        returned by earn vault detail.

        Response preserves request order after address deduplication.

        Request cap: 1000 vault addresses and 256 KiB of JSON body.

        '
      x-status: implemented
      x-cache-ttl: 60
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EarnVaultBatchRequest'
      responses:
        '200':
          description: Earn vault batch
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EarnVaultBatchResponse'
        '400':
          $ref: '#/components/responses/Error400'
        '404':
          $ref: '#/components/responses/Error404'
        '413':
          $ref: '#/components/responses/Error413'
        '415':
          $ref: '#/components/responses/Error415'
        '429':
          $ref: '#/components/responses/Error429'
        '500':
          $ref: '#/components/responses/Error500'
      operationId: postEarnVaultBatch
  /v3/earn/vaults/{chainId}/{address}:
    get:
      tags:
      - Earn
      summary: Earn vault detail
      description: 'Returns earn vault detail. Optional `include` expands related resources.

        Supported values: `apy`, `totals`, `prices`.

        '
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/ChainIdPath'
      - $ref: '#/components/parameters/AddressPath'
      - $ref: '#/components/parameters/IncludeParam'
      responses:
        '200':
          description: Earn vault detail
          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/EarnVaultDetailsWithIncludes'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '400':
          $ref: '#/components/responses/Error400'
        '404':
          $ref: '#/components/responses/Error404'
        '429':
          $ref: '#/components/responses/Error429'
        '500':
          $ref: '#/components/responses/Error500'
      operationId: getEarnVaultsByChainIdByAddress
  /v3/earn/vaults/{chainId}/{address}/events:
    get:
      tags:
      - Earn
      summary: Unified Euler Earn vault event timeline
      description: 'Unified stream of user, interest/reallocation, and governance earn-vault events.

        Requires a bounded time window (`from` + `to`), max 30 days.

        '
      x-status: implemented
      x-cache-ttl: 60
      parameters:
      - $ref: '#/components/parameters/ChainIdPath'
      - $ref: '#/components/parameters/AddressPath'
      - name: from
        in: query
        required: true
        schema:
          type: integer
      - name: to
        in: query
        required: true
        schema:
          type: integer
      - name: type
        in: query
        required: false
        schema:
          type: string
        description: Comma-separated event type filter. Unknown values return 400.
      - $ref: '#/components/parameters/OffsetParam'
      - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: Earn vault events
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        chainId:
                          type: integer
                        type:
                          type: string
                        timestamp:
                          type: string
                          format: date-time
                        blockNumber:
                          type: string
                        txHash:
                          type: string
                        payload:
                          type: object
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '400':
          $ref: '#/components/responses/Error400'
        '404':
          $ref: '#/components/responses/Error404'
        '429':
          $ref: '#/components/responses/Error429'
        '500':
          $ref: '#/components/responses/Error500'
      operationId: getEarnVaultsByChainIdByAddressEvents
components:
  responses:
    Error413:
      description: Request body too large
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Error429:
      description: Rate limited
      headers:
        Retry-After:
          description: Seconds until next request is allowed.
          schema:
            type: integer
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Error415:
      description: Unsupported media type
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Error500:
      description: Internal server error
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    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'
  schemas:
    EarnVaultBatchMeta:
      type: object
      properties:
        count:
          type: integer
        requested:
          type: integer
        notFound:
          type: array
          items:
            type: string
        timestamp:
          type: string
          format: date-time
        chainId:
          type: string
    EarnVaultManagement:
      type: object
      properties:
        owner:
          type: string
        curator:
          type: string
        guardian:
          type: string
        feeRecipient:
          type: string
        timelockSeconds:
          type: integer
          description: Timelock duration in seconds.
        performanceFee:
          type: string
          description: Raw contract performance fee value as a bigint string.
    EarnVaultBatchRequest:
      type: object
      required:
      - chainId
      - addresses
      properties:
        chainId:
          type: integer
        addresses:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            type: string
            maxLength: 42
        include:
          type: array
          items:
            type: string
            enum:
            - strategies
          description: Optional related resources to expand for every returned vault.
    EarnStrategyAllocationCap:
      type: object
      properties:
        current:
          type: string
          description: Raw allocation cap as a bigint string in underlying asset units.
        pending:
          type: string
          description: Pending raw allocation cap as a bigint string in underlying asset units.
        pendingValidAt:
          type: string
          format: date-time
    VaultApy:
      type: object
      properties:
        current:
          $ref: '#/components/schemas/VaultApyPoint'
        history:
          type: array
          items:
            $ref: '#/components/schemas/VaultApyPoint'
    VaultApyPoint:
      type: object
      properties:
        supplyApy:
          type: number
          nullable: true
          description: Percent number with 6 decimal places.
        borrowApy:
          type: number
          description: Percent number with 6 decimal places.
        timestamp:
          type: string
          format: date-time
    EarnVaultBatchResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/EarnVaultBatchItem'
        meta:
          $ref: '#/components/schemas/EarnVaultBatchMeta'
    EarnVaultSummary:
      type: object
      properties:
        chainId:
          type: integer
        address:
          type: string
        name:
          type: string
        symbol:
          type: string
        decimals:
          type: integer
        asset:
          $ref: '#/components/schemas/AssetRef'
        totalAssets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        totalShares:
          type: string
          description: Raw vault share supply as a bigint string.
        lostAssets:
          type: string
          description: Raw lost asset amount as a bigint string.
        exchangeRate:
          type: string
          description: Raw exchange rate as a bigint string.
        totalSupplyUsd:
          type: number
          description: Market USD number for total Earn vault assets.
        availableAssets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        availableAssetsUsd:
          type: number
          description: Market USD number for currently available assets.
        supplyApy:
          type: number
          nullable: true
          description: Public supply APY as a percent number.
        apyCurrent:
          type: number
          nullable: true
          description: Current public APY as a percent number.
        apy7d:
          type: number
          nullable: true
          description: Seven-day public APY as a percent number.
        apy30d:
          type: number
          nullable: true
          description: Thirty-day public APY as a percent number.
        apy90d:
          type: number
          nullable: true
          description: Ninety-day public APY as a percent number.
        utilization:
          type: number
          description: Utilization ratio number.
        strategyCount:
          type: integer
        snapshotTimestamp:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
    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
    VaultTotals:
      type: object
      properties:
        current:
          $ref: '#/components/schemas/VaultTotalsPoint'
        history:
          type: array
          items:
            $ref: '#/components/schemas/VaultTotalsPoint'
    EarnVaultDetailsWithIncludes:
      allOf:
      - $ref: '#/components/schemas/EarnVaultDetails'
      - type: object
        properties:
          apy:
            allOf:
            - $ref: '#/components/schemas/VaultApy'
            nullable: true
          totals:
            allOf:
            - $ref: '#/components/schemas/VaultTotals'
            nullable: true
          prices:
            allOf:
            - $ref: '#/components/schemas/EarnIncludePrices'
            nullable: true
    EarnIncludePrices:
      type: object
      properties:
        asset:
          allOf:
          - $ref: '#/components/schemas/Price'
          nullable: true
    EarnStrategy:
      type: object
      properties:
        address:
          type: string
        vaultType:
          type: string
          enum:
          - evk
          - earn
          - securitize
          - unknown
        symbol:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        decimals:
          type: integer
          nullable: true
        suppliedAssets:
          type: string
          description: Raw underlying asset amount supplied to the strategy.
        withdrawnAssets:
          type: string
          description: Raw underlying asset amount withdrawn from the strategy.
        allocatedAssets:
          type: string
          description: Raw underlying asset amount allocated to the strategy.
        allocatedAssetsUsd:
          type: number
          description: Market USD number for assets allocated to this strategy.
        availableAssets:
          type: string
          description: Raw underlying asset amount available from the strategy.
        inSupplyQueue:
          type: boolean
        inWithdrawQueue:
          type: boolean
        supplyQueueIndex:
          type: integer
          nullable: true
        withdrawQueueIndex:
          type: integer
          nullable: true
        allocationCap:
          $ref: '#/components/schemas/EarnStrategyAllocationCap'
        removableAt:
          type: string
          format: date-time
        status:
          type: string
          enum:
          - active
          - inactive
          - pending_removal
        lastRebalancedAt:
          type: string
          format: date-time
          nullable: true
    Price:
      type: object
      properties:
        chainId:
          type: integer
        address:
          type: string
        symbol:
          type: string
        decimals:
          type: integer
        priceUsd:
          type: number
          description: Market-normalized USD price number. If `source` is `oracle`, this endpoint still exposes the v3 market-price number; use `/v3/oracles/prices` for exact contract-derived oracle values.
        source:
          type: string
        confidence:
          type: number
          nullable: true
        blockNumber:
          type: string
          nullable: true
        timestamp:
          type: string
          format: date-time
    AssetRef:
      type: object
      properties:
        address:
          type: string
        symbol:
          type: string
        decimals:
          type: integer
        name:
          type: string
          nullable: true
    EarnVaultBatchItem:
      allOf:
      - $ref: '#/components/schemas/EarnVaultSummary'
      - type: object
        properties:
          strategies:
            type: array
            items:
              $ref: '#/components/schemas/EarnStrategy'
    EarnVaultDetails:
      allOf:
      - $ref: '#/components/schemas/EarnVaultSummary'
      - type: object
        properties:
          totalShares:
            type: string
            description: Raw vault share supply as a bigint string.
          lostAssets:
            type: string
            description: Raw lost asset amount as a bigint string.
          exchangeRate:
            type: string
            description: Raw exchange rate as a bigint string.
          strategies:
            type: array
            items:
              $ref: '#/components/schemas/EarnStrategy'
          governance:
            $ref: '#/components/schemas/EarnVaultGovernance'
          management:
            $ref: '#/components/schemas/EarnVaultManagement'
    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.
    EarnVaultGovernance:
      type: object
      properties:
        owner:
          type: string
        creator:
          type: string
        curator:
          type: string
        guardian:
          type: string
        feeReceiver:
          type: string
        timelock:
          type: integer
          description: Timelock duration in seconds.
        pendingTimelock:
          type: integer
          description: Pending timelock duration in seconds.
        pendingTimelockValidAt:
          type: string
          format: date-time
        pendingGuardian:
          type: string
        pendingGuardianValidAt:
          type: string
          format: date-time
    VaultTotalsPoint:
      type: object
      properties:
        totalAssets:
          type: string
          description: Raw underlying asset amount as a bigint string.
        totalBorrows:
          type: string
          description: Raw borrowed asset amount as a bigint string.
        cash:
          type: string
          nullable: true
          description: Raw cash amount as a bigint string.
        utilization:
          type: number
          nullable: true
          description: Utilization ratio number.
        supplyApy:
          type: number
          nullable: true
          description: Public supply APY as a percent number.
        borrowApy:
          type: number
          nullable: true
          description: Public borrow APY as a percent number.
        timestamp:
          type: string
          format: date-time
  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
    ChainIdPath:
      name: chainId
      in: path
      required: true
      schema:
        type: integer
    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
    IncludeParam:
      name: include
      in: query
      required: false
      schema:
        type: string
      description: Comma-separated list of related resources to expand. Unknown values are ignored.
    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
  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.