Make the Octav API easily discoverable and usable by AI agents, LLMs, and autonomous programs through standardized documentation formats.
llms.txt Standard - We support the llms.txt format for LLM-friendly documentation
Agent Skill (Recommended)
The fastest way to integrate Octav into any AI agent. Install the official skill and your agent instantly knows the full API:
npx skills add Octav-Labs/octav-api-skill
Works with Claude Code, Codex, ChatGPT, and any agent that supports the Agent Skills standard.
The skill covers all endpoints, authentication, pagination patterns, TypeScript types, error handling, and credit optimization — no need to paste documentation manually.
What are AI Agents?
AI agents are autonomous programs designed to carry out specific tasks or simulations with a degree of independence. They can:
Process inputs and execute logic
Interact with APIs and external services
Make decisions based on data
Achieve predefined goals autonomously
Common Use Cases
Portfolio Assistants AI agents that help users:
Track portfolio performance
Get balance updates
Analyze DeFi positions
Receive alerts on changes
Trading Bots Automated trading systems that:
Monitor wallet activity
Track transaction patterns
Analyze on-chain behavior
Generate trading signals
Analytics Agents Data analysis tools that:
Aggregate cross-chain data
Calculate metrics
Identify trends
Generate reports
Notification Systems Alert systems that:
Watch for transactions
Monitor balances
Detect anomalies
Send notifications
LLMs.txt Integration
The llms.txt format makes web content easily parsable by Large Language Models. Access Octav’s LLM-friendly documentation:
https://api-docs.octav.fi/llms.txt
Point your AI agent or LLM to this URL to automatically understand the Octav API structure and capabilities
What’s Included
The llms.txt file contains:
API Overview - Introduction and key features
Authentication - How to access the API
Endpoints - All available endpoints with descriptions
Data Models - Response structures and types
Code Examples - Usage patterns
Best Practices - Integration guidelines
Quick Start for AI Agents
Load Documentation
Fetch and parse the llms.txt documentation: import requests
# Load LLM-friendly docs
docs = requests.get( 'https://api-docs.octav.fi/llms.txt' ).text
# Feed to your LLM
prompt = f """
Using this API documentation:
{ docs }
How can I get the portfolio for address 0x123...?
"""
Get API Key
Obtain authentication credentials:
Sign up at data.octav.fi
Generate an API key
Purchase credits for API calls
Make API Calls
Use the API in your agent: # Example: Portfolio checking agent
def check_portfolio ( address , api_key ):
headers = { 'Authorization' : f 'Bearer { api_key } ' }
response = requests.get(
f 'https://api.octav.fi/v1/portfolio?addresses= { address } ' ,
headers = headers
)
return response.json()
# Agent logic
portfolio = check_portfolio( '0x123...' , API_KEY )
networth = portfolio[ 0 ][ 'networth' ]
print ( f "Portfolio value: $ { networth } " )
Handle Responses
Process data intelligently: def analyze_portfolio ( portfolio_data ):
data = portfolio_data[ 0 ]
analysis = {
'total_value' : float (data[ 'networth' ]),
'chains' : list (data[ 'chains' ].keys()),
'protocols' : list (data[ 'assetByProtocols' ].keys()),
'chain_count' : len (data[ 'chains' ])
}
return analysis
Example AI Agent
Here’s a complete example of a portfolio monitoring agent:
Python Agent
JavaScript Agent
import requests
import time
from datetime import datetime
class PortfolioAgent :
def __init__ ( self , api_key ):
self .api_key = api_key
self .base_url = 'https://api.octav.fi'
self .headers = { 'Authorization' : f 'Bearer { api_key } ' }
def get_portfolio ( self , address ):
"""Fetch portfolio data for an address"""
response = requests.get(
f ' { self .base_url } /v1/portfolio?addresses= { address } ' ,
headers = self .headers
)
return response.json()[ 0 ]
def analyze_holdings ( self , portfolio ):
"""Analyze portfolio composition"""
analysis = {
'timestamp' : datetime.now().isoformat(),
'total_value' : float (portfolio[ 'networth' ]),
'chains' : {},
'protocols' : {},
'top_assets' : []
}
# Analyze by chain
for chain_key, chain in portfolio[ 'chains' ].items():
analysis[ 'chains' ][chain[ 'name' ]] = float (chain[ 'value' ])
# Analyze by protocol
for protocol_key, protocol in portfolio[ 'assetByProtocols' ].items():
analysis[ 'protocols' ][protocol[ 'name' ]] = float (protocol[ 'value' ])
return analysis
def monitor ( self , address , check_interval = 60 ):
"""Monitor portfolio and report changes"""
last_value = None
while True :
portfolio = self .get_portfolio(address)
current_value = float (portfolio[ 'networth' ])
if last_value is not None :
change = current_value - last_value
change_pct = (change / last_value) * 100
if abs (change_pct) > 1 : # Alert on 1% change
print ( f "🚨 Portfolio changed by { change_pct :.2f} %" )
print ( f " New value: $ { current_value :,.2f} " )
last_value = current_value
time.sleep(check_interval)
# Usage
agent = PortfolioAgent( 'YOUR_API_KEY' )
analysis = agent.analyze_holdings(
agent.get_portfolio( '0x123...' )
)
print (analysis)
Use Cases for AI Agents
Build chat-based portfolio assistants: # Example: ChatGPT-style portfolio assistant
def portfolio_chat_handler ( user_message , address , api_key ):
agent = PortfolioAgent(api_key)
portfolio = agent.get_portfolio(address)
if "balance" in user_message.lower():
return f "Your portfolio is worth $ { portfolio[ 'networth' ] } "
elif "chains" in user_message.lower():
chains = ", " .join(portfolio[ 'chains' ].keys())
return f "You have assets on: { chains } "
elif "top holding" in user_message.lower():
# Find largest position
max_protocol = max (
portfolio[ 'assetByProtocols' ].items(),
key = lambda x : float (x[ 1 ][ 'value' ])
)
return f "Your top holding is { max_protocol[ 1 ][ 'name' ] } : $ { max_protocol[ 1 ][ 'value' ] } "
# User: "What's my balance?"
response = portfolio_chat_handler(
"What's my balance?" ,
"0x123..." ,
API_KEY
)
print (response) # "Your portfolio is worth $12,345.67"
Send notifications on portfolio changes: class AlertAgent ( PortfolioAgent ):
def __init__ ( self , api_key , webhook_url ):
super (). __init__ (api_key)
self .webhook_url = webhook_url
def send_alert ( self , message ):
requests.post(
self .webhook_url,
json = { 'text' : message}
)
def check_thresholds ( self , address , thresholds ):
portfolio = self .get_portfolio(address)
value = float (portfolio[ 'networth' ])
if value < thresholds[ 'min' ]:
self .send_alert(
f "⚠️ Portfolio below $ { thresholds[ 'min' ] :,} "
)
if value > thresholds[ 'max' ]:
self .send_alert(
f "🎉 Portfolio above $ { thresholds[ 'max' ] :,} "
)
# Usage
agent = AlertAgent( API_KEY , SLACK_WEBHOOK )
agent.check_thresholds( '0x123...' , {
'min' : 10000 ,
'max' : 100000
})
Aggregate data across multiple addresses: class AggregatorAgent ( PortfolioAgent ):
def aggregate_portfolios ( self , addresses ):
total_value = 0
all_chains = set ()
all_protocols = set ()
for address in addresses:
portfolio = self .get_portfolio(address)
total_value += float (portfolio[ 'networth' ])
all_chains.update(portfolio[ 'chains' ].keys())
all_protocols.update(portfolio[ 'assetByProtocols' ].keys())
return {
'total_value' : total_value,
'unique_chains' : len (all_chains),
'unique_protocols' : len (all_protocols),
'address_count' : len (addresses)
}
# Usage
agent = AggregatorAgent( API_KEY )
summary = agent.aggregate_portfolios([
'0x123...' ,
'0x456...' ,
'0x789...'
])
print ( f "Combined portfolio: $ { summary[ 'total_value' ] :,.2f} " )
Best Practices
Respect API rate limits (360 requests/minute): import time
from collections import deque
class RateLimitedAgent ( PortfolioAgent ):
def __init__ ( self , api_key , max_rpm = 360 ):
super (). __init__ (api_key)
self .max_rpm = max_rpm
self .requests = deque()
def _check_rate_limit ( self ):
now = time.time()
# Remove requests older than 1 minute
while self .requests and self .requests[ 0 ] < now - 60 :
self .requests.popleft()
if len ( self .requests) >= self .max_rpm:
sleep_time = 60 - (now - self .requests[ 0 ])
time.sleep(sleep_time)
def get_portfolio ( self , address ):
self ._check_rate_limit()
self .requests.append(time.time())
return super ().get_portfolio(address)
Handle API errors gracefully: def safe_api_call ( self , func , * args , max_retries = 3 ):
for attempt in range (max_retries):
try :
return func( * args)
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1 :
raise
time.sleep( 2 ** attempt) # Exponential backoff
Monitor and manage API credits: def check_credits ( self ):
response = requests.get(
f ' { self .base_url } /v1/credits' ,
headers = self .headers
)
credits = response.json()
if credits < 100 :
print ( f "⚠️ Low credits: { credits } " )
return credits