Track link clicks
A short link that nobody measures is just a redirect. This API pulls the numbers behind a given short URL — its total click count, the date it was created and where it points — and hands it back as structured data you can pipe straight into a dashboard, report or attribution model, without scraping an analytics UI.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The question this answers
Once a short link is live, the obvious next question is simple: did it work? How many people actually followed it. Answering that by eyeballing a web dashboard doesn't scale past a handful of links, and most dashboards weren't built to be queried programmatically in the first place. dev.short_url_stats exists to turn that question into an API call: give it a short link, get back the number behind it.
What the response actually contains
You submit the short link (or its identifier) you want data for, and the task returns the total number of clicks the link has received, the date it was created, and the destination it points to — the plain signal you need without being invasive. As with every endpoint here, the call is async: you get a task_id immediately, and the statistics arrive by signed webhook or a 24-hour signed link once ready.
Who actually needs per-link click counts
Growth and marketing teams comparing channel performance across campaigns that share the same offer but different short links. Product teams validating that an in-app referral link is actually being used before investing more in the referral feature. Support and fraud teams spot-checking whether a link that's driving unusual traffic is being abused. Anyone running a link-in-bio or affiliate setup who needs per-link performance without logging into a separate dashboard for every one.
What the count does and doesn't tell you
It's worth being upfront about scope: the number returned is a single aggregate total of clicks, not a per-visitor log. It doesn't tell you who clicked, from what country, on what device, or through which referrer — it counts how many times the link was followed. That keeps it privacy-friendly and simple, but it also means it measures reach, not audience: if you want to compare channels, mint a separate short link per channel with dev.short_url, and the difference between their counts is the comparison.
Fitting it into a reporting pipeline
Because results come back as structured data via webhook, you can schedule a stats pull after a campaign ends, or query it on demand when someone asks 'how's that link doing?' Pair it with dev.short_url so link creation and link performance live in the same workflow instead of two disconnected tools.
What you can do with it
Campaign comparison
Pull click counts for every short link in a multi-channel campaign to see which channel actually drove traffic, not just which one got the most impressions.
Referral program validation
Check whether referral links generated inside your app are being clicked at all before deciding whether to expand the referral feature.
Anomaly spot-checks
Query the click count for a link showing an unusual traffic spike to judge whether the volume looks organic or automated.
Affiliate and link-in-bio reporting
Generate a per-link performance summary for creators or partners without giving them dashboard access to your full account.
FAQ
What data does the click analytics API return?
The total number of clicks a short link has received, the date it was created, and the destination URL it points to.
Does it track individual users?
No — the data returned is a single aggregated count, not a personal log tied to identifiable visitors.
Does it show where clicks came from, or on what device?
No — it returns the total click count, not geography, referrers or device data. To compare sources, create a separate short link per channel with dev.short_url and compare their counts.
Can I get stats for any short link, or only ones I created?
Only for short links created under your account — you can't query analytics for links you don't own.
Is there a free way to test this?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How do I receive the statistics?
Via signed webhook (recommended) or a signed link valid for 24 hours, matching the delivery pattern of every task in the platform.
What's the cost per stats request?
0.002 dollars per request, and you're never charged for a request that fails after retries.
Can I pull stats for many links in bulk?
Yes — submit one request per link asynchronously and collect results as each webhook arrives; there's no need to poll a dashboard link by link.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/short-url-stats \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"id":"abc123"}'const res = await fetch("https://api.kit.forhosting.com/dev/short-url-stats", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"id": "abc123"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/short-url-stats",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"id": "abc123"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/short-url-stats", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"id":"abc123"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"id":"abc123"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/short-url-stats", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"id": "abc123"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.short_url_stats",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |