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

# Oracle Monitoring

Use an API key generated in the Oracle Dashboard to read your organization's oracle configuration, feeds, historical updates, gas costs, and transactions.

<Note>
  Dashboard API keys authenticate requests to the DIA Indexer API. They are not used with the dashboard's internal `/api/oracle/*` routes.
</Note>

## Base URL

```text theme={"system"}
https://indexer.api.diadata.org/v1
```

All authenticated requests send the API key in the `X-Api-Key` header:

```http theme={"system"}
X-Api-Key: YOUR_API_KEY
```

<Warning>
  Treat the API key as a secret. Store it in a server-side environment variable or secret manager. Never commit it to source control or expose it in frontend JavaScript, browser storage, mobile applications, query strings, screenshots, or logs.
</Warning>

## Generate and store a key

1. Open **Oracle Dashboard → Settings → API Key**.
2. Select **Generate API key**.
3. Copy the key immediately. It is displayed only once.
4. Store it in your deployment's secret manager.

For local development, set environment variables in your shell:

```bash theme={"system"}
export DIA_API_KEY="your-api-key"
export DIA_INDEXER_URL="https://indexer.api.diadata.org/v1"
```

Do not put the real key in an `.env` file that is committed to Git.

## Make your first request

List the oracles available to the authenticated organization.

<CodeGroup>
  ```bash cURL theme={"system"}
  curl --fail-with-body \
    "$DIA_INDEXER_URL/account/oracles" \
    -H "Accept: application/json" \
    -H "X-Api-Key: $DIA_API_KEY"
  ```

  ```javascript Node.js theme={"system"}
  const response = await fetch(
    "https://indexer.api.diadata.org/v1/account/oracles",
    {
      headers: {
        Accept: "application/json",
        "X-Api-Key": process.env.DIA_API_KEY,
      },
    },
  );

  if (!response.ok) {
    throw new Error(`DIA API request failed: ${response.status} ${await response.text()}`);
  }

  const oracleGroups = await response.json();
  console.log(oracleGroups);
  ```

  ```python Python theme={"system"}
  import os
  import requests

  response = requests.get(
      "https://indexer.api.diadata.org/v1/account/oracles",
      headers={
          "Accept": "application/json",
          "X-Api-Key": os.environ["DIA_API_KEY"],
      },
      timeout=30,
  )
  response.raise_for_status()
  print(response.json())
  ```
</CodeGroup>

Example response:

```json theme={"system"}
[
  {
    "customer": "example-org",
    "oracles": [
      {
        "oracle_id": "example_oracle_mainnet",
        "network_name": "Ethereum",
        "network_id": 1,
        "address": "0x0000000000000000000000000000000000000000",
        "explorer_url": "https://etherscan.io/address/0x0000000000000000000000000000000000000000",
        "status": "active",
        "last_update": "2026-10-01T10:30:00Z",
        "est_runway_days": 94.2
      }
    ]
  }
]
```

Use this response to discover the exact `network_name`, `address`, and `oracle_id` needed by the other endpoints.

## Endpoint reference

| Method | Path | Description |
| - | - | - |
| `GET` | `/account/oracles` | List the organization's oracles |
| `GET` | `/account/oracle/{blockchain}/{address}` | Get one oracle and its configured feeds |
| `GET` | `/account/oracles/feed/{blockchain}/{address}/{feed}` | Get one feed, its sources, and guardians |
| `GET` | `/account/oracles/feeds/updates/{blockchain}/{address}/{feed}` | Get historical feed updates |
| `GET` | `/account/customer/oracles/gasCostHistory/{blockchain}/{address}` | Get gas-wallet and consumption statistics |
| `GET` | `/account/customer/oracles/transactions/{blockchain}/{address}` | Get on-chain update transactions |

### Path conventions

* Use the exact blockchain name returned as `network_name`, such as `Ethereum`, `Base`, or `Arbitrum`.
* EVM addresses should be EIP-55 checksum compliant.
* Use the feed identifier returned by the oracle-detail endpoint.
* Write slash-based pairs in API-safe dash notation: `ETH/USD` becomes `ETH-USD` in a URL path.
* Typed feed identifiers retain their notation, for example `denominator:wBTC` or `fairValue:wBTC`.
* Do not double-encode feed identifiers. For example, do not send `ETH%252FUSD`.

## Get oracle details

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/oracle/Ethereum/0xYourChecksumAddress" \
  -H "X-Api-Key: $DIA_API_KEY"
```

Example response:

```json theme={"system"}
{
  "oracle_id": "example_oracle_mainnet",
  "customer": "example-org",
  "network_name": "Ethereum",
  "network_id": 1,
  "address": "0xYourChecksumAddress",
  "status": "active",
  "last_update": "2026-10-01T10:30:00Z",
  "config": {
    "heartbeat": 3600000,
    "price_deviation": 0.002,
    "gas_limit": 0,
    "gas_multiplier": 0
  },
  "feeds": [
    {
      "feed_id": "ETH/USD",
      "latest_value": 4200.25,
      "heartbeat": 3600000,
      "price_deviation": 0.002,
      "last_update": "2026-10-01T10:30:00Z",
      "status": "active"
    }
  ]
}
```

<Note>
  `heartbeat` is expressed in milliseconds. `price_deviation` is a fraction: `0.002` means `0.2%`.
</Note>

## Get feed details

For a slash-based pair, use dash notation in the URL:

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/oracles/feed/Boba/0xYourChecksumAddress/ETH-USD" \
  -H "X-Api-Key: $DIA_API_KEY"
```

For a typed feed, retain the colon:

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/oracles/feed/Hemi/0xYourChecksumAddress/denominator:hemiBTC" \
  -H "X-Api-Key: $DIA_API_KEY"
```

The response includes the latest value, update configuration, source pairs, DEX pools, and configured guardians:

```json theme={"system"}
{
  "oracle_id": "example_oracle_mainnet",
  "feed_id": "ETH-USD",
  "latest_value": 4200.25,
  "latest_timestamp": "2026-10-01T10:30:00Z",
  "heartbeat": 3600000,
  "deviation": 0.002,
  "data_sources": [
    {
      "exchange": "ExampleExchange",
      "pairs": ["ETH-USDT"],
      "pool_address": "",
      "pool_network": ""
    }
  ],
  "guardians": [
    {
      "name": "ExampleGuardian",
      "asset": "ETH",
      "chain": "Ethereum",
      "asset_address": "0x0000000000000000000000000000000000000000",
      "deviation": 0.002,
      "max_timestamp_age": 3600,
      "min_guardian_matches": 1
    }
  ]
}
```

## Get historical updates

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/oracles/feeds/updates/Boba/0xYourChecksumAddress/ETH-USD?start_time=1788220800&end_time=1790812800&limit=500" \
  -H "X-Api-Key: $DIA_API_KEY"
```

| Query parameter | Type | Default | Description |
| - | - | - | - |
| `start_time` | Unix timestamp, seconds | 30 days ago | Beginning of the requested range |
| `end_time` | Unix timestamp, seconds | Current time | End of the requested range |
| `limit` | Integer | `200` | Maximum number of updates; capped at `2000` |

`end_time` must be later than `start_time`.

Example response:

```json theme={"system"}
{
  "feed": "ETH/USD",
  "contract_blockchain": "Boba",
  "contract_address": "0xYourChecksumAddress",
  "start_time": "2026-09-01T00:00:00Z",
  "end_time": "2026-10-01T00:00:00Z",
  "count": 2,
  "updates": [
    {
      "value": 4200.25,
      "timestamp": "2026-10-01T10:30:00Z",
      "customer": "example-org",
      "source": "oracle"
    }
  ]
}
```

## Get gas-cost history

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/customer/oracles/gasCostHistory/Ethereum/0xYourChecksumAddress?window=30d&bucket_size=1d" \
  -H "X-Api-Key: $DIA_API_KEY"
```

| Query parameter | Default | Description |
| - | - | - |
| `window` | `30d` | Lookback window, for example `12h`, `30d`, or `2w` |
| `bucket_size` | `1d` | Aggregation interval using the same duration format |

Example response:

```json theme={"system"}
{
  "oracle_id": "example_oracle_mainnet",
  "wallet_address": "0xYourChecksumAddress",
  "wallet_balance": 0.125,
  "gas_token_symbol": "ETH",
  "gas_token_decimals": 18,
  "window": "30d",
  "bucket_size": "1d",
  "updates_per_day": 24,
  "monthly_cost_native": 0.015,
  "est_runway_days": 250,
  "points": [
    {
      "timestamp": "2026-10-01T00:00:00Z",
      "avg_cost_per_update": 0.0000208
    }
  ]
}
```

## Get transactions

```bash theme={"system"}
curl --fail-with-body \
  "$DIA_INDEXER_URL/account/customer/oracles/transactions/Ethereum/0xYourChecksumAddress?limit=50" \
  -H "X-Api-Key: $DIA_API_KEY"
```

| Query parameter | Default | Description |
| - | - | - |
| `limit` | `50` | Page size; capped at `200` |
| `next` | None | Opaque cursor returned by the previous response |

Example response:

```json theme={"system"}
{
  "oracle_id": "example_oracle_mainnet",
  "network": "Ethereum",
  "limit": 50,
  "txns": [
    {
      "tx_hash": "0xTransactionHash",
      "feed": "ETH/USD",
      "value": 4200.25,
      "timestamp": "2026-10-01T10:30:00Z",
      "explorer_url": "https://etherscan.io/tx/0xTransactionHash"
    }
  ],
  "next": "CURSOR_FROM_THIS_RESPONSE"
}
```

Pass `next` back unchanged to retrieve the following page:

```bash theme={"system"}
curl --fail-with-body --get \
  "$DIA_INDEXER_URL/account/customer/oracles/transactions/Ethereum/0xYourChecksumAddress" \
  -H "X-Api-Key: $DIA_API_KEY" \
  --data-urlencode "limit=50" \
  --data-urlencode "next=CURSOR_FROM_PREVIOUS_RESPONSE"
```

## Errors

Errors are returned with an HTTP status and a JSON body. Authentication errors use an `error` field:

```json theme={"system"}
{
  "error": "API key not valid"
}
```

Endpoint validation and data errors can use `errorcode` and `errormessage`:

```json theme={"system"}
{
  "errorcode": 400,
  "errormessage": "invalid limit"
}
```

| Status | Meaning |
| - | - |
| `400 Bad Request` | A path parameter, time range, limit, or cursor is invalid |
| `401 Unauthorized` | The API key is missing, invalid, or not associated with a user |
| `403 Forbidden` | The key is valid but cannot access the requested organization or resource |
| `404 Not Found` | The requested feed or historical data is unavailable |
| `500 Internal Server Error` | The indexer or datastore could not complete the request |

Log the HTTP status, request path, and response body when diagnosing an error, but never log the `X-Api-Key` header.

## Revoke or rotate a key

Revoke keys from **Oracle Dashboard → Settings → API Key**. Revocation applies to subsequent API requests.

If key generation reports that the maximum number of keys has been reached, revoke an existing key before requesting another one.

For rotation without downtime:

1. Generate and securely store the replacement key.
2. Update every server or secret store that uses the old key.
3. Confirm requests succeed with the replacement key.
4. Revoke the old key.

<Tip>
  Use separate secrets for development and production. Rotate a key immediately if it appears in logs, screenshots, source control, or browser code.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.