Skip to Content
Retargeting Pixels on every Link 🎉
Link Squeeze LogoLink Squeeze Docs
FeaturesToolsPricingBlog
CTRL K
CTRL K
    • How to Add Custom Domains to Link Squeeze
    • How to Shorten Links Using Link Squeeze
    • How to Shorten Shopify URLs Using Link Squeeze
    • How to Add Google Ads Tag to Link Squeeze
    • How to Add Meta Pixel to Link Squeeze
    • How to Add Retargeting Pixels to links in Link Squeeze
    • How to Create a Custom Audience on Facebook and Instagram
    • Authentication
    • Links
    • Click Analytics
    • QR Codes
    • Domains
    • Pixels
    • Webhooks
    • Errors & Rate Limits
  • Features
  • Tools
  • Pricing
  • Blog
    • How to Add Custom Domains to Link Squeeze
    • How to Shorten Links Using Link Squeeze
    • How to Shorten Shopify URLs Using Link Squeeze
    • How to Add Google Ads Tag to Link Squeeze
    • How to Add Meta Pixel to Link Squeeze
    • How to Add Retargeting Pixels to links in Link Squeeze
    • How to Create a Custom Audience on Facebook and Instagram
    • Authentication
    • Links
    • Click Analytics
    • QR Codes
    • Domains
    • Pixels
    • Webhooks
    • Errors & Rate Limits

On This Page

  • The click object
  • About device
  • About link_id
  • List clicks across the account
  • Polling for new clicks
  • List clicks for one link
  • Click statistics
Question? Give us feedback
API ReferenceClick Analytics

Click analytics

Three endpoints report on clicks: an account-wide log across every link, a per-link log, and an aggregated time series of click counts. All three require the links:read scope.

MethodPathScopeReturns
GET/v1/clickslinks:readPaginated log across all your links
GET/v1/links/{id}/clickslinks:readPaginated log for one link
GET/v1/links/{id}/statslinks:readClick counts grouped by period

A link belonging to another account returns 404 not_found from the nested endpoints.

The click object

{ "id": "c41d8b30-9e57-4a22-b6f8-1d0e7a94c2b5", "ip": "203.0.113.42", "country": "US", "visitor_id": "visitor-9f2c1b", "referrer": "https://twitter.com/", "device": "iPhone", "browser": "Safari", "platform": "iOS", "created_at": "2026-08-28T10:16:31.000000Z" }
FieldTypeDescription
iduuidThe click’s identifier
ipstring | nullIP address the click came from
countrystring | nullTwo-letter country code resolved from the IP
visitor_idstring | nullPseudonymous visitor identifier, stable across clicks from the same visitor
referrerstring | nullThe page the visitor came from, when the browser sent one
devicestring | nullDevice model when known (iPhone), otherwise a category (Mobile, Tablet, Desktop, Bot)
browserstring | nullBrowser name
platformstring | nullOperating system
created_attimestampWhen the click was recorded

Any of the enriched fields can be null — referrer when the visitor navigated directly, country when the IP could not be resolved, and the device fields when the user agent could not be parsed.

About device

device mixes two vocabularies by design. When the user agent identifies a specific model it reports that (iPhone, Nexus 5); when it does not — which is the normal case for desktop browsers — it falls back to a coarse category: Mobile, Tablet, Desktop, or Bot.

Group by it and you get sensible buckets either way, but do not assume the value is drawn from a fixed set.

About link_id

link_id is present on GET /v1/clicks and in webhook deliveries, where the link a click belongs to would otherwise be ambiguous. It is omitted from GET /v1/links/{id}/clicks, because the link is already named in the request path.

List clicks across the account

GET /v1/clicks

Scope: links:read

Every click on every link you own, newest first, in the standard paginated shape. This is the endpoint to poll for “any new click on any of my links” — the per-link log below would need one request per link, re-checked every time a link is added.

Query parameterTypeDescription
link_iduuidOnly return clicks on this link. Must be a valid UUID.
pageintegerPage to return. Defaults to 1.
per_pageintegerResults per page. Defaults to 15, maximum 100.

Each click includes link_id, so you can attribute it without a second request.

curl "https://app.linksqueeze.io/api/v1/clicks?per_page=100" \ -H "Authorization: Bearer $LINKSQUEEZE_API_KEY" \ -H "Accept: application/json"
{ "data": [ { "id": "c41d8b30-9e57-4a22-b6f8-1d0e7a94c2b5", "link_id": "9b1f4e2a-6c3d-4a17-9f2e-7c8d5a1b3e40", "ip": "203.0.113.42", "country": "US", "visitor_id": "visitor-9f2c1b", "referrer": "https://twitter.com/", "device": "iPhone", "browser": "Safari", "platform": "iOS", "created_at": "2026-08-28T10:16:31.000000Z" } ], "links": { "first": "...", "last": "...", "prev": null, "next": "..." }, "meta": { "current_page": 1, "per_page": 100, "total": 4210 } }

link_id filters by the link’s public UUID. A malformed value is rejected with 422, and a UUID belonging to another account simply returns an empty result rather than an error.

Polling for new clicks

Results are ordered newest first, so page 1 always holds the most recent activity. Record the id of the newest click you have processed, then read forward until you meet it again.

For anything latency-sensitive, prefer the link.clicked webhook — it pushes each click as it happens and removes the polling entirely.

List clicks for one link

GET /v1/links/{id}/clicks

Scope: links:read

Returns the raw click log for a single link, newest first, in the standard paginated shape. Clicks here omit link_id, since the link is named in the path.

Query parameterTypeDescription
pageintegerPage to return. Defaults to 1.
per_pageintegerResults per page. Defaults to 15, maximum 100.
curl "https://app.linksqueeze.io/api/v1/links/9b1f4e2a-6c3d-4a17-9f2e-7c8d5a1b3e40/clicks?per_page=100" \ -H "Authorization: Bearer $LINKSQUEEZE_API_KEY" \ -H "Accept: application/json"
{ "data": [ { "id": "c41d8b30-9e57-4a22-b6f8-1d0e7a94c2b5", "ip": "203.0.113.42", "country": "US", "visitor_id": "visitor-9f2c1b", "referrer": "https://twitter.com/", "device": "Desktop", "browser": "Safari", "platform": "iOS", "created_at": "2026-08-28T10:16:31.000000Z" } ], "links": { "first": "...", "last": "...", "prev": null, "next": "..." }, "meta": { "current_page": 1, "per_page": 100, "total": 128 } }

Click statistics

GET /v1/links/{id}/stats

Scope: links:read

Returns click counts grouped into time buckets — the shape you want for a chart, without paging through every individual click.

Query parameterTypeDescription
group_bystringOne of day, week, or month. Defaults to day.
fromdateOnly count clicks from this date onward. Inclusive, from the start of the day.
todateOnly count clicks up to this date. Inclusive, through the end of the day.
curl "https://app.linksqueeze.io/api/v1/links/9b1f4e2a-6c3d-4a17-9f2e-7c8d5a1b3e40/stats?group_by=day&from=2026-07-01&to=2026-07-31" \ -H "Authorization: Bearer $LINKSQUEEZE_API_KEY" \ -H "Accept: application/json"
{ "data": [ { "period": "2026-07-01", "clicks": 2 }, { "period": "2026-07-02", "clicks": 1 } ] }
FieldTypeDescription
perioddateThe start of the bucket, as YYYY-MM-DD
clicksintegerNumber of clicks recorded within that bucket

Buckets are sorted oldest first. period is always the first day of the bucket: the day itself for day, the Monday for week, and the first of the month for month.

Empty periods are omitted. A day with no clicks does not appear in the response as a zero — it is simply absent. If you are drawing a chart, generate the full range of periods yourself and fill in the gaps with 0.

This response is not paginated and has no links or meta object. Narrow it with from and to rather than by paging.

An invalid group_by value is rejected with 422 validation_error.

Last updated on September 5, 2026
LinksQR Codes
Link Squeeze LogoLink Squeeze

Branded short links with built-in retargeting pixels for performance marketers.

Product
  • Pricing
  • Sign up
  • Log in
  • Use cases
  • Docs
  • API
  • Blog
Free tools
  • Link shortener
  • UTM builder
  • Link Preview Generator
  • All tools
Legal
  • Privacy policy
  • Terms of service
  • Support
Compare
  • Bitly
  • Rebrandly
  • Short.io
  • Replug
  • Dub
© 2026 Link Squeeze. All rights reserved.Made for marketers who measure everything.