Analytics Exports and Reconciliation
Use this guide to query analytics, export data, and understand how metrics are calculated and aggregated.
When to use
- You want to export click or conversion data for reporting.
- You need to understand what a metric means and how it is calculated.
- You want to know why analytics numbers may differ from other sources.
Available dimensions
| Dimension | groupBy value | What it shows |
|---|---|---|
| Time series | day | Click counts per day |
| Link | slug | Clicks per link slug |
| Country | country | Clicks by ISO country code |
| Device | device | Clicks by MOBILE, TABLET, DESKTOP, BOT, UNKNOWN |
| Referrer | referrer | Clicks by referring domain (or "direct") |
| Segment | segment | Clicks by visitor behavior segment |
Metric definitions
| Metric | Definition |
|---|---|
| clicks | Total redirect events (HTTP 302/307 responses) |
| qualifiedClicks | Clicks minus bot clicks |
| botClicks | Clicks from detected bot user agents |
| conversions | Post-click events ingested via POST /v2/public/conversions |
| impressions | Intent observation events (segment analytics only) |
| revenue | Sum of value fields from conversion payloads |
Freshness
Analytics are aggregated from CloudFront real-time logs. The target latency is under 60 minutes.
Each response includes a freshness block:
{
"freshness": {
"status": "FRESH",
"lastUpdatedAt": "2026-02-25T12:05:00Z",
"slaMinutes": 60
}
}
| Status | Meaning |
|---|---|
| FRESH | Updated within the last 60 minutes |
| STALE | Older than 60 minutes |
| UNKNOWN | No data available yet |
Confidence score
When ?confidence=true is passed, the response includes a confidence score (0-100) based on:
- Whether any clicks exist
- Whether conversions exceed clicks (anomaly)
- Bot traffic ratio
- Data staleness
Higher scores indicate more reliable data.
UI path
- Open
https://app.{PUBLIC_DOMAIN}. - Navigate to your handle and open Analytics.
- Choose a dimension (slug, country, device, referrer, segment).
- Optionally filter by date range or campaign.
- Use the Export button to download CSV or JSON.
Required auth
- CREATOR-level
JWTor above to query analytics. PATwithanalytics.*scope for automation.- PRO or ENTERPRISE plan required for exports (
exportsfeature gate).
API fallback
Query analytics
GET /v2/handles/{handle}/analytics
Query parameters:
groupBy(required):day,slug,country,device,referrer,segmentfromDay,toDay(optional): Date range inyyyymmddformatcampaignId(optional): Filter to a specific campaignslug(optional): Filter to a specific linkconfidence(optional): Include confidence scorefunnel(optional): Include funnel metricssort(optional):ascordesc
Export analytics
GET /v2/handles/{handle}/analytics/export
Query parameters:
format:jsonorcsvgroupBy: Same options as abovefromDay,toDay: Date rangecampaignId: Optional campaign filter
Requires PRO or ENTERPRISE plan.
Submit a conversion
POST /v2/public/conversions
{
"ctx": "signed_context_token",
"eventType": "conversion",
"idempotencyKey": "unique_key",
"value": 99.99,
"currency": "USD"
}
The ctx token is minted at redirect time and must be submitted within its TTL (default 15 minutes). Duplicate submissions with the same idempotencyKey are safely deduplicated.
Rate limit: 120 conversions per IP per hour.
Reconciliation notes
- Click counts come from CloudFront logs, not from application-level records. This means analytics reflect actual network-level redirect events.
- Dimension rollups are forward-only. Country, device, and referrer breakdowns are only available from the date dimension tracking was enabled.
- Conversions require a valid
ctxtoken. If the context token has expired, the conversion cannot be attributed. This means total clicks will typically be higher than attributable conversions. - Duplicate conversions are deduplicated by idempotency key. Replaying the same conversion does not double-count.
- Bot detection filters known user agents but cannot catch all automated traffic. The
botClicksmetric provides transparency. - Rollup counts are approximate. The at-least-once delivery model means occasional recounts during retries.
Common errors
| Code | Error | Cause |
|---|---|---|
| 400 | invalid_group_by | Unrecognized groupBy value |
| 400 | invalid_ctx | Context token expired or malformed |
| 403 | feature_locked | Export requires PRO plan |
| 429 | rate_limited | Conversion ingestion rate limit exceeded |
Related: