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

# Advertiser reporting

> Read aggregated campaign performance from the Management API.

Advertiser reporting requires an API key with the **`reporting`** permission.
See [Management API overview](/advertisers/api/overview) for base URL, authentication,
and error format.

Data comes from the `advertiser_daily_rollup` table, scoped to your organization's
`org_id`. Results include only campaigns that belong to your org.

## Endpoint

```
GET /v1/advertiser/reporting/campaigns
```

Aggregates impressions, clicks, conversions, spend, and revenue, then recomputes
rate KPIs from those totals.

## Query parameters

| Parameter      | Default         | Description                                                            |
| -------------- | --------------- | ---------------------------------------------------------------------- |
| `date_from`    | today − 30 days | Inclusive start date (`YYYY-MM-DD`)                                    |
| `date_to`      | today           | Inclusive end date (`YYYY-MM-DD`)                                      |
| `breakdown`    | `campaign`      | `campaign` (one row per campaign) or `daily` (one row per day)         |
| `campaign_ids` | —               | Comma-separated campaign UUIDs to filter to. Invalid UUIDs are dropped |
| `limit`        | `100`           | Page size (1–1000)                                                     |
| `offset`       | `0`             | Rows to skip                                                           |

The maximum date window is **92 days**. Requests with a wider range return
`400 bad_request`.

## Example: campaign breakdown

```bash theme={null}
curl "https://api.adgentek.ai/webapi/v1/advertiser/reporting/campaigns\
?date_from=2026-06-01&date_to=2026-06-30&breakdown=campaign" \
  -H "x-api-key: adv_YOUR_KEY"
```

Response (`200`):

```json theme={null}
{
  "data": [
    {
      "campaign_id": "…",
      "campaign_name": "Q3 Awareness",
      "campaign_status": "active",
      "brand_name": "Acme",
      "objective": "awareness",
      "impressions": 1200,
      "clicks": 34,
      "conversions": 3,
      "spend_usd": 45.2,
      "revenue_usd": 120.0,
      "ctr": 2.83,
      "cpc_usd": 1.33,
      "cpa_usd": 15.07,
      "cvr": 8.82,
      "ecpm_usd": 37.67,
      "roas": 2.65
    }
  ],
  "pagination": {
    "limit": 100,
    "offset": 0,
    "total": 1,
    "has_more": false
  },
  "query": {
    "breakdown": "campaign",
    "date_from": "2026-06-01",
    "date_to": "2026-06-30",
    "campaign_ids": null
  }
}
```

## Example: daily breakdown

Use `breakdown=daily` for a time series. Each row includes a `date` field and
aggregates across all campaigns for that day:

```bash theme={null}
curl "https://api.adgentek.ai/webapi/v1/advertiser/reporting/campaigns\
?date_from=2026-06-01&date_to=2026-06-07&breakdown=daily" \
  -H "x-api-key: adv_YOUR_KEY"
```

## Metrics

Base metrics are summed over the requested window:

| Field         | Meaning            |
| ------------- | ------------------ |
| `impressions` | Served impressions |
| `clicks`      | Clicks             |
| `conversions` | Conversion events  |
| `spend_usd`   | Advertiser spend   |
| `revenue_usd` | Attributed revenue |

Rate KPIs are **recomputed from the summed base metrics**, not averaged from
daily rates:

| Field      | Formula                    |
| ---------- | -------------------------- |
| `ctr`      | clicks / impressions × 100 |
| `cpc_usd`  | spend / clicks             |
| `cpa_usd`  | spend / conversions        |
| `cvr`      | conversions / clicks × 100 |
| `ecpm_usd` | spend / impressions × 1000 |
| `roas`     | revenue / spend            |

When the denominator is zero, the rate is `0.0`.

## Pagination

The response includes a `pagination` object:

| Field      | Meaning                                                  |
| ---------- | -------------------------------------------------------- |
| `limit`    | Page size you requested                                  |
| `offset`   | Rows skipped                                             |
| `total`    | Rows returned on this page                               |
| `has_more` | `true` when `total == limit` (there may be another page) |

Increase `offset` by `limit` to fetch the next page.

## Errors

| HTTP  | Code                            | Typical cause                                     |
| ----- | ------------------------------- | ------------------------------------------------- |
| `400` | `bad_request`                   | Bad dates, reversed range, or window over 92 days |
| `401` | `auth_missing` / `auth_invalid` | Missing or invalid API key                        |
| `403` | `forbidden`                     | Key lacks the `reporting` permission              |
| `500` | `internal_error`                | Query failure                                     |

## Campaign writes vs reporting reads

Reporting is read-only. To create or change campaigns, use the
[campaign management](/advertisers/api/campaigns) endpoints (requires the
`campaigns` permission). A single API key can carry both permissions.

## OpenAPI reference

Full schema definitions live in the machine-readable contract:

```
GET https://api.adgentek.ai/webapi/openapi.yaml
```

Look for `AdvertiserReportingResponse` and `AdvertiserCampaignRow`.
