Computing Units
Every Open API endpoint advertises a per-call cost called a Computing Unit (CU). CU is how Pendle meters the work each request does and enforces fair-use against high-frequency consumers.
Budget
Two fixed-window buckets per IP, both must have capacity for a call to succeed:
| Window | Limit |
|---|---|
| 1 minute | 200 CU |
| 1 week | 400,000 CU |
Every successful call deducts its x-computing-unit cost from both buckets. The minute bucket refills every 60s; the weekly bucket refills every 168h.
When either budget is exhausted the API returns HTTP 429 with body { "statusCode": 429, "message": "ThrottlerException: Too Many Requests" }. Wait for the next window before retrying.
Endpoint-Specific Throttles
A few endpoints have additional per-IP throttles on top of the CU budget:
| Endpoint | Extra throttle |
|---|---|
GET /v1/indicators/export | 3 requests/minute/IP |
Higher Rate Limits via API Key
If your integration needs more than the per-IP free-tier limits, paid plans are available through the Boros API Dashboard.
Getting an API key
- Go to https://api-boros.pendle.finance/dashboard
- Connect your wallet and sign the verification message to log in
- Choose a plan and create a new API key
Save the generated key securely — you'll need it to authenticate your requests.
Using your API key
Include your key as a Bearer token in the Authorization header on every request:
Authorization: Bearer <API_KEY>
Example:
curl -i -H "Authorization: Bearer your_api_key_here" \
https://api-boros.pendle.finance/apis/v1/markets
Authenticated requests are billed against your plan's higher limits instead of the per-IP free-tier budget.
Where CU is Reported
| Surface | Format |
|---|---|
| OpenAPI spec | x-computing-unit extension on every operation. Static endpoints publish a number ("1", "2", "20"); dynamic endpoints publish a number with a + suffix ("1+", "3+"). |
| HTTP response | x-computing-unit response header on every successful call. For dynamic endpoints, the header reports the actual CU charged for that specific request. |
The redesigned interactive docs at api-boros.pendle.finance/apis/docs display the published cost next to every endpoint.
Static vs Dynamic Cost
Static ("N")
The endpoint always charges N CU per call regardless of parameters. Examples:
| Endpoint | CU |
|---|---|
GET /v1/assets | 1 |
GET /v1/markets | 2 |
GET /v1/markets/order-book | 2 |
GET /v1/on-chain-events | 3 |
GET /v1/indicators/export | 20 |
| Any single calldata-builder POST | 1 |
Dynamic ("N+")
The endpoint charges at least N (the minimum, billed for an empty / default request) and scales with the work performed. The actual cost is reported in the response header. Common scaling axes:
- Page size — list endpoints charge proportionally to
limit. Example:GET /v1/events/liquidation-eventsismax(1, ceil(limit / 200)). - Batch size — multi-item endpoints charge 1 CU per 10 items. Example:
POST /v1/funding-rate/settlement-summaryismax(1, ceil(settlementSummary.length / 10));POST /v1/calldata-builder/agent/place-ordersismax(1, ceil(orderRequests.length / 10)). - Number of indicators —
GET /v1/indicatorscharges 1 CU per indicator listed inselect. Audma:7;30entry counts as one indicator regardless of how many windows are packed in. makerlookup flag —GET /v1/incentives/maker-incentives/campaigns/{marketId}is 1 CU withoutmaker, 2 CU withmaker.
The minimum-and-grow pattern means callers paying only for what they use — passing fewer items / indicators is cheaper.
Reading the Header in Practice
const res = await axios.get(`${BASE_URL}/v1/indicators`, {
params: { marketId: 1, timeFrame: '1h', select: 'u,fp,fgi,udma:7;30' },
});
const cuCharged = Number(res.headers['x-computing-unit']); // e.g. "4"
For dynamic endpoints, you can sum the header over a window to reason about total compute spent.
Tips
- Static endpoints are cheap. The vast majority of read endpoints are 1 CU. Build dashboards against them without worrying about cost.
- Batch where possible.
POST /v1/accounts/market-acc-infosaccepts up to 100marketAccsin one request;GET /v1/markets/by-idsandGET /v1/amm/stateslikewise accept comma-separated IDs. One batched call is far cheaper than N individual calls. - Prefer streaming for long histories. For multi-day indicator windows,
GET /v1/indicators/exportis a flat 20 CU regardless of the indicators selected — much cheaper than hammering/v1/indicatorsrepeatedly. - Calldata batching is cheap. A
place-ordersrequest with up to 10orderRequests[]entries is 1 CU; cost grows by 1 per additional 10 entries.