> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Short Links API

> Create branded short links and read click stats. Public redirects live at `/l/:code` (no API prefix).

# Short Links API

Branded short URLs for messages and campaigns. By default links resolve on the platform host (`https://api.orbit.devotel.io/l/abc123`); configure a vanity domain in **Settings → General** to mint links on your own host instead (e.g. `https://go.yourbrand.com/abc123`). The redirect handler (`GET /l/:code`) is mounted at the root of the API host and is rate-limited to 60 req/min per IP. Click data is captured asynchronously and exposed via the stats endpoint.

**Base path:** `/api/v1/links` (management) — public redirect at `https://api.orbit.devotel.io/l/{code}`

**Authentication:** API key (`X-API-Key`) or session JWT for management; the redirect itself is anonymous.

| Method   | Path                                        | Purpose                                                              |
| -------- | ------------------------------------------- | -------------------------------------------------------------------- |
| `POST`   | `/api/v1/links/`                            | Create a short link                                                  |
| `GET`    | `/api/v1/links/`                            | List short links                                                     |
| `GET`    | `/api/v1/links/insights`                    | Tenant-wide insights — summary KPIs, top links, daily click timeline |
| `GET`    | `/api/v1/links/contacts/{contactId}/clicks` | Per-contact link-click history                                       |
| `GET`    | `/api/v1/links/{id}/stats`                  | Per-link click stats                                                 |
| `DELETE` | `/api/v1/links/{id}`                        | Delete a short link                                                  |

## Default short-link host & branded domains

Every short link resolves through the redirect handler at `GET /l/{code}`. The **host** a link is minted on is resolved in this order:

1. **Your tenant's branded short-link domain**, if you've set one under **Settings → General → Branded short-link domain**. It must be a bare `https://` host with no path, query, or fragment (for example `https://go.yourbrand.com`) whose DNS is CNAME'd to Orbit's redirector. A malformed value falls back to the platform default rather than blocking the send.
2. **The platform default host** — `https://api.orbit.devotel.io` — used for every tenant that hasn't configured a branded domain.

So a link minted for a tenant with no branded domain looks like `https://api.orbit.devotel.io/l/abc123`, while a tenant on `go.yourbrand.com` gets `https://go.yourbrand.com/l/abc123`. Both terminate TLS and serve the same redirect.

<Note>
  The platform default is `api.orbit.devotel.io`. Set a per-tenant branded domain if you want short, recognisable links your recipients trust.
</Note>

### Operator configuration

Self-hosting operators choose the platform default short-link host through environment variables. Per-tenant branded domains always take precedence over both.

| Variable                    | Default                        | Description                                                                                                                                         |
| --------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEVOTEL_SHORT_LINK_DOMAIN` | *(unset)*                      | Dedicated branded short-link host (e.g. `https://orbt.to`). When set, platform-default short links are minted on it instead of the API origin.      |
| `DEVOTEL_API_URL`           | `https://api.orbit.devotel.io` | Fallback short-link host used when `DEVOTEL_SHORT_LINK_DOMAIN` is unset. This is also the public API origin, so it is not exclusive to short links. |

<Warning>
  Provision DNS, TLS, and a `GET /l/:code` ingress rule for the host **before** setting `DEVOTEL_SHORT_LINK_DOMAIN`. Point it at a host that does not yet serve the redirect and newly minted links will fail to resolve.
</Warning>

## Example — shorten a URL

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/links/ \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/promo?utm_campaign=may26",
    "campaign_id": "cmp_may26"
  }'
```

The response includes the full short URL — embed it directly in outbound messages.

## Insights

`GET /api/v1/links/insights` returns tenant-wide URL-shortener analytics in a single call: summary KPIs, the top links ranked by clicks, and a per-day click timeline. All parameters are optional.

| Parameter     | Type           | Default | Description                                             |
| ------------- | -------------- | ------- | ------------------------------------------------------- |
| `window_days` | integer (1–90) | `7`     | Trailing window in days to aggregate clicks over.       |
| `top_limit`   | integer (1–50) | `10`    | Number of top links to return, ranked by clicks.        |
| `campaign_id` | string         | —       | Restrict insights to links attributed to this campaign. |

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/links/insights?window_days=30&top_limit=5" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

## Per-contact clicks

`GET /api/v1/links/contacts/{contactId}/clicks` resolves tracked short-link clicks back to a single recipient contact and returns the click history newest-first — useful for surfacing per-contact engagement in the CDP.

| Parameter   | Type            | Default | Description                                       |
| ----------- | --------------- | ------- | ------------------------------------------------- |
| `contactId` | string (path)   | —       | Identifier of the contact whose clicks to return. |
| `limit`     | integer (1–500) | `100`   | Maximum number of clicks to return.               |

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/links/contacts/con_abc123/clicks?limit=50" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

## Landing Pages

No-code landing pages (microsites) are built from a block list and served under the same `/links` base path. A published page mints a trackable short URL and rolls up per-page visits and conversions by campaign and by originating message.

| Method   | Path                                         | Purpose                                                         |
| -------- | -------------------------------------------- | --------------------------------------------------------------- |
| `POST`   | `/api/v1/links/landing-pages`                | Create a draft landing page                                     |
| `GET`    | `/api/v1/links/landing-pages`                | List landing pages (cursor-paginated; optional `status` filter) |
| `GET`    | `/api/v1/links/landing-pages/{id}`           | Fetch a single landing page                                     |
| `PATCH`  | `/api/v1/links/landing-pages/{id}`           | Update title, content, campaign, or archive                     |
| `POST`   | `/api/v1/links/landing-pages/{id}/publish`   | Publish and mint the trackable short URL                        |
| `GET`    | `/api/v1/links/landing-pages/{id}/analytics` | Per-page visits + conversions by campaign/message               |
| `DELETE` | `/api/v1/links/landing-pages/{id}`           | Delete a landing page (visit/conversion events cascade)         |

Create a draft, then publish it to mint the trackable short URL:

```bash theme={null}
# 1. Create a draft
curl -X POST https://api.orbit.devotel.io/api/v1/links/landing-pages \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Spring launch", "campaign_id": "cmp_may26" }'

# 2. Publish it — the response carries the trackable short_url
curl -X POST https://api.orbit.devotel.io/api/v1/links/landing-pages/lp_abc123/publish \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

The list endpoint accepts an optional `status` filter (`draft`, `published`, `archived`) alongside the standard `cursor` / `limit` pagination params. The analytics endpoint accepts `top_limit` (1–50, default 10) to bound the per-campaign and per-message breakdowns.

## See also

* [Goal Tracking](/api-reference/analytics) — pair clicks with conversions for attribution
