> ## 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.

# Contract Protocol

> Look up which DeFi protocol a contract address belongs to

Resolve a contract address to the DeFi protocol it belongs to. Provide a `chain` to look up a single protocol on that chain, or omit it to search the address across every chain Octav knows it on.

<Info>
  **Cost:** 5 credits per lookup. The credits are **refunded** if no protocol is found (404).
</Info>

<Note>
  **Interactive Playground:** Test this endpoint in the [API Playground](/api-reference/contract-protocol/contract-protocol). Get your API key at [data.octav.fi](https://data.octav.fi/)
</Note>

***

## Endpoint

<CodeGroup>
  ```bash Request theme={null}
  GET https://api.octav.fi/v1/contract-protocol
  ```

  ```bash Example theme={null}
  curl "https://api.octav.fi/v1/contract-protocol?contract=0x1f98431c8ad98523631ae4a59f267346ea31f984&chain=ethereum" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

## Parameters

<ParamField query="contract" type="string" required>
  The contract address to look up. Accepts an EVM address (`0x…`) or a Solana base58 address.

  ```
  contract=0x1f98431c8ad98523631ae4a59f267346ea31f984
  ```
</ParamField>

<ParamField query="chain" type="string">
  Chain key (e.g. `ethereum`, `arbitrum`, `base`, `polygon`, `solana`). Match a chain's `key` field from the [Chains](/api/endpoints/chains) endpoint.

  If omitted, the endpoint returns **every chain** the address is known on.
</ParamField>

***

## Response

The response shape depends on whether you provide `chain`:

* **`chain` provided** → a single `{ protocol }` object.
* **`chain` omitted** → a `{ protocols }` array, where each entry is additionally tagged with its `chainKey`. The array is unordered.

<Note>
  Because the top-level field differs (`protocol` vs `protocols`), branch on which key is present rather than assuming a fixed shape.
</Note>

### Protocol Fields

<ResponseField name="name" type="string">
  Protocol display name (e.g. `"Uniswap V3"`)
</ResponseField>

<ResponseField name="key" type="string">
  Protocol key (e.g. `"uniswap-v3"`)
</ResponseField>

<ResponseField name="imgSmall" type="string">
  URL to small protocol icon
</ResponseField>

<ResponseField name="imgLarge" type="string">
  URL to large protocol icon
</ResponseField>

<ResponseField name="chainKey" type="string">
  Chain the match belongs to. **Only present** in the array response (when `chain` is omitted).
</ResponseField>

***

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  # Single chain
  curl "https://api.octav.fi/v1/contract-protocol?contract=0x1f98431c8ad98523631ae4a59f267346ea31f984&chain=ethereum" \
    -H "Authorization: Bearer YOUR_API_KEY"

  # All chains (address only)
  curl "https://api.octav.fi/v1/contract-protocol?contract=0x1f98431c8ad98523631ae4a59f267346ea31f984" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  async function getContractProtocol(contract, chain) {
    const params = new URLSearchParams({ contract });
    if (chain) params.set('chain', chain);

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

    const data = await response.json();
    // Single match when chain is given, array of matches otherwise
    return data.protocol ?? data.protocols;
  }

  const single = await getContractProtocol(
    '0x1f98431c8ad98523631ae4a59f267346ea31f984',
    'ethereum'
  );
  const allChains = await getContractProtocol(
    '0x1f98431c8ad98523631ae4a59f267346ea31f984'
  );
  ```

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

  def get_contract_protocol(contract, chain=None):
      params = {'contract': contract}
      if chain:
          params['chain'] = chain

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

      data = response.json()
      # Single match when chain is given, array of matches otherwise
      return data.get('protocol') or data.get('protocols')

  single = get_contract_protocol(
      '0x1f98431c8ad98523631ae4a59f267346ea31f984',
      chain='ethereum'
  )
  all_chains = get_contract_protocol(
      '0x1f98431c8ad98523631ae4a59f267346ea31f984'
  )
  ```

  ```typescript TypeScript theme={null}
  interface Protocol {
    name: string;
    key: string;
    imgSmall: string;
    imgLarge: string;
  }

  interface ProtocolWithChain extends Protocol {
    chainKey: string;
  }

  type SingleResponse = { protocol: Protocol };
  type MultiResponse = { protocols: ProtocolWithChain[] };

  async function getContractProtocol(
    contract: string,
    chain?: string
  ): Promise<Protocol | ProtocolWithChain[]> {
    const params = new URLSearchParams({ contract });
    if (chain) params.set('chain', chain);

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

    const data: SingleResponse | MultiResponse = await response.json();
    return 'protocol' in data ? data.protocol : data.protocols;
  }
  ```
</CodeGroup>

***

## Example Response

<CodeGroup>
  ```json chain provided (single match) theme={null}
  {
    "protocol": {
      "name": "Uniswap V3",
      "key": "uniswap-v3",
      "imgSmall": "https://images.octav.fi/...small.png",
      "imgLarge": "https://images.octav.fi/...large.png"
    }
  }
  ```

  ```json chain omitted (all matches) theme={null}
  {
    "protocols": [
      {
        "name": "Uniswap V3",
        "key": "uniswap-v3",
        "imgSmall": "https://images.octav.fi/...small.png",
        "imgLarge": "https://images.octav.fi/...large.png",
        "chainKey": "ethereum"
      },
      {
        "name": "Uniswap V3",
        "key": "uniswap-v3",
        "imgSmall": "https://images.octav.fi/...small.png",
        "imgLarge": "https://images.octav.fi/...large.png",
        "chainKey": "arbitrum"
      }
    ]
  }
  ```
</CodeGroup>

***

## Error Responses

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="circle-exclamation">
    The `contract` parameter is missing.

    ```json theme={null}
    {
      "error": "Validation Failed",
      "message": "\"contract\" is required"
    }
    ```
  </Accordion>

  <Accordion title="401 Unauthorized" icon="lock">
    Missing/invalid API key, or your key has no access to this endpoint.

    ```json theme={null}
    {
      "message": "Unauthorized"
    }
    ```

    **Solution:** Check your API key in the Authorization header.
  </Accordion>

  <Accordion title="402 Payment Required" icon="credit-card">
    Insufficient credits.

    ```json theme={null}
    {
      "message": "Insufficient credits",
      "creditsNeeded": 5
    }
    ```

    **Solution:** Purchase more credits at [data.octav.fi](https://data.octav.fi/)
  </Accordion>

  <Accordion title="404 Not Found" icon="circle-question">
    No protocol matches the contract address. **The credits are refunded.**

    ```json theme={null}
    {
      "message": "No protocol found for contract 0x1f98... [on ethereum]"
    }
    ```
  </Accordion>

  <Accordion title="429 Too Many Requests" icon="gauge-high">
    Rate limit exceeded.

    ```json theme={null}
    {
      "message": "Rate limit exceeded",
      "retryAfter": 60
    }
    ```

    **Solution:** Wait for the specified time or implement retry logic.
  </Accordion>

  <Accordion title="500 Internal Server Error" icon="triangle-exclamation">
    Unexpected server error.

    ```json theme={null}
    {
      "message": "Error while searching for contract protocol"
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Protocols" icon="layer-group" href="/api/endpoints/protocols">
    List all DeFi protocols on a specific chain
  </Card>

  <Card title="Chains" icon="link-simple" href="/api/endpoints/chains">
    Get all supported chains and their keys
  </Card>

  <Card title="Portfolio" icon="wallet" href="/api/endpoints/portfolio">
    Get portfolio holdings by protocol
  </Card>

  <Card title="Protocol Types Reference" icon="diagram-project" href="/api/reference/protocol-types">
    View all protocol type categories
  </Card>
</CardGroup>
