Appearance
Link Stats
link_statistics returns analytics for a single link over a date range, broken down by day, country, campaign, destination, and platform.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
link_id | uuid! | Yes | The ID of the link. |
start_time | date! | Yes | Start of the period, UTC. ISO 8601 — either YYYY-MM-DD or a full YYYY-MM-DDTHH:MM:SSZ timestamp. |
end_time | date! | Yes | End of the period, UTC. Must be after start_time. |
offset | String | No | Accepted for backward compatibility and currently ignored. All results are returned in UTC. |
referrer | String | No | Filter to a single referring host, e.g. instagram.com. |
utm_source | String | No | Filter to a single utm_source. |
utm_medium | String | No | Filter to a single utm_medium. |
utm_campaign | String | No | Filter to a single utm_campaign. |
country | String | No | Filter to a single ISO 3166-1 alpha-2 country code. |
WARNING
offset was previously documented as a required local-time offset. It is optional, it is typed String rather than Int, and the analytics backend does not read it — every bucket is a UTC day. Convert to local time on the client if you need it.
Request
graphql
query LinkStats(
$link_id: uuid!
$start_time: date!
$end_time: date!
) {
link_statistics(
link_id: $link_id
start_time: $start_time
end_time: $end_time
) {
events
countries
campaigns
destinations
platform_stats
}
}Variables:
json
{
"link_id": "9c4b2f10-...",
"start_time": "2026-02-20",
"end_time": "2026-02-25"
}Request only the sections you need. Each one is fetched from the analytics store separately, so dropping platform_stats from the selection genuinely saves work.
Response
json
{
"data": {
"link_statistics": {
"events": [
{ "count": 36, "day": "2024-02-20", "event": "clickthrough" },
{ "count": 48, "day": "2024-02-20", "event": "view" },
{ "count": 42, "day": "2024-02-21", "event": "clickthrough" },
{ "count": 61, "day": "2024-02-21", "event": "view" },
{ "count": 50, "day": "2024-02-22", "event": "clickthrough" },
{ "count": 88, "day": "2024-02-22", "event": "view" }
],
"countries": [
{ "count": 727, "country": "VE" },
{ "count": 238, "country": "CO" },
{ "count": 180, "country": "MX" },
{ "count": 118, "country": "EC" }
],
"campaigns": [
{
"count": 518,
"event": "view",
"referrer": "m.facebook.com",
"utm_campaign": null,
"utm_medium": "paid",
"utm_source": "facebook"
},
{
"count": 282,
"event": "clickthrough",
"referrer": "m.facebook.com",
"utm_campaign": null,
"utm_medium": "paid",
"utm_source": "facebook"
}
],
"destinations": [
{
"count": 726,
"destination_id": "3aad8009-a307-4429-a586-8b3dbe39cdda",
"event": "clickthrough"
}
],
"platform_stats": [
{ "count": 402, "day": "2024-02-20", "platform": "ios" },
{ "count": 288, "day": "2024-02-20", "platform": "android" }
]
}
}
}Sections
events
Daily counts per event type. Two event types are recorded:
| Event | Meaning |
|---|---|
view | The link page was loaded. |
clickthrough | A visitor clicked a destination button. |
| Field | Description |
|---|---|
day | UTC day, YYYY-MM-DD. |
event | view or clickthrough. |
count | Number of events that day. |
A day with no activity is omitted, not returned as zero. Fill gaps client-side when charting, or your x-axis will skip days.
Clickthrough rate is clickthrough / view for the same day.
countries
Totals per country across the whole range, sorted descending.
| Field | Description |
|---|---|
country | ISO 3166-1 alpha-2 code. |
count | Events from that country. |
campaigns
Traffic sources, split by event type. This is the section to use for ad attribution.
| Field | Description |
|---|---|
referrer | Referring host, e.g. instagram.com. |
utm_source, utm_medium, utm_campaign | UTM parameters as they arrived on the URL. null when absent. |
event | view or clickthrough. |
count | Events matching that combination. |
Rows appear per unique combination, so the same campaign shows up twice — once for view, once for clickthrough. Pair them to get a per-campaign conversion rate.
destinations
Clicks per destination button.
| Field | Description |
|---|---|
destination_id | ID from link_destinations. |
event | Always clickthrough. |
count | Clicks on that button. |
Resolve IDs to names by fetching the link's destinations — see Destinations:
graphql
query { links_by_pk(id: $link_id) { destinations { id type cta } } }platform_stats
Daily counts per device platform (ios, android, desktop, and similar).
Filtering
The optional arguments narrow every section at once. To see only paid Instagram traffic:
graphql
query PaidInstagram($link_id: uuid!, $start_time: date!, $end_time: date!) {
link_statistics(
link_id: $link_id
start_time: $start_time
end_time: $end_time
utm_source: "instagram"
utm_medium: "paid"
) {
events
countries
destinations
}
}Or a single market:
graphql
link_statistics(
link_id: $link_id
start_time: $start_time
end_time: $end_time
country: "MX"
) { events campaigns }Filters are exact-match and combine with AND. There is no wildcard or list form — to compare several campaigns, issue one query per campaign, or request unfiltered campaigns and group client-side.
Notes and limits
- Access is checked against link ownership. Requesting stats for a link you do not manage fails rather than returning empty data.
- Data comes from a separate analytics store, so very recent events may lag by a few minutes. Do not treat this as a real-time counter.
- Days with no events are omitted from every section.
link_statisticsis the most expensive field in the API. Cache aggressively, request only the sections you use, and prefer one wide date range over many narrow ones.- For cheap lifetime totals with no date range, read
views_totalandclickthroughs_totalfrom the link itself — see Get Link — or use Link Totals.
Deprecated
link_stats (singular, no _statistics) is an older query that depends on a backend field that no longer exists. It is not functional. Use link_statistics.
See also
- Artist Stats — the same daily events across an artist's whole catalog
- Link Totals — lifetime view/click totals for every link at once