DocumentationShortening API

DocsBuild04

Shortening API

Create and manage account-owned short links, or use the browser-only guest flow for one temporary link. This reference documents request fields, response bodies, tier restrictions, pagination, expiry, and failure behavior as implemented by the edge routes.

Base URL
https://lixrl.com
Content type
application/json
Authentication
Bearer API key

Authentication

Account endpoints accept a scoped API key in the standard Bearer header. Create a key under Profile → API Keys. Never place API keys in URLs or browser-delivered JavaScript.

Request header
Authorization: Bearer elu_YOUR_API_KEY

Guest requests

The guest endpoint does not accept an API key. It is protected by a same-origin browser check, risk scoring, and a 24-hour D1 quota, so it is not a replacement for the authenticated integration API.

Guest shortening

POST/api/guest/urls

Creates one temporary short link from the public landing page. The service fixes the expiry at 24 hours, generates the code, stores no click analytics, and returns 429 while the derived guest identity is still inside its quota window.

Guest shortening request fields
FieldTypeRequiredDescription
urlstringYesAbsolute HTTP or HTTPS destination, maximum 2,048 characters. Private, loopback, unsafe, and denylisted hosts are rejected.
Same-origin browser request
fetch('/api/guest/urls', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://example.com/article' })
})
201 Created
{
  "short_url": "https://lixrl.com/gA1b2C3",
  "short_code": "gA1b2C3",
  "original_url": "https://example.com/article",
  "expires_at": "2026-08-02T10:30:00.000Z",
  "guest": true
}

Guest quota response

429 Too Many Requests
{
  "error": "Your guest link has already been used. Sign in for persistent links.",
  "account_required": true,
  "available_at": "2026-08-02T10:30:00.000Z"
}

The response includes Retry-After in seconds. Guest links cannot be listed, edited, recovered, or converted into account links after creation.

POST/api/urls

Create link request fields
FieldTypeRequiredDescription
urlstringYesAbsolute HTTP or HTTPS destination. The same private-network and safe-content checks used by guest shortening apply.
titlestringNoHuman-readable label between 1 and 255 characters.
custom_codestringNoPro or higher. A unique 3–32 character slug containing letters, digits, hyphens, or underscores.
expires_atISO 8601NoPro or higher. A future timestamp; null/omitted links do not expire.
campaignstringNoA campaign label between 1 and 64 characters.
tagsstring[]NoUp to 10 normalized tags, each no longer than 24 characters.
utmobjectNoOptional source, medium, campaign, term, and content values appended as UTM parameters.
cURL
curl -X POST https://lixrl.com/api/urls \
  -H "Authorization: Bearer elu_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/long-url",
    "title": "Launch announcement",
    "custom_code": "launch",
    "expires_at": "2026-12-31T23:59:59.000Z"
  }'
201 Created
{
  "short_url": "https://lixrl.com/launch",
  "short_code": "launch",
  "original_url": "https://example.com/long-url",
  "title": "Launch announcement",
  "created_at": "2026-08-01 10:30:00",
  "expires_at": "2026-12-31T23:59:59.000Z"
}

Free accounts can own up to 25 links. A duplicate custom code returns 409; unavailable tier features and exhausted account quotas return 403.

Bulk create account links

POST/api/urls/bulk-create

Submit up to 25 ordinary create-link payloads. Each item is validated, safety checked, quota checked, and returned with its own HTTP-style status. A fully successful batch returns 201; a partial batch returns 207 so callers can retry only failed rows.

Request body
{
  "links": [
    {"url":"https://example.com/a","campaign":"launch","tags":["email"]},
    {"url":"https://example.com/b","utm":{"source":"newsletter","medium":"email"}}
  ]
}

GET/api/urls

List links query parameters
FieldTypeRequiredDescription
limitintegerNoPage size from 1–100. Defaults to 50.
offsetintegerNoNumber of matching records to skip. Defaults to 0; maximum 100,000.
searchstringNoCase-insensitive match against short code, destination, or title. Input is capped at 100 characters.
cURL
curl 'https://lixrl.com/api/urls?limit=20&offset=0&search=example' \
  -H "Authorization: Bearer elu_YOUR_KEY"
200 OK
{
  "urls": [
    {
      "id": 42,
      "user_id": 7,
      "short_code": "launch",
      "original_url": "https://example.com/long-url",
      "title": "Launch announcement",
      "is_active": 1,
      "clicks": 18,
      "created_at": "2026-08-01 10:30:00",
      "updated_at": "2026-08-01 10:30:00",
      "expires_at": null
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}

GET/api/urls/{code}

Returns the complete URL record shown in the list response. Ownership is enforced: an unknown code or a code belonging to another account returns 404.

cURL
curl https://lixrl.com/api/urls/launch \
  -H "Authorization: Bearer elu_YOUR_KEY"

PATCH/api/urls/{code}

Send at least one mutable field. The short code itself cannot be changed.

Update link request fields
FieldTypeRequiredDescription
urlstringNoNew validated HTTP or HTTPS destination.
titlestring | nullNoNew 1–255 character title, or null to remove it.
is_activebooleanNoFalse disables redirects without deleting the record or analytics.
expires_atISO 8601 | nullNoFuture timestamp, or null to remove expiry.
cURL
curl -X PATCH https://lixrl.com/api/urls/launch \
  -H "Authorization: Bearer elu_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/new","title":null,"is_active":true}'
200 OK
{
  "success": true
}

DELETE/api/urls/{code}

Permanently removes the link and its click records. Use is_active: false when you may need to restore the redirect later.

Irreversible

Deleting a link also deletes its analytics. There is no undo.
cURL
curl -X DELETE https://lixrl.com/api/urls/launch \
  -H "Authorization: Bearer elu_YOUR_KEY"
200 OK
{
  "success": true
}

Status codes and retries

HTTP status codes returned by the shortening API
StatusMeaningAction
400Malformed input or unsupported field value.Correct the request before retrying.
401Missing, invalid, expired, or revoked credentials.Replace the API key.
403Tier restriction, quota, risk rejection, or CSRF failure.Read the error string; signing in or upgrading may be required.
404The account does not own a matching short code.Verify the code and credentials.
409Requested custom code is already taken.Choose another code or omit custom_code.
422Safe Browsing rejected the destination.Use a safe destination; do not retry unchanged.
429Rate or guest quota exceeded.Wait for Retry-After before retrying.
500/503Transient service or configuration failure.Retry with capped exponential backoff.

See the dedicated error reference for response conventions and retry guidance.

URL Shortener API — Create and Manage Short Links | Lixrl