---
title: Short links
description: How Retidal's tracked short links capture ad-platform Click IDs and feed them into attribution via the _tl and _tk parameters.
---

Short links are the bridge between an ad click and everything that follows.
Retidal generates them (in the console — see below), you use them as your ad
destination, and each click seeds the attribution record your later events
attach to.

## Prerequisites

- A short link created in the console (see [Creating links](#creating-links) below) and
  used as the destination URL on your ad platform.

## The redirect

```
GET https://api.retidal.com/s/{code}
```

A click on `GET /s/{code}` always gets a **`302`** redirect — never a permanent
redirect. A permanent redirect would be cached by the browser, so a returning
visitor's second click would never hit Retidal at all and the click would go
untracked. `302` guarantees every click is seen.

On each redirect, Retidal:

1. Extracts all 29 platforms' Click IDs plus UTM parameters, IP, user agent,
   referrer, and geo from the inbound query string, and persists them
   asynchronously.
2. Appends `_tl=<shortLinkId>` to the destination URL, passing through the rest
   of the inbound query string and filling in default UTM values.
3. Sets first-party cookies scoped to `Domain=retidal.com` (`Path=/;
   SameSite=Lax`, `Secure` over https): a visitor cookie (1 year max-age) and a
   session cookie (30 minutes), reusing existing values where present.

```
User clicks ad
  → https://api.retidal.com/s/aBc123?bd_vid=xxx
  → 302 redirect
  → https://landing-page.com/?bd_vid=xxx&utm_source=baidu&_tl=clxyz123abc
```

### Failure responses

| Status | Meaning |
| --- | --- |
| `404` | The short code doesn't resolve to any link (`GET /s/{code}`). |
| `410` | The link exists but is paused or has expired (`GET /s/{code}`). |

## `_tl` — attribution after a redirect

`_tl` is the short link's record **ID**, appended by Retidal itself after a
redirect. Read it from the landing page URL and send it back as `shortLinkId` on
your subsequent events:

```javascript
const urlParams = new URLSearchParams(window.location.search);
const shortLinkId = urlParams.get("_tl");

await fetch("https://api.retidal.com/api/v1/t", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-API-Key": "your-api-key" },
  body: JSON.stringify({
    eventName: "purchase",
    visitorId: getVisitorId(),
    shortLinkId,
    properties: { amount: 9900 },
  }),
});
```

## `_tk` — attribution without a redirect

`_tk` is different: it's an **inbound** parameter, and its value is the short
link's **code**, not its ID. Use it when the ad destination is the real landing
page URL directly (no `/s/{code}` hop), with `_tk=<code>` appended to it manually.
On page load, your SDK reads `_tk` and reports it as `shortLinkCode` (or `_tk`)
on the event so Retidal can resolve it back to the same short link and its ad
platform configuration:

```javascript
const tk = urlParams.get("_tk");
if (tk) {
  await fetch("https://api.retidal.com/api/v1/t", {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-API-Key": "your-api-key" },
    body: JSON.stringify({
      eventName: "page_view",
      visitorId: getVisitorId(),
      shortLinkCode: tk,
      landingUrl: window.location.href,
      clickIds: extractClickIds(),
    }),
  });
}
```

| Parameter | Direction | Carries | Use it for |
| --- | --- | --- | --- |
| `_tl` | Outbound — appended by Retidal after a `/s/{code}` redirect | Short link **ID** | Standard flow: ad → short link → redirect → landing page |
| `_tk` / `shortLinkCode` | Inbound — you append it to the direct landing URL yourself | Short link **code** | Direct-landing ads that skip the redirect hop |

## Tracking-only links

A short link's ad-platform configuration is optional. When it's unset, the link
still records clicks and visits but never triggers a conversion callback to any
ad platform — useful for plain traffic measurement, non-paid channels (social
shares, email), or a link you haven't wired up to a platform yet.

## Creating links

Short links are created and managed in the Retidal console (`destinationUrl` and
`campaignId` are required; `adPlatformConfigId` and UTM overrides are optional),
not through the ingestion API documented on this page — the console session
handles creation, and this page covers what happens once a link exists and gets
clicked.

## What this unlocks

A click captured through a short link seeds the attribution record that
[Cross-device attribution](/docs/attribution/cross-device)'s Tier 0 (explicit) priority
reads from — without it, later events fall back to lower-priority, less accurate
attribution tiers.

## Verify it worked

```bash
curl -s -o /dev/null -D - https://api.retidal.com/s/{code} | grep -i location
# expect: HTTP/2 302, with a Location header carrying the destination URL plus
# _tl=<shortLinkId> appended — that _tl value is what you read back and send as
# shortLinkId on subsequent events
```

## If it doesn't work

If the redirect 404s/410s, or `_tl`/`_tk` is missing or misread on the landing page so
the click's attribution record ends up wrong or absent, work through
[Attribution looks wrong](/docs/troubleshooting/attribution-looks-wrong).

## Next steps

<CardGroup cols={2}>
  <Card title="Click IDs" href="/docs/sending-data/click-ids">
    The full 29-platform parameter reference.
  </Card>
  <Card title="Cross-device attribution" href="/docs/attribution/cross-device">
    How Retidal decides which click an event belongs to.
  </Card>
</CardGroup>
