Skip to content

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.

All GET analytics endpoints accept date range parameters:

ParamDescription
daysNumber 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.
startISO date (e.g. 2026-01-01). Used with end.
endISO date (e.g. 2026-01-31). Used with start.

Get aggregate metrics for the date range.

GET /v1/api/analytics/overview

Auth: 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
}

Get a step-by-step conversion funnel with drop-off percentages.

GET /v1/api/analytics/funnel

Auth: 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).


Get daily event counts grouped by event type.

GET /v1/api/analytics/timeseries

Auth: Secret key required

Query parameters:

ParamDescription
event_typesComma-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
}

Get click and install counts broken down by UTM campaign.

GET /v1/api/analytics/campaigns

Auth: 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
}

Get click counts by country.

GET /v1/api/analytics/geo

Auth: 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.


Get recent raw events.

GET /v1/api/analytics/events

Auth: Secret key required

Query parameters:

ParamDefaultMaxDescription
limit50200Number 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
}
]
}

Download all events in the date range as a CSV file.

GET /v1/api/analytics/export

Auth: Secret key required

Response: CSV file download.

  • Content-Type: text/csv
  • Content-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


Send a custom event from your app or server.

POST /v1/api/analytics/track

Auth: 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"
}
}
FieldRequiredRules
event_typeYesMust start with custom., match custom.[a-z0-9_]+, max 100 characters
urlNoURL associated with the event
propertiesNoOptional metadata (campaign, source, medium, platform, user_id)

Response 200:

{ "ok": true }

Errors:

StatusError
400event_type is required
400event_type must start with "custom."
400event_type must match pattern: custom.[a-z0-9_]+
400event_type must be 100 characters or less
403Custom events are not available on the free tier

Track up to 100 custom events in a single request. Used by SDKs to flush queued events.

POST /v1/api/analytics/batch

Auth: 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" }
}
]
}
FieldRequiredRules
eventsYesNon-empty array, max 100 items
events[].event_typeYesSame rules as single track
events[].urlNo
events[].propertiesNo

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:

StatusError
400events array is required and must not be empty
400Maximum 100 events per batch
403Custom events are not available on the free tier