API Documentation

    The pigi.finance Data API (v1) gives programmatic access to the same DeFi vault data that powers this site — current metrics, daily history, and aggregated stats. All responses are JSON and CORS is open, so you can call it from a server or a browser.

    Need a key? Request access on the API page. You'll receive a key like pigi_live_….

    Base URL
    https://pigi.finance/api/v1

    Machine-readable spec: OpenAPI 3 (openapi.yaml) — import it into Postman, Swagger UI, or your codegen of choice.

    Authentication

    Auth is a two-step API key → token exchange. Your long-lived API key is secret; you trade it for a short-lived JWT (≈1 hour) and send that as a Bearer token on every request. When the token expires, exchange the key again.

    # 1. Exchange your API key for a short-lived token
    curl -X POST https://pigi.finance/api/v1/auth/token \
      -H "Content-Type: application/json" \
      -d '{"apiKey":"pigi_live_xxxxxxxxxxxxxxxx"}'
    
    # → { "token": "<JWT>", "expiresIn": 3600, "plan": "free" }
    
    # 2. Call any data endpoint with the token
    curl "https://pigi.finance/api/v1/vaults?limit=5" \
      -H "Authorization: Bearer <JWT>"

    Keep your API key server-side. The short-lived token is safe to use from the browser. A token from this API can't be used on any other pigi endpoint and vice-versa.

    Endpoints

    POST/api/v1/auth/tokenNo auth

    Exchange an API key for a short-lived bearer token.

    Request body (JSON)

    ParameterTypeDescription
    apiKeystringYour secret API key.

    Response

    { "token": "<JWT>", "expiresIn": 3600, "plan": "free" }
    GET/api/v1/vaultsBearer token

    List vaults with optional filters and pagination.

    Query parameters (all optional)

    ParameterTypeDescription
    protocol_namestringFilter by protocol (e.g. Aave, Morpho, Euler, Uniswap).
    chain_idnumberFilter by chain id (e.g. 1, 8453, 42161).
    strategy_idnumberFilter by a strategy (compat) id.
    tvl_filterstringTVL band, e.g. gte_1m, gte_5m, non_na, na.
    apr_filterstringAPR band, e.g. gt_5, gt_10, lte_10, non_na, na.
    age_filterstringPool age, e.g. new, 3mo, 6mo, 12mo, non_na, na.
    limitnumberPage size. Default 100, max 1000.
    offsetnumberRows to skip. Default 0.

    Response

    {
      "data": [ { /* Vault */ } ],
      "pagination": { "total": 1342, "limit": 100, "offset": 0, "hasMore": true },
      "availableFilters": { "protocol_names": [...], "chain_ids": {...}, "all_chain_ids": [...] }
    }
    GET/api/v1/vaults/:idBearer token

    Fetch a single vault by its pool id. Returns 404 if not found.

    Response

    { "data": { /* Vault */ } }
    GET/api/v1/vaults/:id/historyBearer token

    Daily time-series for a vault. Here :id is the strategy id (strategy_id on the Vault object).

    Query parameters

    ParameterTypeDescription
    rangestringWindow: 7D, 30D, 90D, or 180D. Default 7D.

    Response

    {
      "data": [
        { "timestamp": "2026-06-23T00:00:00Z", "tvl": 12500000, "apr": 6.21,
          "apy": 6.40, "ra_apr": 5.11, "tvl_30d_ma": 12100000, "apr_30d_ma": 6.05 }
      ],
      "lastTvl": 12500000, "lastApr": 6.21, "lastApy": 6.40, "lastRaApr": 5.11,
      "lastTvl30dMa": 12100000, "lastApr30dMa": 6.05, "lastRaApr30dMa": 4.95
    }

    ra_apr is risk-adjusted APR (APR minus the strategy's risk score); it is null when no risk score is set.

    GET/api/v1/vaults/:id/statsBearer token

    Aggregated stats over fixed windows for a vault (:id = strategy id). Omit period to get all windows.

    Query parameters

    ParameterTypeDescription
    periodstringweekly, monthly, quarterly, or yearly (optional).

    Response

    {
      "weekly":  { "tvl_low": 11.8e6, "tvl_high": 12.6e6, "apr": 6.1, "apy": 6.3,
                   "period_start": "...", "period_end": "..." },
      "monthly": { ... }, "quarterly": { ... }, "yearly": { ... }
    }
    GET/api/v1/usageBearer token

    Your request count for the current calendar month (UTC) and your plan limit.

    Response

    {
      "clientId": 1, "plan": "free",
      "period": { "start": "2026-06-01T00:00:00Z", "end": "2026-07-01T00:00:00Z" },
      "used": 1423, "limit": 100000, "remaining": 98577
    }

    limit and remaining are null when your plan has no cap.

    GET/api/v1No auth

    Discovery index — lists the available endpoints and the docs URL.

    The Vault object

    Returned by /vaults and /vaults/:id.

    ParameterTypeDescription
    idnumberPool id (use for /vaults/:id).
    strategy_idnumberStrategy id (use for /history and /stats).
    protocol_namestringProtocol, e.g. Aave, Morpho, Euler.
    chain_idnumberChain id.
    pool_namestringHuman-readable vault/pool name.
    pool_addressstringOn-chain pool/vault address.
    asset_addressstring | nullUnderlying asset address.
    typestringPool-type category (Lending, AMM, …).
    tvl_30d_manumber30-day moving-average TVL (USD).
    apr_30d_manumber30-day moving-average APR (%).
    holdersnumber | nullHolder count.
    pool_creation_datestring | nullISO date the pool was created.
    updated_atstring | nullBlock-time of the newest data point.
    tvl_flow_1dnumber | null1-day TVL flow.
    tvl_flow_7dnumber | null7-day TVL flow.
    apr_trend_1dnumber | null1-day APR trend.

    Errors & conventions

    Errors are JSON: { "error": "<code>" }. Successful data responses are cached for 5 minutes (Cache-Control: public, max-age=300); auth and usage responses are never cached. Every authenticated request counts toward your monthly usage.

    ParameterTypeDescription
    400missing_api_key / invalid_idMalformed request.
    401invalid_api_key / invalid_tokenBad key on exchange, or missing/expired token.
    403client_suspendedYour API client is suspended.
    404not_foundNo vault with that id.
    405method_not_allowedWrong HTTP method for the route.
    500internal_errorUnexpected server error.