Retrieve a paginated list of DeFi protocols available on a specific blockchain network. Use the chainKey from the Chains endpoint to specify which chain to query.
Endpoint
GET https://api.octav.fi/v1/chains/:chainKey/protocols
Parameters
The chain identifier (e.g. ethereum, solana, arbitrum). Must match a chain’s key field from the Chains endpoint. /v1/chains/ethereum/protocols
Page number for pagination
Number of protocols per page
Response
Returns a paginated list of protocol objects.
Top-Level Fields
Array of protocol objects (see fields below)
Pagination metadata:
page — Current page number
limit — Items per page
hasMore — Whether more pages are available
Protocol Fields
Unique protocol identifier
Protocol key (e.g. "aave", "uniswap v3")
Display name (e.g. "Aave", "Uniswap V3")
URL to small protocol icon
URL to large protocol icon
true if this is a user-created custom protocol. Custom protocols only appear on page 1 and are listed before system protocols.
Example Request
cURL
JavaScript
Python
TypeScript
curl "https://api.octav.fi/v1/chains/ethereum/protocols?page=1&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"data" : [
{
"uuid" : "abc12345-1234-5678-9abc-def012345678" ,
"key" : "aave" ,
"name" : "Aave" ,
"imgSmall" : "https://images.octav.fi/tokens/small/aave_small_icon.png" ,
"imgLarge" : "https://images.octav.fi/tokens/large/aave_large_icon.png" ,
"isUserProtocol" : false
},
{
"uuid" : "def67890-1234-5678-9abc-def012345678" ,
"key" : "uniswap v3" ,
"name" : "Uniswap V3" ,
"imgSmall" : "https://images.octav.fi/tokens/small/uniswap_small_icon.png" ,
"imgLarge" : "https://images.octav.fi/tokens/large/uniswap_large_icon.png" ,
"isUserProtocol" : false
}
],
"pagination" : {
"page" : 1 ,
"limit" : 20 ,
"hasMore" : true
}
}
The endpoint uses page-based pagination. Use page and limit to navigate through results.
Paginating Through All Protocols
Fetch all protocols for a chain by iterating until hasMore is false: async function getAllProtocols ( chainKey ) {
const allProtocols = [];
let page = 1 ;
let hasMore = true ;
while ( hasMore ) {
const response = await fetch (
`https://api.octav.fi/v1/chains/ ${ chainKey } /protocols?page= ${ page } &limit=100` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }
);
const result = await response . json ();
allProtocols . push ( ... result . data );
hasMore = result . pagination . hasMore ;
page ++ ;
}
return allProtocols ;
}
const protocols = await getAllProtocols ( 'ethereum' );
console . log ( `Total protocols on Ethereum: ${ protocols . length } ` );
Use Cases
Protocol Selector
Multi-Chain Protocols
Search Protocols
Build a protocol selection dropdown for your UI: async function loadProtocolOptions ( chainKey ) {
const response = await fetch (
`https://api.octav.fi/v1/chains/ ${ chainKey } /protocols?limit=100` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }
);
const { data : protocols } = await response . json ();
return protocols . map ( protocol => ({
value: protocol . key ,
label: protocol . name ,
icon: protocol . imgSmall ,
isCustom: protocol . isUserProtocol
}));
}
// Populate dropdown when user selects a chain
const options = await loadProtocolOptions ( 'ethereum' );
Find which protocols are available across chains: async function getProtocolsByChains ( chainKeys ) {
const results = {};
for ( const chainKey of chainKeys ) {
const response = await fetch (
`https://api.octav.fi/v1/chains/ ${ chainKey } /protocols?limit=100` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }
);
const { data } = await response . json ();
results [ chainKey ] = data . map ( p => p . key );
}
return results ;
}
const protocols = await getProtocolsByChains ([ 'ethereum' , 'arbitrum' , 'base' ]);
console . log ( 'Ethereum protocols:' , protocols . ethereum . length );
console . log ( 'Arbitrum protocols:' , protocols . arbitrum . length );
Client-side filtering of protocol results: async function searchProtocols ( chainKey , query ) {
// Fetch all protocols (the API does not expose server-side search)
const allProtocols = await getAllProtocols ( chainKey );
const lowerQuery = query . toLowerCase ();
return allProtocols . filter ( p =>
p . name . toLowerCase (). includes ( lowerQuery ) ||
p . key . toLowerCase (). includes ( lowerQuery )
);
}
const results = await searchProtocols ( 'ethereum' , 'uniswap' );
// => [{ name: "Uniswap V2", ... }, { name: "Uniswap V3", ... }]
Error Responses
Invalid query parameters. {
"error" : "Validation Failed" ,
"details" : {
"message" : " \" limit \" must be less than or equal to 100"
}
}
Common causes:
page is less than 1
limit exceeds 100
Authentication failed. {
"error" : "Unauthorized" ,
"message" : "Invalid API key"
}
Solution: Check your API key in the Authorization header
The specified chain key does not exist. {
"message" : "Chain with key 'xyz' not found"
}
Solution: Use the Chains endpoint to discover valid chain keys
Rate limit exceeded. {
"error" : "Rate limit exceeded" ,
"message" : "You have exceeded your rate limit" ,
"retry_after" : 60
}
Solution: Wait for the specified time or implement retry logic