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

# Dashboard API

> Query your dashboard data programmatically using your API key.

Pull the same metrics you see in the dashboard — revenue, impressions, placements, devices, geography, user insights — from scripts, cron jobs, or custom integrations. All endpoints are read-only.

## Base URL

```
https://platform.trygravity.ai
```

## Authentication

Every request must include your Gravity API key in the `X-API-Key` header. Grab the key from your [dashboard](https://app.trygravity.ai) under **Settings → Platform Settings**.

```bash theme={null}
curl https://platform.trygravity.ai/publisher-dashboard/info \
  -H "X-API-Key: YOUR_API_KEY"
```

<Note>
  This is the same API key used to serve ads. No extra credentials required.
</Note>

***

## Endpoints

### GET `/publisher-dashboard/info`

Publisher profile and lifetime totals.

<ParamField header="X-API-Key" type="string" required>
  Your Gravity API key.
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl https://platform.trygravity.ai/publisher-dashboard/info \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "publisher_id": "abc-123",
  "name": "My Platform",
  "url": "https://myplatform.com",
  "payout_model": "CPM",
  "total_impressions": 7800000,
  "total_clicks": 42000
}
```

***

### GET `/publisher-dashboard/stats`

Daily performance time series — impressions, clicks, revenue, CPM, CPC, CTR.

<ParamField query="days" type="integer" default="30">
  Number of days to look back (1–3650).
</ParamField>

<ParamField query="start_date" type="string">
  Start date (`YYYY-MM-DD`). Overrides `days` when paired with `end_date`.
</ParamField>

<ParamField query="end_date" type="string">
  End date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="tz" type="string" default="UTC">
  IANA timezone for date bucketing (e.g. `America/New_York`).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/stats?days=7&tz=America/New_York" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "totalImpressions": 250000,
  "totalClicks": 1200,
  "totalRevenue": 1250.50,
  "avgCpm": 5.00,
  "avgCpc": 1.04,
  "avgCtr": 0.48,
  "timeSeries": [
    {
      "date": "2025-05-20",
      "impressions": 35000,
      "clicks": 170,
      "revenue": 178.50,
      "cpm": 5.10,
      "cpc": 1.05,
      "ctr": 0.49
    }
  ]
}
```

***

### GET `/publisher-dashboard/activity`

Ad request funnel — requests, wins, impressions, fill rate, show rate.

<ParamField query="days" type="integer" default="7">
  Number of days (1–30).
</ParamField>

<ParamField query="start_date" type="string">
  Start date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="end_date" type="string">
  End date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="tz" type="string" default="UTC">
  IANA timezone.
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/activity?days=7" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "data": [
    {
      "date": "2025-05-20",
      "requests": 50000,
      "wins": 35000,
      "impressions": 30000,
      "revenue": 150.25
    }
  ],
  "total_requests": 350000,
  "total_wins": 245000,
  "total_impressions": 210000,
  "total_revenue": 1050.00,
  "fill_rate": 0.70,
  "show_rate": 0.8571
}
```

| Field       | Description                                               |
| ----------- | --------------------------------------------------------- |
| `fill_rate` | `wins / requests` — how often a campaign matched.         |
| `show_rate` | `impressions / wins` — how often matched ads were viewed. |

***

### GET `/publisher-dashboard/placements`

Per-placement performance breakdown with daily time series.

<ParamField query="days" type="integer" default="7">
  Number of days (1–365).
</ParamField>

<ParamField query="start_date" type="string">
  Start date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="end_date" type="string">
  End date (`YYYY-MM-DD`).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/placements?days=7" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "placements": [
    {
      "placement": "below_response",
      "impressions": 120000,
      "clicks": 600,
      "ctr": 0.005,
      "revenue": 600.00,
      "cpm": 5.00,
      "cpc": 1.00,
      "daily": [
        {
          "date": "2025-05-20",
          "impressions": 17000,
          "clicks": 85,
          "ctr": 0.005,
          "revenue": 85.00,
          "cpm": 5.00,
          "cpc": 1.00
        }
      ]
    }
  ],
  "period_days": 7
}
```

***

### GET `/publisher-dashboard/devices`

Performance breakdown by device type (desktop, mobile, tablet).

<ParamField query="days" type="integer" default="30">
  Number of days (1–365).
</ParamField>

<ParamField query="start_date" type="string">
  Start date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="end_date" type="string">
  End date (`YYYY-MM-DD`).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/devices?days=30" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "devices": [
    {
      "device_type": "desktop",
      "impressions": 150000,
      "clicks": 750,
      "ctr": 0.005,
      "revenue": 750.00,
      "cpm": 5.00,
      "cpc": 1.00,
      "daily": [
        {
          "date": "2025-05-20",
          "device_type": "desktop",
          "impressions": 5000,
          "clicks": 25,
          "ctr": 0.005,
          "revenue": 25.00,
          "cpm": 5.00,
          "cpc": 1.00
        }
      ]
    }
  ],
  "period_days": 30
}
```

***

### GET `/publisher-dashboard/geography`

Per-country performance breakdown.

<ParamField query="days" type="integer" default="30">
  Number of days (1–365).
</ParamField>

<ParamField query="start_date" type="string">
  Start date (`YYYY-MM-DD`).
</ParamField>

<ParamField query="end_date" type="string">
  End date (`YYYY-MM-DD`).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/geography?days=30" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "countries": [
    {
      "country_code": "US",
      "impressions": 500000,
      "clicks": 2500,
      "ctr": 0.005,
      "revenue": 2500.00,
      "cpm": 5.00,
      "cpc": 1.00
    }
  ],
  "period_days": 30
}
```

***

### GET `/publisher-dashboard/users`

Paginated per-user lifetime stats with sorting and search.

<ParamField query="page" type="integer" default="1">
  Page number (starts at 1).
</ParamField>

<ParamField query="per_page" type="integer" default="50">
  Results per page (1–200).
</ParamField>

<ParamField query="sort" type="string" default="requests">
  Sort column. One of: `requests`, `ads_served`, `impressions`, `clicks`, `revenue_microdollars`, `first_seen`, `last_seen`.
</ParamField>

<ParamField query="order" type="string" default="desc">
  Sort direction: `asc` or `desc`.
</ParamField>

<ParamField query="search" type="string">
  Filter users by ID (partial match).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/users?page=1&per_page=10&sort=impressions&order=desc" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "users": [
    {
      "pub_user_id": "user_abc123",
      "requests": 500,
      "ads_served": 350,
      "impressions": 300,
      "clicks": 15,
      "revenue_microdollars": 1500000,
      "first_seen": "2025-01-15",
      "last_seen": "2025-05-20"
    }
  ],
  "total": 12000,
  "has_more": true,
  "page": 1,
  "per_page": 10
}
```

***

### GET `/publisher-dashboard/countries`

Top countries by user count.

<ParamField query="limit" type="integer" default="20">
  Number of countries to return (1–100).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl "https://platform.trygravity.ai/publisher-dashboard/countries?limit=10" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</RequestExample>

**Response**

```json theme={null}
{
  "countries": [
    {
      "country_code": "US",
      "requests": 200000,
      "ads_served": 140000,
      "unique_users": 8000,
      "pct_requests": 57.1
    }
  ]
}
```

***

## MCP server

The reporting endpoints above are also exposed as an [MCP](https://modelcontextprotocol.io) server, so AI agents and MCP-capable clients can query your account directly.

* **Endpoint:** `POST https://platform.trygravity.ai/mcp` (JSON-RPC 2.0 over HTTP)
* **Auth:** `X-API-Key` header (or `Authorization: Bearer <key>`)

A publisher API key unlocks read-only tools mirroring this API: `publisher_get_info`, `publisher_get_stats`, `publisher_get_activity`, `publisher_get_placements`, `publisher_get_devices`, `publisher_get_geography`, `publisher_get_users`, and `publisher_get_countries`.

```bash theme={null}
curl https://platform.trygravity.ai/mcp \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
```

***

## Code examples

<CodeGroup>
  ```python Python theme={null}
  import requests

  API_KEY = "your-api-key"
  BASE = "https://platform.trygravity.ai/publisher-dashboard"

  # Get last 30 days of performance stats
  stats = requests.get(
      f"{BASE}/stats",
      headers={"X-API-Key": API_KEY},
      params={"days": 30, "tz": "America/New_York"},
  ).json()

  print(f"Impressions: {stats['totalImpressions']:,}")
  print(f"Revenue: ${stats['totalRevenue']:.2f}")
  print(f"eCPM: ${stats['avgCpm']:.2f}")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "your-api-key";
  const BASE = "https://platform.trygravity.ai/publisher-dashboard";

  const res = await fetch(`${BASE}/stats?days=30&tz=America/New_York`, {
    headers: { "X-API-Key": API_KEY },
  });
  const stats = await res.json();

  console.log(`Impressions: ${stats.totalImpressions.toLocaleString()}`);
  console.log(`Revenue: $${stats.totalRevenue.toFixed(2)}`);
  console.log(`eCPM: $${stats.avgCpm.toFixed(2)}`);
  ```

  ```bash curl theme={null}
  # Get publisher info
  curl https://platform.trygravity.ai/publisher-dashboard/info \
    -H "X-API-Key: YOUR_API_KEY"

  # Get stats for a specific date range
  curl "https://platform.trygravity.ai/publisher-dashboard/stats?start_date=2025-05-01&end_date=2025-05-31" \
    -H "X-API-Key: YOUR_API_KEY"

  # Get placement breakdown
  curl "https://platform.trygravity.ai/publisher-dashboard/placements?days=7" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</CodeGroup>

## Errors

| Status | Description                                                 |
| ------ | ----------------------------------------------------------- |
| `401`  | Invalid or missing `X-API-Key`.                             |
| `400`  | Invalid parameter (e.g. bad timezone, out-of-range `days`). |
| `422`  | Missing required parameter.                                 |

## Questions

Email [support@trygravity.ai](mailto:support@trygravity.ai) for anything API-related. We read it.
