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

# Publisher performance

> Read the numbers your Index dashboard shows, with your publisher API key

The same figures as the **Index** page of your Gravity dashboard (revenue, index calls,
recommendations, clicks, click-through rate, conversions, conversion rate, plus the daily series
behind the chart), as JSON, for any window in the last 90 days. Both are computed from one shared
query, so the API and the dashboard always agree for the same UTC date range.

> [!NOTE]
>
> Days are **UTC**. The dashboard buckets by UTC day too, so a range that matches the dashboard's
> date picker returns the same totals as its cards.

## Authentication

Send your publisher API key (the key you already use for [`POST /search`](/gravity-index/search))
as the `X-API-Key` header. `X-Platform-Api-Key` is accepted as an alias.

**X-API-Key** `string` *required*

Publisher API key. The publisher is resolved from the key alone; there is no publisher parameter.

| Status | Body | Meaning |
| - | - | - |
| `401` | `Invalid API key` | The key does not belong to any publisher |
| `403` | `publisher_not_approved` | The publisher account is blocked |
| `403` | `index_not_enabled` | The publisher has no active Index profile yet (pending accounts included) |
| `422` | — | Bad date, out-of-range window, or an unsupported query parameter |
| `429` | — | More than 60 requests per minute for this publisher; retry after `Retry-After` seconds |

## Request

**side** `string` (default: publisher)

Must be `publisher` (the default). Any other value is `422`.

**start\_date** `string`

First UTC day, `YYYY-MM-DD`. Defaults to 29 days before `end_date` (a 30-day window). Must be
on or after `available_from` (today minus 90 days).

**end\_date** `string`

Last UTC day, `YYYY-MM-DD`, inclusive. Defaults to today (UTC). Cannot be in the future or before
`start_date`.

Only `side`, `start_date` and `end_date` are accepted with an API key. Anything else (`limit`,
`status`, …) is `422`; those parameters belong to the dashboard session's view of this route, which
returns a different payload.

## Response

**publisher\_id** `string`

Your publisher ID

**timezone** `string`

Always `UTC`

**start\_date** `string`

First day in the window (`YYYY-MM-DD`)

**end\_date** `string`

Last day in the window (`YYYY-MM-DD`)

**available\_from** `string`

Earliest day you can request (today minus 90 days)

**summary** `object`

Totals over the window, the dashboard's cards.

**revenue\_cents** `integer`

Publisher payout in cents from approved, locked, payable, paid or billed conversions

**index\_calls** `integer`

Index searches your platform made

**recommendations** `integer`

Searches that returned a recommendation

**clicks** `integer`

Searches whose tracked link was clicked (one per search, counted on the day of the click)

**click\_through\_rate** `number | null`

`clicks` divided by searches that returned a tracked link. `null` when no search in the window
returned a link.

**conversions** `integer`

Approved conversions attributed to you

**conversion\_rate** `number`

`conversions` divided by `recommendations`; `0` when there were no recommendations

**daily** `array`

One entry per UTC day from `start_date` to `end_date`, ascending, zero-filled.

**date** `string`

`YYYY-MM-DD`

**index\_calls** `integer`

**recommendations** `integer`

**clicks** `integer`

**conversions** `integer`

> [!NOTE]
>
> `index_calls` is usually higher than `recommendations`: searches that return no match, and
> consumer product searches, still count as calls. For a publisher on CPA-only programs this gap is
> expected, not a sign that calls are being lost.

## Example

```bash theme={null}
curl "https://api-interface.trygravity.com/index/attributions?side=publisher&start_date=2026-10-01&end_date=2026-10-07" \
  -H "X-API-Key: $GRAVITY_PUBLISHER_KEY"
```

```json theme={null}
{
  "publisher_id": "2b1f4d4e-9c8a-4f0e-b1b2-5c1b7a3f9d10",
  "timezone": "UTC",
  "start_date": "2026-10-01",
  "end_date": "2026-10-07",
  "available_from": "2026-07-23",
  "summary": {
    "revenue_cents": 1400,
    "index_calls": 812,
    "recommendations": 403,
    "clicks": 57,
    "click_through_rate": 0.1414,
    "conversions": 2,
    "conversion_rate": 0.00496
  },
  "daily": [
    {"date": "2026-10-01", "index_calls": 120, "recommendations": 61, "clicks": 9, "conversions": 0},
    {"date": "2026-10-02", "index_calls": 98, "recommendations": 47, "clicks": 6, "conversions": 1},
    {"date": "2026-10-03", "index_calls": 0, "recommendations": 0, "clicks": 0, "conversions": 0},
    {"date": "2026-10-04", "index_calls": 141, "recommendations": 70, "clicks": 11, "conversions": 0},
    {"date": "2026-10-05", "index_calls": 160, "recommendations": 82, "clicks": 12, "conversions": 1},
    {"date": "2026-10-06", "index_calls": 150, "recommendations": 74, "clicks": 10, "conversions": 0},
    {"date": "2026-10-07", "index_calls": 143, "recommendations": 69, "clicks": 9, "conversions": 0}
  ]
}
```

Omit both dates for the last 30 days ending today. Polling once a day is plenty; the limit is 60
requests per minute per publisher.


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