Analytics API
The analytics API provides access to your Appspace’s click, install, and conversion data. Read endpoints require a secret key. Event tracking accepts publishable or secret keys.
Date range parameters
Section titled “Date range parameters”All GET analytics endpoints accept date range parameters:
| Param | Description |
|---|---|
days | Number of days to look back. Defaults to 30. Clamped to your plan’s retention limit (Free: 7, Standard: 180, Growth: 365, Scale: 730). Ignored if start and end are provided. |
start | ISO date (e.g. 2026-01-01). Used with end. |
end | ISO date (e.g. 2026-01-31). Used with start. |
Overview
Section titled “Overview”Get aggregate metrics for the date range.
GET /v1/api/analytics/overviewAuth: Secret key required
Response 200:
{ "total_clicks": 10041, "total_installs": 1401, "total_views": 5672, "total_store_redirects": 3200, "total_banner_clicks": 450, "total_events": 15092, "conversion_rate": 14.0, "days": 30}Funnel
Section titled “Funnel”Get a step-by-step conversion funnel with drop-off percentages.
GET /v1/api/analytics/funnelAuth: Secret key required
Response 200:
{ "steps": [ { "name": "clicks", "count": 1000, "percentage": 100 }, { "name": "views", "count": 850, "percentage": 85 }, { "name": "store_redirects", "count": 420, "percentage": 49.41 }, { "name": "installs", "count": 89, "percentage": 21.19 }, { "name": "link_opens", "count": 72, "percentage": 80.90 } ], "days": 30}Each percentage is relative to the previous step (except clicks, which is always 100).
Timeseries
Section titled “Timeseries”Get daily event counts grouped by event type.
GET /v1/api/analytics/timeseriesAuth: Secret key required
Query parameters:
| Param | Description |
|---|---|
event_types | Comma-separated list of event types (e.g. click,install). Returns all types if omitted. |
Response 200:
{ "series": { "click": [ { "date": "2026-01-01", "count": 120 }, { "date": "2026-01-02", "count": 98 } ], "install": [ { "date": "2026-01-01", "count": 10 } ] }, "days": 30}Campaigns
Section titled “Campaigns”Get click and install counts broken down by UTM campaign.
GET /v1/api/analytics/campaignsAuth: Secret key required
Response 200:
{ "campaigns": [ { "campaign": "spring-sale", "source": "email", "medium": "newsletter", "term": "", "content": "", "clicks": 400, "installs": 30 }, { "campaign": "email-blast", "source": "mailchimp", "medium": "email", "term": "", "content": "footer-cta", "clicks": 200, "installs": 15 } ], "days": 30}Geographic breakdown
Section titled “Geographic breakdown”Get click counts by country.
GET /v1/api/analytics/geoAuth: Secret key required
Response 200:
{ "countries": [ { "country": "US", "count": 600 }, { "country": "GB", "count": 200 }, { "country": "DE", "count": 150 } ], "days": 30}Country values are ISO 3166-1 alpha-2 codes.
Raw events
Section titled “Raw events”Get recent raw events.
GET /v1/api/analytics/eventsAuth: Secret key required
Query parameters:
| Param | Default | Max | Description |
|---|---|---|---|
limit | 50 | 200 | Number of events to return |
Response 200:
{ "events": [ { "event_id": "evt_abc123", "event_type": "click", "timestamp": "2026-01-15T10:30:00Z", "url": "https://myapp.tolinku.com/merchant/abc", "country": "US", "device_type": "mobile", "os": "iOS", "browser": "Safari", "platform": "ios", "campaign": "spring-sale", "source": "email", "prefix": "merchant", "is_bot": 0 } ]}Export
Section titled “Export”Download all events in the date range as a CSV file.
GET /v1/api/analytics/exportAuth: Secret key required
Response: CSV file download.
Content-Type: text/csvContent-Disposition: attachment; filename="analytics-30d.csv"
CSV columns: event_id, event_type, timestamp, url, referrer, country, region, city, device_type, os, browser, platform, campaign, source, medium, term, content, prefix, is_bot
Track a custom event
Section titled “Track a custom event”Send a custom event from your app or server.
POST /v1/api/analytics/trackAuth: Any valid API key (publishable or secret)
Request body:
{ "event_type": "custom.purchase", "url": "https://myapp.com/checkout", "properties": { "campaign": "spring-sale", "source": "email", "medium": "newsletter", "platform": "ios", "user_id": "user_123" }}| Field | Required | Rules |
|---|---|---|
event_type | Yes | Must start with custom., match custom.[a-z0-9_]+, max 100 characters |
url | No | URL associated with the event |
properties | No | Optional metadata (campaign, source, medium, platform, user_id) |
Response 200:
{ "ok": true }Errors:
| Status | Error |
|---|---|
400 | event_type is required |
400 | event_type must start with "custom." |
400 | event_type must match pattern: custom.[a-z0-9_]+ |
400 | event_type must be 100 characters or less |
403 | Custom events are not available on the free tier |
Batch track events
Section titled “Batch track events”Track up to 100 custom events in a single request. Used by SDKs to flush queued events.
POST /v1/api/analytics/batchAuth: Any valid API key (publishable or secret)
Request body:
{ "events": [ { "event_type": "custom.add_to_cart", "url": "https://myapp.com/product/123", "properties": { "user_id": "user_abc" } }, { "event_type": "custom.checkout_start", "properties": { "user_id": "user_abc" } } ]}| Field | Required | Rules |
|---|---|---|
events | Yes | Non-empty array, max 100 items |
events[].event_type | Yes | Same rules as single track |
events[].url | No | |
events[].properties | No |
Response 200:
{ "ok": true, "accepted": 2}If some events are invalid, they are skipped and the valid ones are still tracked:
{ "ok": true, "accepted": 1, "errors": [ "events[1]: event_type must start with \"custom.\"" ]}Errors:
| Status | Error |
|---|---|
400 | events array is required and must not be empty |
400 | Maximum 100 events per batch |
403 | Custom events are not available on the free tier |