Skip to main content
Social mediaBy SendURL team10 min read

How to Track TikTok Bio Link Clicks and Find the Video

Part of the Social media handbook

Put a short link in your TikTok profile, then line its click times up with your posts to see which video sent people to your site. UTM values and a script included.

To track clicks on your TikTok bio link, put a short link that counts every visit in your profile's Website field, then read its clicks against the times you posted. TikTok can't tell you which video sent a visitor, because the link sits on your profile, not on the video, so timing is how you connect the two.

A tracked link records each click with its time, country, device, browser and operating system. It never records a name. This guide covers who can add a bio link, how to set one up, how to work out which video drove the clicks, and the UTM values GA4 files correctly. It is part of the social media tracking handbook.

Not every account can. TikTok decides who gets a clickable link in the profile by account type, follower count and region, and it has changed the rules before. Many guides quote a 1,000-follower threshold or a registered business account; we couldn't confirm the current rule on TikTok's own help centre when we checked on 15 October 2026, so we don't repeat it as fact.

The quickest way to know is to look:

  1. Open your profile in the TikTok app and tap Edit profile.
  2. If there is a Website field, you can add a link. Paste it there.
  3. If there isn't, your account doesn't have the feature yet. Typing a URL into the bio text doesn't help: it shows as plain text, not a link.

This guide is about the profile link because it is the one link that stays put. TikTok also has shop, ads and other link features for some accounts and regions; those report their own clicks inside TikTok.

  1. Build the destination with UTM parameters if you use GA4: https://example.com/drops/oct-hoodie?utm_source=tiktok&utm_medium=social&utm_campaign=2026-10-hoodie-drop&utm_content=bio.
  2. Shorten it with a slug people can read on screen, for example snu.to/mayabakes-tt. You can do it on the home page without an account, but only a free account lets you pick the slug.
  3. Paste the short link into the Website field and save.
  4. Open it once yourself to check it lands on the right page. That visit counts as a click, so note the time and ignore it later.

Each click then shows up on the link's page in the console with its time, country (no city), device, browser and operating system. That is SendURL's free link tracker; the same records come out of the API as JSON.

UTMs go on the destination, never on the short link. snu.to/mayabakes-tt?utm_source=tiktok doesn't work: SendURL redirects to the stored destination and doesn't forward a query string added to the short link.

Slugs are unique across all of SendURL, case-sensitive and permanent, so add something of yours (mayabakes-) and pick lowercase. The slug naming guide has patterns that stay readable in a video overlay.

Which TikTok video drove the clicks?

There is no field for it. A tap on your bio link comes from your profile page, and nothing in the request says which video brought the person there. You can still get close, three ways.

1. Match clicks to post times. If a video sends people to your profile, their clicks arrive while that video is being watched. Give each click to the latest video posted before it, within a window, and compare the totals. The script below does that.

2. Change the destination, keep the link. If each video promotes a different page, point the same short link at the page of the newest video. The Website field never changes. SendURL doesn't store past destinations, so note the time of each change: clicks before it went to the old page, clicks after it to the new one. Changing the destination is an API call, not a console form:

Point the bio link at the newest video's pageShell
curl -X PATCH "https://api.sendurl.to/api/v1/links/$LINK_ID" \
  -H "Authorization: Bearer $SENDURL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destinationUrl": "https://example.com/drops/nov-scarf?utm_source=tiktok&utm_medium=social&utm_campaign=2026-11-scarf-drop&utm_content=bio"}'

The redirect switches within seconds. LINK_ID is the link's id, returned when you create it (update a link in the API reference).

3. A new link per campaign. Put snu.to/mayabakes-tt-oct in the profile for October and snu.to/mayabakes-tt-nov for November. Each link's total is that campaign's bio clicks with no arithmetic. It costs an edit to your profile each month, and the old link keeps counting the odd click from screenshots and shares.

Count clicks per video with Python

The script reads every click of the bio link and gives each one to the most recent video posted before it, if that video went live less than 24 hours earlier. Clicks outside every window are your baseline: people who found your profile some other way. The script needs requests (pip install requests).

clicks_per_video.pyPython
import os, time
from collections import Counter
from datetime import datetime, timedelta

import requests

API = "https://api.sendurl.to/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SENDURL_API_KEY']}"}

# When each video went live, in UTC (+00:00) or with your own offset.
VIDEOS = {
    "unboxing": "2026-10-12T17:30:00+00:00",
    "behind-the-scenes": "2026-10-13T08:00:00+00:00",
    "sale-countdown": "2026-10-14T18:15:00+00:00",
}
WINDOW = timedelta(hours=24)

def parse(ts):
    return datetime.fromisoformat(ts.replace("Z", "+00:00"))

def clicks(link_id):
    params = {"limit": 10}
    while True:
        r = requests.get(f"{API}/links/{link_id}/clicks", headers=HEADERS, params=params, timeout=10)
        r.raise_for_status()
        page = r.json()
        yield from page["clicks"]
        if not page["pagination"]["hasMore"]:
            return
        params["cursor"] = page["pagination"]["nextCursor"]
        time.sleep(0.25)  # stay under the API's rate limit

posted_at = {name: parse(t) for name, t in VIDEOS.items()}
posted = sorted((t, name) for name, t in posted_at.items())

def video_for(at):
    """The latest video posted before this click, if it is inside the window."""
    before = [(t, name) for t, name in posted if t <= at]
    if before and at - before[-1][0] <= WINDOW:
        return before[-1][1]
    return "(no video in the last 24 h)"

per_video = Counter()
by_hour = Counter()
for c in clicks(os.environ["LINK_ID"]):
    if not c["browser"]:
        continue  # previews and scripts usually have no browser in the user agent
    at = parse(c["clickedAt"])
    video = video_for(at)
    per_video[video] += 1
    if not video.startswith("("):
        hours = int((at - posted_at[video]).total_seconds() // 3600)
        by_hour[hours] += 1

for video, n in per_video.most_common():
    print(f"{n:5}  {video}")
print("\nclicks by hours after posting:")
for h in sorted(by_hour):
    print(f"  {h:2} h  {by_hour[h]}")

Run it as LINK_ID=<id> python3 clicks_per_video.py. The output looks like this (example numbers):

OutputText
   41  sale-countdown
   23  unboxing
   12  (no video in the last 24 h)
    9  behind-the-scenes

clicks by hours after posting:
   0 h  31
   1 h  14
   2 h  8
   …

Read it with two caveats. Videos that go viral late break the 24-hour assumption, so widen WINDOW if your views build over days. And two videos posted close together share their clicks with whichever came second; space posts a few hours apart when you want a clean read. The click object reference lists every field the API returns.

SendURL doesn't filter bots or count unique visitors, which is why the script skips clicks with no browser. Bot clicks and link previews explains what else can follow a link and how to spot it.

UTM parameters for TikTok

If the destination has GA4, tag it. tiktok is on Google's list of social sources, so utm_source=tiktok lands in Organic Social with any non-paid medium, and utm_medium=social makes that certain (GA4 default channel group). Values are case-sensitive in reports: TikTok and tiktok show as two sources, so keep them lowercase.

PlacementShort linkutm_sourceutm_mediumutm_contentGA4 channel
Profile Website fieldsnu.to/mayabakes-tttiktoksocialbioOrganic Social
Profile link for one campaignsnu.to/mayabakes-tt-octtiktoksocialbio-octOrganic Social
A creator's bio, during a collabsnu.to/mayabakes-tt-lenatiktoksocialcreator-lenaOrganic Social
TikTok adsnone (see below)tiktokpaid-socialthe ad's namePaid Social

Copy-ready destinations for the October campaign:

Tagged destinationsText
https://example.com/drops/oct-hoodie?utm_source=tiktok&utm_medium=social&utm_campaign=2026-10-hoodie-drop&utm_content=bio
https://example.com/drops/oct-hoodie?utm_source=tiktok&utm_medium=social&utm_campaign=2026-10-hoodie-drop&utm_content=creator-lena
https://example.com/drops/oct-hoodie?utm_source=tiktok&utm_medium=paid-social&utm_campaign=2026-10-hoodie-drop&utm_content=countdown-15s

For ads, put the tagged destination straight into the ad. TikTok counts ad clicks itself, and a short link adds nothing there. The UTM parameters guide has the full rules and examples for other channels.

Cross-posting the same video to Instagram

Posting one video on TikTok and as an Instagram Reel? Give each profile its own link: snu.to/mayabakes-tt in TikTok, snu.to/mayabakes-ig in Instagram. Two links answer "which app sends more people" with two totals. One shared link leaves you guessing from the referrer, when there is one at all. The Instagram link tracking guide covers bio slots and DMs there, and tracking Instagram Story link sticker clicks covers Stories.

When to post, from your own clicks

Published "best time to post on TikTok" studies measure views or engagement, not link clicks. Buffer's March 2026 study of more than 52 million posts, for instance, ranks TikTok times by median views (Buffer). A video can get plenty of views at an hour when nobody leaves the app.

Your bio link's click times are the better signal for link posts. Run the script above for a month, look at the hours after posting that bring the most clicks, and try posting earlier or later. The best time to post guide turns click times into a weekday-by-hour heatmap in your audience's time zone.

Checklist

  • Profile has a Website field (Edit profile); if not, nothing to track yet
  • Destination tagged: utm_source=tiktok&utm_medium=social&utm_campaign=<yyyy-mm-campaign>&utm_content=bio
  • UTMs on the destination, not on the short link
  • Custom slug with your own prefix, lowercase: snu.to/<you>-tt
  • Opened once to check the landing page; that test click noted
  • Post times written down in UTC for the timing script
  • Separate links for TikTok, Instagram and each creator
  • Clicks with no browser treated as previews or scripts, not people
  • Destination changes made through the API, so the profile link never changes

Shorten your first TikTok link on the SendURL home page, no account needed.

Frequently asked questions

Can you see who clicked the link in your TikTok bio?

No. Neither TikTok nor a short link names the people who tap it. A tracked link shows how many clicks it got, when, and the country, device and browser behind each one.

Why can't I add a link to my TikTok bio?

TikTok only shows the Website field to some accounts, depending on account type, follower count and region. If Edit profile has no Website field, your account doesn't have the feature yet. A URL typed into the bio text is not a link.

How do I know which TikTok video got the clicks?

The bio link sits on your profile, not on a video, so the click carries no video ID. Compare click times with post times: clicks that arrive in the hours after a video went live are most likely from that video.

How do I see TikTok traffic in Google Analytics?

Put UTM parameters on the destination URL: utm_source=tiktok and utm_medium=social. GA4 files the visit under Organic Social. Put them on the destination, not on the short link, because a short link doesn't pass its own query string on.

Start tracking links free.

Create your first short link with click analytics in seconds. No credit card, no sign-up to start.

Shorten a link