REST API documentation
Pro plan only. $9.00 per month. Create a Bearer key at /dashboard/api-keys. Keep it secret and send it in the Authorization header. Verify your email before creating links.
Base URL: https://brandedshortlinks.com/api/v1. Requests and responses use JSON. Set API_KEY to your key in your shell, then run the examples in order. After creating a link, set LINK_ID to the id returned in its JSON response. Example answers illustrate the shape; ids, slugs and timestamps vary.
export API_BASE="https://brandedshortlinks.com/api/v1"
No phishing, malware, spam or illegal content. We check every destination and disable links that break these rules.
Limits and responses
60 requests per 1 minute per key. Responses include x-ratelimit-limit and x-ratelimit-remaining. The API rate-limit 429 includes Retry-After: 60. Creation also allows 20 links per minute per account, 60 per hour per IP and 1,000 per month on Pro.
Link status is lowercase: active, disabled, expired or deleted. createdAt and expiresAt are ISO timestamps; expiresAt is null for non-expiring links. Only your own links are accessible.
POST /api/v1/links
Create a link with required url and optional slug. Omit slug for a random back-half. Custom slugs are case-sensitive, 3 to 40 ASCII letters, digits, hyphens or underscores, starting and ending with a letter or digit.
curl --fail-with-body -X POST "$API_BASE/links" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
--data '{"url":"https://example.com/"}'Example response: HTTP 201
{
"id": "link-id",
"slug": "aB2cD3",
"shortUrl": "https://brandedshortlinks.com/aB2cD3",
"destination": "https://example.com/",
"status": "active",
"redirectType": 302,
"createdAt": "2026-10-15T12:00:00.000Z",
"expiresAt": null
}GET /api/v1/links
List up to 20 links. Pass ?cursor= with the previous nextCursor to read the next page. A null nextCursor means there are no more pages.
curl --fail-with-body -X GET "$API_BASE/links" \ -H "Authorization: Bearer $API_KEY"
Example response: HTTP 200
{
"links": [
{
"id": "link-id",
"slug": "aB2cD3",
"shortUrl": "https://brandedshortlinks.com/aB2cD3",
"destination": "https://example.com/",
"status": "active",
"redirectType": 302,
"createdAt": "2026-10-15T12:00:00.000Z",
"expiresAt": null
}
],
"nextCursor": null
}GET /api/v1/links/{id}
Read one of your links by its id.
curl --fail-with-body -X GET "$API_BASE/links/$LINK_ID" \ -H "Authorization: Bearer $API_KEY"
Example response: HTTP 200
{
"id": "link-id",
"slug": "aB2cD3",
"shortUrl": "https://brandedshortlinks.com/aB2cD3",
"destination": "https://example.com/",
"status": "active",
"redirectType": 302,
"createdAt": "2026-10-15T12:00:00.000Z",
"expiresAt": null
}PATCH /api/v1/links/{id}
Update url, status (active or disabled), or redirectType (301 or 302). Destination edits use the same checks as creation. The default redirect is 302. Browsers cache 301 redirects, so click counts can undercount.
curl --fail-with-body -X PATCH "$API_BASE/links/$LINK_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
--data '{"url":"https://example.com/updated","status":"disabled","redirectType":302}'Example response: HTTP 200
{
"id": "link-id",
"slug": "aB2cD3",
"shortUrl": "https://brandedshortlinks.com/aB2cD3",
"destination": "https://example.com/updated",
"status": "disabled",
"redirectType": 302,
"createdAt": "2026-10-15T12:00:00.000Z",
"expiresAt": null
}GET /api/v1/links/{id}/stats?days=1
Read daily human clicks, bot clicks and top country, referrer host, device and browser values. days defaults to 30 and is clamped to 1 through the plan retention window. This example requests one day.
curl --fail-with-body -X GET "$API_BASE/links/$LINK_ID/stats?days=1" \ -H "Authorization: Bearer $API_KEY"
Example response: HTTP 200
{
"days": [
{
"day": "2026-10-15",
"clicks": 0
}
],
"total": 0,
"botClicks": 0,
"countries": [],
"referrers": [],
"devices": [],
"browsers": []
}DELETE /api/v1/links/{id}
Soft-delete a link. The answer contains status deleted; subsequent reads return 404.
curl --fail-with-body -X DELETE "$API_BASE/links/$LINK_ID" \ -H "Authorization: Bearer $API_KEY"
Example response: HTTP 200
{
"id": "link-id",
"slug": "aB2cD3",
"shortUrl": "https://brandedshortlinks.com/aB2cD3",
"destination": "https://example.com/",
"status": "deleted",
"redirectType": 302,
"createdAt": "2026-10-15T12:00:00.000Z",
"expiresAt": null
}Errors
Errors return JSON with an error string, for example:
{
"error": "Invalid API key."
}HTTP 400
- Invalid JSON.
- Invalid link input.
- Invalid days.
- Enter a destination URL.
- Enter a valid destination URL.
- The destination URL must be at most 2,048 characters.
- The destination must use HTTP or HTTPS.
- The destination must not contain a username or password.
- The destination host must not be an IP address.
- The destination must use a public domain name.
- Internationalized destination hosts are not supported.
- Custom slugs must contain 3 to 40 characters.
- Custom slugs must use ASCII letters, digits, hyphens or underscores and start and end with a letter or digit.
HTTP 401
- Invalid API key.
HTTP 403
- The API is included with Pro ($9 a month).
- Your account is suspended.
- Verify your email first. We sent a link to your inbox.
- This link can only be re-enabled by an administrator.
HTTP 404
- Link not found.
- Not found.
HTTP 409
- This slug is already taken.
- This slug is reserved.
HTTP 422
- This destination failed our safety check. If you think this is wrong, email [email protected].
- Links to our own domain are not allowed. If you think this is wrong, email [email protected].
- Links to other URL shorteners are not allowed. If you think this is wrong, email [email protected].
HTTP 429
- Too many API requests. Try again in a minute.
- Too many links too fast. Try again in a minute.
- Pro accounts can create 1000 links per month.
A locally blocked destination returns 422 with the stored block reason followed by: If you think this is wrong, email [email protected].