# Agent API

Read-only analytics access for coding agents: the same numbers the dashboard renders, over REST and MCP.

Other guides: [quickstart.md](quickstart.md) · [events.md](events.md) · [revenuecat.md](revenuecat.md) · [apps.md](apps.md) · [apple-ads.md](apple-ads.md)

## Auth

Every request:

```
Authorization: Bearer <key>
```

(`x-api-key: <key>` also works.) Mint keys at dashboard → gear icon → **agent api** tab. A key (`ap_sk_…`) belongs to your account, is shown once (stored hashed), and is scoped at creation — all your apps (new apps included automatically) or a selected list; edit the scope or revoke it there anytime. Every tool answers only within the scope: `list_apps` returns the scoped set, `app: "all"` aggregates exactly that set. Keys are read-only, distinct from the per-app `ap_pk_` ingest key. Never commit or print one — use an environment variable.

## REST

`GET` with query params, or `POST` with a JSON body of the same args, against `https://activationpal.com/api/v1/<tool>`:

```bash
curl -s "https://activationpal.com/api/v1/get_stats?app=myapp&range=7d" \
  -H "Authorization: Bearer $AP_KEY"

curl -s https://activationpal.com/api/v1/get_events \
  -H "Authorization: Bearer $AP_KEY" -H "Content-Type: application/json" \
  -d '{"app": "myapp", "name": "paywall_shown", "limit": 100}'
```

Responses: `{ "ok": true, ... }` or `{ "ok": false, "error": "..." }`. `GET /api/v1` (authed) lists every tool with its JSON schema.

## MCP

Streamable-HTTP, stateless, same tools and key: `https://activationpal.com/api/mcp`

```bash
claude mcp add --transport http activationpal https://activationpal.com/api/mcp \
  --header "Authorization: Bearer <key>"
```

## Tools

### `list_apps`

No params. Returns every tracked app: `id` (the `app` value in every other tool), display `name`, IANA `timezone`, App Store `adam_id`.

### `get_stats`

The full analytics snapshot — the exact object the web dashboard renders.

| Param | Type | Notes |
|---|---|---|
| `app` | string, required | App id from `list_apps`, or `all` |
| `range` | string | `today`, `yesterday`, `week` (calendar week, Mon-first), `7d` (default), `30d`, `month` |
| `tz` | string | IANA override; default: the app's own timezone ([apps.md](apps.md)) — every bucket and daily cut runs in it |
| `users` | boolean | Include the per-device rollup (long; default false) |

Returns: headline installs / onboarded / devices / app-opens / purchases / ARPU / conversion + paywall-conversion rates (install-cohort) / average + median session length with previous-period values; gross revenue + mix (new subs / renewals / one-time); pricing-tier splits with per-country detail; time-bucketed chart series; cohort onboarding funnel (steps, answer splits, completion, paywall shown → plan → purchased with plan splits); paywall placements; acquisition (Apple Ads vs organic via AdServices); Apple Search Ads spend / taps / CPI; RevenueCat health (trials, conversions, churn reasons, by-product); geo by country and city; device / OS / app-version / language breakdowns; custom event counts; per-app distribution in `all` mode.

### `get_events`

Recent raw events, newest first. Each row: `name`, `ts`, `device_id`, `user_id`, `country`, `city`, `source`, `env`, `props`.

| Param | Type | Notes |
|---|---|---|
| `app` | string, required | App id, or `all` |
| `limit` | number | 1–500, default 50 |
| `name` | string | Exact event name — `paywall_shown`, `rc_renewal`, any custom event |
| `device_id` | string | Only this device's events |
| `source` | string | `sdk` or `revenuecat` |
| `env` | string | `release`, `testflight`, `debug` |
| `since` | string | ISO timestamp — only events at/after it |

### `get_user`

One device's full timeline for an app, oldest first: every SDK event it sent plus the RevenueCat events of every user id it reported — replays a single user's journey. Params, both required: `app`, `device_id` (from `get_stats` with `users: true`, or `get_events`).
