Authentication
Every request to the Track Link API carries an API key. Keys are created in the dashboard and shown once.
Create a key
Go to Developers in the dashboard and choose New key. Pick read-only unless you need to create or edit links. The key is displayed once at creation and cannot be retrieved afterwards — only its first few characters are ever shown again.
Keys look like tl_live_…. Treat one like a password: anyone holding it can act on your account with the access you granted.
Send it
Either header works.
curl https://api.gettrack.link/api/v1/links \
-H "Authorization: Bearer tl_live_your_key_here"
# equivalent
curl https://api.gettrack.link/api/v1/links \
-H "X-API-Key: tl_live_your_key_here"Prefer Authorization from a browser — it is the header allowed through CORS. Better still, do not call the API from a browser at all: a key in client-side JavaScript is a key you have published.
From your language
There is nothing to install and nothing to send beyond the header. These are equivalent.
# Python - standard library, no dependencies
import json, urllib.request
req = urllib.request.Request(
"https://api.gettrack.link/api/v1/links",
headers={"Authorization": "Bearer tl_live_your_key_here"},
)
with urllib.request.urlopen(req, timeout=20) as r:
links = json.load(r)["data"]# Python - requests
import requests
r = requests.get(
"https://api.gettrack.link/api/v1/links",
headers={"Authorization": "Bearer tl_live_your_key_here"},
timeout=20,
)
r.raise_for_status()
links = r.json()["data"]// Node 18+ - no dependencies
const r = await fetch("https://api.gettrack.link/api/v1/links", {
headers: { Authorization: "Bearer tl_live_your_key_here" },
});
if (!r.ok) throw new Error(`Track Link API ${r.status}`);
const { data: links } = await r.json();Every list response is shaped { data, pagination } and every single-resource response { data }, so the payload is always under data.
Sending a User-Agent that names your integration is worth doing — it is the first thing we look at when you report a problem — but it is not required, and no client library is preferred over another.
Scopes
| Scope | Can do | Requires |
|---|---|---|
| read | List links, read clicks, stats and usage | Any plan |
| read,write | Also create, edit and delete links; manage webhooks | Agency or Business |
The plan is checked on every request, not baked into the key. If an account is downgraded, its write keys stop being able to write immediately — no key rotation needed.
Rate limits
| Plan | Requests per minute |
|---|---|
| Free | 60 |
| Starter | 120 |
| Pro | 300 |
| Agency | 600 |
| Business | Unlimited |
The limit is per account, not per key — minting more keys does not buy more throughput. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 also carries Retry-After.
Plan limits still apply
The API is not a way around your plan. The same rules the dashboard enforces apply to every request:
- Data retention. Click and stats queries are clamped to your plan's window. Asking for an earlier
start_datereturns data from the start of that window, not an error. - Link count. Creating past your limit returns 403 with code
PLAN_LIMIT. - Locked links. After a downgrade, links over the cap keep redirecting but cannot be edited. They are marked
is_locked. You can still delete them. - Page size.
limitis capped at 100. Asking for more is a 400, not a silent truncation.
Errors
| Status | Meaning |
|---|---|
| 400 | Malformed request — a bad date, or limit above 100 |
| 401 | Missing, unknown, revoked or expired key |
| 403 | Read-only key, wrong plan, or a plan limit reached |
| 404 | No such resource in this workspace |
| 429 | Rate limited — see Retry-After |
A 401 never distinguishes "unknown" from "revoked" from "expired" — telling them apart would confirm to an attacker which guess was once real.
Revoking
Revoke from the Developers page. It takes effect immediately — there is no propagation delay to wait out. Revoking cannot be undone; create a new key instead.
Workspaces
A key belongs to the workspace it was created in, and can only ever see that workspace. To work across a personal workspace and an organization, create one key in each.
Next
- Links API — list, create, update, delete
- Webhooks — signed events, and how to verify them
- CLI and MCP server — the same API without writing HTTP