Link Squeeze API
The Link Squeeze API is a REST API for creating and managing branded short links, adding custom domains, attaching retargeting pixels, reading click analytics, and subscribing to webhooks for link and pixel events.
It speaks JSON, uses standard HTTP verbs and status codes, and is authenticated with a bearer token you generate yourself.
Base URL
https://app.linksqueeze.io/api/v1Every path in this reference is relative to that base. All requests must be made over HTTPS.
An active plan is required to use the API. Requests from an account
without a live subscription, lifetime purchase, or running trial are refused
with 402 payment_required, even when the API key itself is valid.
Quick start
Generate an API key from Integrations → API in the dashboard, then create your first link:
curl -X POST https://app.linksqueeze.io/api/v1/links \
-H "Authorization: Bearer $LINKSQUEEZE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"destination_url": "https://example.com/summer-sale",
"slug": "summer"
}'{
"data": {
"id": "9b1f4e2a-6c3d-4a17-9f2e-7c8d5a1b3e40",
"title": "Summer Sale",
"destination_url": "https://example.com/summer-sale",
"short_url": "sqzly.link/summer",
"slug": "summer",
"hostname": "sqzly.link",
"og_title": "Summer Sale — 30% off everything",
"og_description": "Our biggest sale of the year, ending Sunday.",
"og_image": "https://cdn.example.com/preview.png",
"utm_params": {},
"tags": [],
"expires_at": null,
"pixel_ids": [],
"clicks": 0,
"status": "active",
"created_at": "2026-08-28T10:14:02.000000Z",
"updated_at": "2026-08-28T10:14:02.000000Z"
}
}The title and preview metadata were filled in by scraping the destination page - see preview metadata.
Reference
All endpoints
| Method | Path | Scope |
|---|---|---|
GET | /v1/me | any valid key |
GET | /v1/tokens | any valid key |
GET | /v1/links | links:read |
POST | /v1/links | links:write |
GET | /v1/links/{id} | links:read |
PATCH | /v1/links/{id} | links:write |
DELETE | /v1/links/{id} | links:write |
GET | /v1/clicks | links:read |
GET | /v1/links/{id}/clicks | links:read |
GET | /v1/links/{id}/stats | links:read |
GET | /v1/links/{id}/qrcode | links:read |
POST | /v1/links/{id}/qrcode | links:write |
GET | /v1/qrcodes/{id}/image/{format} | signed URL |
GET | /v1/domains | domains:read |
POST | /v1/domains | domains:write |
GET | /v1/domains/{id} | domains:read |
PATCH | /v1/domains/{id} | domains:write |
POST | /v1/domains/{id}/verify | domains:write |
DELETE | /v1/domains/{id} | domains:write |
GET | /v1/pixels | pixels:read |
POST | /v1/pixels | pixels:write |
GET | /v1/pixels/{id} | pixels:read |
PATCH | /v1/pixels/{id} | pixels:write |
DELETE | /v1/pixels/{id} | pixels:write |
GET | /v1/webhooks | webhooks:manage |
POST | /v1/webhooks | webhooks:manage |
DELETE | /v1/webhooks/{id} | webhooks:manage |
Every endpoint takes a bearer token except the QR image route, which is reached through a signed URL so that an <img> tag or an email client can load it without credentials.
Conventions
Identifiers
Every object is addressed by its UUID, which is returned as id. Internal numeric primary keys are never exposed, and paths such as /links/{id} always expect a UUID.
GET /api/v1/links/9b1f4e2a-6c3d-4a17-9f2e-7c8d5a1b3e40Requests
Send Content-Type: application/json on requests with a body, and Accept: application/json on every request so that errors come back as JSON rather than HTML.
Partial updates use PATCH. Only the fields you send are changed — with one exception on links, described in Updating a link.
Responses
A single object is wrapped in a data key:
{ "data": { "id": "...", "...": "..." } }Deletes return 204 No Content with an empty body.
Pagination
List endpoints return a standard paginated shape — a data array alongside links and meta objects:
{
"data": [{ "id": "..." }],
"links": {
"first": "https://app.linksqueeze.io/api/v1/links?page=1",
"last": "https://app.linksqueeze.io/api/v1/links?page=4",
"prev": null,
"next": "https://app.linksqueeze.io/api/v1/links?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 4,
"path": "https://app.linksqueeze.io/api/v1/links",
"per_page": 15,
"to": 15,
"total": 52
}
}Control the page with ?page= and the page size with ?per_page=. The default page size is 15 and the maximum is 100 — a larger value is silently capped rather than rejected.
Results are ordered newest first.
GET /v1/me and GET /v1/tokens are the endpoints that are not paginated
— the first returns a single object, the second every API key on the account
in one data array.
Timestamps
All timestamps are ISO 8601 in UTC, for example 2026-08-28T10:14:02.000000Z.
Errors
Every error uses the same envelope, with a machine-readable code and a human-readable message:
{
"error": {
"code": "validation_error",
"message": "The given data was invalid.",
"errors": {
"destination_url": ["The destination url field must be a valid URL."]
}
}
}See Errors & rate limits for the full list of codes.
Rate limits
Requests are limited to 60 per minute per API key. Two keys on the same account get independent budgets, and keys are never throttled by other customers sharing an IP address.