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_….
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
/api/v1/auth/tokenNo authExchange an API key for a short-lived bearer token.
Request body (JSON)
| Parameter | Type | Description |
|---|---|---|
| apiKey | string | Your secret API key. |
Response
{ "token": "<JWT>", "expiresIn": 3600, "plan": "free" }/api/v1/vaultsBearer tokenList vaults with optional filters and pagination.
Query parameters (all optional)
| Parameter | Type | Description |
|---|---|---|
| protocol_name | string | Filter by protocol (e.g. Aave, Morpho, Euler, Uniswap). |
| chain_id | number | Filter by chain id (e.g. 1, 8453, 42161). |
| strategy_id | number | Filter by a strategy (compat) id. |
| tvl_filter | string | TVL band, e.g. gte_1m, gte_5m, non_na, na. |
| apr_filter | string | APR band, e.g. gt_5, gt_10, lte_10, non_na, na. |
| age_filter | string | Pool age, e.g. new, 3mo, 6mo, 12mo, non_na, na. |
| limit | number | Page size. Default 100, max 1000. |
| offset | number | Rows to skip. Default 0. |
Response
{
"data": [ { /* Vault */ } ],
"pagination": { "total": 1342, "limit": 100, "offset": 0, "hasMore": true },
"availableFilters": { "protocol_names": [...], "chain_ids": {...}, "all_chain_ids": [...] }
}/api/v1/vaults/:idBearer tokenFetch a single vault by its pool id. Returns 404 if not found.
Response
{ "data": { /* Vault */ } }/api/v1/vaults/:id/historyBearer tokenDaily time-series for a vault. Here :id is the strategy id (strategy_id on the Vault object).
Query parameters
| Parameter | Type | Description |
|---|---|---|
| range | string | Window: 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.
/api/v1/vaults/:id/statsBearer tokenAggregated stats over fixed windows for a vault (:id = strategy id). Omit period to get all windows.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| period | string | weekly, 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": { ... }
}/api/v1/usageBearer tokenYour 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.
/api/v1No authDiscovery index — lists the available endpoints and the docs URL.
The Vault object
Returned by /vaults and /vaults/:id.
| Parameter | Type | Description |
|---|---|---|
| id | number | Pool id (use for /vaults/:id). |
| strategy_id | number | Strategy id (use for /history and /stats). |
| protocol_name | string | Protocol, e.g. Aave, Morpho, Euler. |
| chain_id | number | Chain id. |
| pool_name | string | Human-readable vault/pool name. |
| pool_address | string | On-chain pool/vault address. |
| asset_address | string | null | Underlying asset address. |
| type | string | Pool-type category (Lending, AMM, …). |
| tvl_30d_ma | number | 30-day moving-average TVL (USD). |
| apr_30d_ma | number | 30-day moving-average APR (%). |
| holders | number | null | Holder count. |
| pool_creation_date | string | null | ISO date the pool was created. |
| updated_at | string | null | Block-time of the newest data point. |
| tvl_flow_1d | number | null | 1-day TVL flow. |
| tvl_flow_7d | number | null | 7-day TVL flow. |
| apr_trend_1d | number | null | 1-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.
| Parameter | Type | Description |
|---|---|---|
| 400 | missing_api_key / invalid_id | Malformed request. |
| 401 | invalid_api_key / invalid_token | Bad key on exchange, or missing/expired token. |
| 403 | client_suspended | Your API client is suspended. |
| 404 | not_found | No vault with that id. |
| 405 | method_not_allowed | Wrong HTTP method for the route. |
| 500 | internal_error | Unexpected server error. |