# Overview

Create trackable short links and read their click analytics.

A short link maps a generated 12-character id to a destination URL and records
every click. Creating one needs a token; following one does not.

```bash
curl -X POST https://api.console.buildbase.app/api/links \
  -H "Authorization: $BUILDBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Launch announcement","url":"https://example.com/launch"}'
```

The response carries a `linkId` — that is the public handle:

```json
{
  "_id": "665f…",
  "name": "Launch announcement",
  "url": "https://example.com/launch",
  "linkId": "a7Kd92LmQz01",
  "archived": false
}
```

> **Note:**
  `name` and `url` are both required. `linkId` is generated for you — a
  12-character random string, unique across the organization. You cannot choose
  a custom slug.


## Following a link

Two public redirect routes, neither requiring authentication:

| Path                           | When to use                                |
| ------------------------------ | ------------------------------------------ |
| `/api/r/:linkId`               | Short form. Resolves the id without an org |
| `/api/redirect/:orgId/:linkId` | Org-scoped, and the faster lookup          |

The short form has to search organizations to find the id, so prefer the
org-scoped route when you know the org — it goes straight to the record.

## What a click records

Each redirect writes an analytics row before forwarding:

| Field            | Contents                         |
| ---------------- | -------------------------------- |
| `linkId`         | The link followed                |
| `url`            | The short URL requested          |
| `destinationUrl` | Where the visitor was sent       |
| `ip`             | Client IP                        |
| `agent`          | User agent string                |
| `headers`        | Request headers                  |
| `info`           | Parsed device and browser detail |
| `ipInfo`         | Geographic lookup from the IP    |

> **Note:**
  Clicks are recorded with no bot filtering and no deduplication. A link fetched
  by a crawler, a link preview unfurler, or an email scanner counts the same as
  a human click.

Treat the numbers as relative — useful for comparing links, not for reporting
unique visitors.



Because IP and geographic data are stored per click, short links carry personal
data. Include them in whatever retention policy covers the rest of your
analytics.

## Reading analytics

| Method | Path                          | Returns               |
| ------ | ----------------------------- | --------------------- |
| `GET`  | `/api/links-analytics`        | Click rows, paginated |
| `GET`  | `/api/links-analytics/chart`  | Clicks over time      |
| `GET`  | `/api/links-analytics/counts` | Totals                |

Filter by link with the standard `filter` parameter:

```bash
curl -G https://api.console.buildbase.app/api/links-analytics \
  -H "Authorization: $BUILDBASE_TOKEN" \
  --data-urlencode 'filter={"linkId":"a7Kd92LmQz01"}' \
  --data-urlencode 'sort={"createdAt":-1}'
```

## Managing links

| Method   | Path             | Purpose                      |
| -------- | ---------------- | ---------------------------- |
| `GET`    | `/api/links`     | List links, paginated        |
| `GET`    | `/api/links/:id` | One link                     |
| `PATCH`  | `/api/links/:id` | Update name, URL, or archive |
| `DELETE` | `/api/links/:id` | Delete                       |

Updating `url` changes where an already-published link points, which is the main
reason to use one. Archiving keeps the record and its history; deleting removes
the link, and existing shares stop resolving.

## Next Steps

- [Admin API](/reference/admin-api) — tokens and list-query parameters.
- [Reporting](/reference/reporting) — where per-module analytics live.
