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
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

/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.

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.

/api/urls
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.
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.

/api/urls
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
}
/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"
/api/urls/{code}

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

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
}
/api/urls/{code}

Permanently removes the link and its click records. This operation is irreversible; use is_active: false when you may need to restore the redirect later.

cURL
curl -X DELETE https://lixrl.com/api/urls/launch \
  -H "Authorization: Bearer elu_YOUR_KEY"
200 OK
{
  "success": true
}

Status codes and retries

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.

ElixpoURL — Fast, Secure URL Shortener with Analytics