> ## Documentation Index
> Fetch the complete documentation index at: https://docs.octav.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Make your first API request in minutes

Get started with the Octav API and make your first request in minutes.

<Info>
  **Prerequisites** — You'll need an API key from [data.octav.fi](https://data.octav.fi/). See [Authentication](/api/authentication) for details.
</Info>

***

## Your First Request

Let's start by checking your remaining credits - this endpoint is free and perfect for testing authentication.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.octav.fi/v1/credits \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const apiKey = 'YOUR_API_KEY';

  const response = await fetch('https://api.octav.fi/v1/credits', {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });

  const credits = await response.json();
  console.log(`Remaining credits: ${credits}`);
  ```

  ```python Python theme={null}
  import requests

  api_key = 'YOUR_API_KEY'

  response = requests.get(
      'https://api.octav.fi/v1/credits',
      headers={'Authorization': f'Bearer {api_key}'}
  )

  credits = response.json()
  print(f'Remaining credits: {credits}')
  ```

  ```typescript TypeScript theme={null}
  const apiKey: string = process.env.OCTAV_API_KEY!;

  const response = await fetch('https://api.octav.fi/v1/credits', {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });

  const credits: number = await response.json();
  console.log(`Remaining credits: ${credits}`);
  ```
</CodeGroup>

### Response

```json theme={null}
19033
```

The credits endpoint returns a simple number indicating your remaining credit balance.

<Check>
  **Success!** If you see a number, your API key is working correctly.
</Check>

***

## Fetch a Portfolio

Now let's retrieve portfolio data for a blockchain address.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.octav.fi/v1/portfolio?addresses=0x6426af179aabebe47666f345d69fd9079673f6cd" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const address = '0x6426af179aabebe47666f345d69fd9079673f6cd';

  const response = await fetch(
    `https://api.octav.fi/v1/portfolio?addresses=${address}`,
    {
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    }
  );

  const portfolio = await response.json();
  console.log('Net Worth:', portfolio.networth);
  console.log('Protocols:', Object.keys(portfolio.assetByProtocols).length);
  ```

  ```python Python theme={null}
  address = '0x6426af179aabebe47666f345d69fd9079673f6cd'

  response = requests.get(
      'https://api.octav.fi/v1/portfolio',
      params={'addresses': address},
      headers={'Authorization': f'Bearer {api_key}'}
  )

  portfolio = response.json()
  print(f"Net Worth: {portfolio['networth']}")
  print(f"Protocols: {len(portfolio['assetByProtocols'])}")
  ```

  ```typescript TypeScript theme={null}
  const address = '0x6426af179aabebe47666f345d69fd9079673f6cd';

  interface Portfolio {
    address: string;
    networth: string;
    assetByProtocols: Record<string, any>;
    chains: Record<string, any>;
  }

  const response = await fetch(
    `https://api.octav.fi/v1/portfolio?addresses=${address}`,
    {
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    }
  );

  const portfolio: Portfolio = await response.json();
  console.log('Net Worth:', portfolio.networth);
  console.log('Protocols:', Object.keys(portfolio.assetByProtocols).length);
  ```
</CodeGroup>

### Response Structure

<Accordion title="View Sample Response" icon="code">
  ```json theme={null}
  {
    "address": "0x6426af179aabebe47666f345d69fd9079673f6cd",
    "cashBalance": "0",
    "dailyIncome": "0",
    "dailyExpense": "0",
    "fees": "0",
    "feesFiat": "0",
    "lastUpdated": "1715173392020",
    "networth": "45231.89",
    "assetByProtocols": {
      "wallet": {
        "key": "wallet",
        "name": "Wallet",
        "value": "12453.20",
        "assets": [
          {
            "balance": "1.5",
            "symbol": "ETH",
            "price": "3200.50",
            "value": "4800.75",
            "chain": "ethereum"
          }
        ]
      },
      "aave_v3": {
        "key": "aave_v3",
        "name": "Aave V3",
        "value": "8934.12",
        "assets": [...]
      }
    },
    "chains": {
      "ethereum": {
        "value": "25123.45",
        "protocols": [...]
      },
      "arbitrum": {
        "value": "20108.44",
        "protocols": [...]
      }
    }
  }
  ```
</Accordion>

<Info>
  **Cost:** 1 credit per call
</Info>

***

## Query Transaction History

Retrieve transaction history with pagination and filtering.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.octav.fi/v1/transactions?addresses=0x6426af179aabebe47666f345d69fd9079673f6cd&limit=10&offset=0&sort=DESC" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    addresses: '0x6426af179aabebe47666f345d69fd9079673f6cd',
    limit: '10',
    offset: '0',
    sort: 'DESC'
  });

  const response = await fetch(
    `https://api.octav.fi/v1/transactions?${params}`,
    {
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    }
  );

  const transactions = await response.json();
  console.log(`Retrieved ${transactions.length} transactions`);
  transactions.forEach(tx => {
    console.log(`${tx.type} - ${tx.chain.name} - ${tx.timestamp}`);
  });
  ```

  ```python Python theme={null}
  params = {
      'addresses': '0x6426af179aabebe47666f345d69fd9079673f6cd',
      'limit': 10,
      'offset': 0,
      'sort': 'DESC'
  }

  response = requests.get(
      'https://api.octav.fi/v1/transactions',
      params=params,
      headers={'Authorization': f'Bearer {api_key}'}
  )

  transactions = response.json()
  print(f'Retrieved {len(transactions)} transactions')
  for tx in transactions:
      print(f"{tx['type']} - {tx['chain']['name']} - {tx['timestamp']}")
  ```

  ```typescript TypeScript theme={null}
  interface Transaction {
    hash: string;
    type: string;
    timestamp: string;
    chain: {
      key: string;
      name: string;
    };
    from: string;
    to: string;
    value: string;
    fees: string;
  }

  const params = new URLSearchParams({
    addresses: '0x6426af179aabebe47666f345d69fd9079673f6cd',
    limit: '10',
    offset: '0',
    sort: 'DESC'
  });

  const response = await fetch(
    `https://api.octav.fi/v1/transactions?${params}`,
    {
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    }
  );

  const transactions: Transaction[] = await response.json();
  console.log(`Retrieved ${transactions.length} transactions`);
  ```
</CodeGroup>

### Key Parameters

<ParamField query="addresses" type="string" required>
  Wallet address (EVM or SOL)
</ParamField>

<ParamField query="limit" type="integer" required>
  Number of transactions per page (1-250)
</ParamField>

<ParamField query="offset" type="integer" required>
  Pagination offset
</ParamField>

<ParamField query="sort" type="string">
  Sort order: `DESC` (newest first) or `ASC` (oldest first)
</ParamField>

<Info>
  **Cost:** 1 credit per call
</Info>

***

## Common Patterns

### Environment Variables

Store your API key securely in environment variables:

<CodeGroup>
  ```bash .env theme={null}
  OCTAV_API_KEY=your_api_key_here
  ```

  ```javascript JavaScript theme={null}
  // Load from .env file
  require('dotenv').config();
  const apiKey = process.env.OCTAV_API_KEY;
  ```

  ```python Python theme={null}
  import os
  from dotenv import load_dotenv

  load_dotenv()
  api_key = os.getenv('OCTAV_API_KEY')
  ```

  ```typescript TypeScript theme={null}
  import dotenv from 'dotenv';
  dotenv.config();

  const apiKey = process.env.OCTAV_API_KEY;
  ```
</CodeGroup>

### Error Handling

Always handle errors gracefully:

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function fetchPortfolio(address) {
    try {
      const response = await fetch(
        `https://api.octav.fi/v1/portfolio?addresses=${address}`,
        {
          headers: {
            'Authorization': `Bearer ${apiKey}`
          }
        }
      );

      if (!response.ok) {
        const error = await response.json();
        throw new Error(`API Error: ${error.message}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to fetch portfolio:', error);
      throw error;
    }
  }
  ```

  ```python Python theme={null}
  def fetch_portfolio(address):
      try:
          response = requests.get(
              'https://api.octav.fi/v1/portfolio',
              params={'addresses': address},
              headers={'Authorization': f'Bearer {api_key}'}
          )

          response.raise_for_status()
          return response.json()

      except requests.exceptions.HTTPError as e:
          print(f'HTTP Error: {e}')
          raise
      except requests.exceptions.RequestException as e:
          print(f'Request failed: {e}')
          raise
  ```

  ```typescript TypeScript theme={null}
  async function fetchPortfolio(address: string): Promise<Portfolio> {
    try {
      const response = await fetch(
        `https://api.octav.fi/v1/portfolio?addresses=${address}`,
        {
          headers: {
            'Authorization': `Bearer ${apiKey}`
          }
        }
      );

      if (!response.ok) {
        const error = await response.json();
        throw new Error(`API Error: ${error.message}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to fetch portfolio:', error);
      throw error;
    }
  }
  ```
</CodeGroup>

### Rate Limit Handling

Respect rate limits with retry logic:

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function fetchWithRetry(url, options, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      const response = await fetch(url, options);

      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 60;
        console.log(`Rate limited. Retrying after ${retryAfter}s...`);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      return response;
    }

    throw new Error('Max retries exceeded');
  }
  ```

  ```python Python theme={null}
  import time

  def fetch_with_retry(url, headers, max_retries=3):
      for i in range(max_retries):
          response = requests.get(url, headers=headers)

          if response.status_code == 429:
              retry_after = int(response.headers.get('Retry-After', 60))
              print(f'Rate limited. Retrying after {retry_after}s...')
              time.sleep(retry_after)
              continue

          return response

      raise Exception('Max retries exceeded')
  ```
</CodeGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Portfolio Endpoint" icon="wallet" href="/api/endpoints/portfolio">
    Detailed documentation for portfolio data
  </Card>

  <Card title="Nav Endpoint" icon="wallet" href="/api/endpoints/nav">
    Detailed documentation for nav data
  </Card>

  <Card title="Transactions Endpoint" icon="receipt" href="/api/endpoints/transactions">
    Query and filter transaction history
  </Card>

  <Card title="All Endpoints" icon="list" href="/api/endpoints/status">
    Explore all available endpoints
  </Card>

  <Card title="Pricing" icon="credit-card" href="/api/pricing">
    Understand credit costs
  </Card>
</CardGroup>

***

## Need Help?

<CardGroup cols={2}>
  <Card title="Join Discord" icon="discord" href="https://discord.com/invite/qvcknAa73A">
    Get help from the community
  </Card>

  <Card title="Contact Support" icon="envelope" href="/docs/contact-us">
    Reach out to our team
  </Card>
</CardGroup>
