Kokli logo — URL shortener
Kokli
kok.li
REST API · v1

Kokli URL shortener API

Use the Kokli REST API to create and edit short links and fetch click analytics from your own app, website, Telegram bot or CRM. Responses are JSON and authentication uses an API key.

Quick start

  1. 1
    Get a plan with API access

    API access is included in the plans marked “API access” on the pricing page.

  2. 2
    Create an API key

    Go to “API keys” in your dashboard and choose the key's name and permissions. The key is shown only once.

  3. 3
    Send your first request

    Send the key in the Authorization: Bearer header and create your first short link with POST /links.

Create a short link in the language of your choice — base URL: https://kok.li/api/v1

curl -X POST https://kok.li/api/v1/links \
  -H "Authorization: Bearer kk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"longUrl": "https://example.com/very/long/url"}'

Authentication

All requests (except the introduction and the OpenAPI file) require an API key. Send the key in the Authorization: Bearer kk_live_… or X-API-Key header. Keep the key on the server side only, and never put it in browser code or a mobile app.

  • You can set an expiry date and a list of allowed IPs (single IPs or CIDR ranges) for each key.
  • Revoked or expired keys are rejected immediately with a 401 error.
  • The site admin may disable a key's or an account's access in case of abuse.

Permissions (scopes)

When creating a key, you choose which areas it can access. Follow the principle of least privilege; for example, a reporting dashboard key only needs links:read and analytics:read.

ScopePurposeEndpoints
links:readRead linksGET /links, GET /links/{code}
links:writeCreate & edit linksPOST /links, POST /links/bulk, PATCH /links/{code}
links:deleteDelete linksDELETE /links/{code}
analytics:readView click analyticsGET /links/{code}/stats, GET /analytics
qr:readGet QR codesGET /links/{code}/qr
account:readAccount info & usageGET /me

API endpoints

All paths are relative to https://kok.li/api/v1. Responses are JSON and timestamps are ISO 8601 (UTC).

POST/api/v1/links/bulk

Bulk create links

Creates up to 50 links in one request. Each item takes the same fields as “Create a short link” and gets its own result; one failed item doesn't stop the others.

Required scope: links:write

JSON body
linksrequiredarrayArray of 1–50 objects with the create-link fields
Example request
{
  "links": [
    { "longUrl": "https://example.com/a" },
    { "longUrl": "https://example.com/b", "alias": "promo-b" }
  ]
}
Example response
{
  "created": 1,
  "failed": 1,
  "results": [
    { "index": 0, "ok": true, "link": { "code": "x7Kp2q", "shortUrl": "https://kok.li/x7Kp2q" } },
    { "index": 1, "ok": false, "status": 409, "code": "alias_taken", "error": "This alias is already taken." }
  ]
}
GET/api/v1/analytics

Account analytics

Same output as link analytics, but for all links in your account combined. Accepts range or from/to.

Required scope: analytics:read

GET/api/v1/links/{code}/qr

QR code image

Returns a PNG or SVG QR code for the short link (the response is an image, not JSON).

Required scope: qr:read

Query parameters
formatstringpng (default) or svg
sizeintegerImage width, 64–1024 px (default 320)
color / bgColorhexForeground and background colours, e.g. 000000 and ffffff
marginintegerMargin 0–10
eccstringError correction level: L, M, Q or H
GET/api/v1/me

Account, key & usage

Returns your account and plan, the current key's permissions and rate limit, and this month's usage.

Required scope: account:read

Example response
{
  "user": { "id": "66f1…", "name": "Alex" },
  "plan": { "tier": "pro", "label": "Pro" },
  "key": { "prefix": "kk_live_3fa9c1", "scopes": ["links:read", "links:write"], "rateLimitPerMinute": 60 },
  "limits": { "maxKeys": 10, "maxLinks": -1, "monthlyLinkLimit": 1000 },
  "usage": { "period": "2026-09", "monthlyLinksCreated": 42, "totalLinks": 318 }
}

Rate limits & quotas

  • Each key has a requests-per-minute limit (60 by default). The remaining allowance is returned in the RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers.
  • Once you exceed the limit you'll get a 429 response with the code rate_limited; wait a few seconds and try again.
  • Links created through the API count against your plan's overall limit and monthly quota.
  • Bulk creation accepts up to 50 links per request.

Errors

Error responses always include a human-readable message (in the Accept-Language language: Persian, English or Arabic) in error and a stable English code in code; base your application logic on code.

{ "error": "This API key doesn't have the “links:write” scope.", "code": "insufficient_scope", "requiredScope": "links:write" }
CodeHTTPMeaning
missing_api_key401No key was sent in the Authorization or X-API-Key header.
invalid_api_key401The key is invalid or has been revoked.
key_expired401The key has expired; create a new one.
key_disabled403The key has been temporarily disabled by the site admin.
ip_not_allowed403Your IP isn't in this key's allowlist.
api_access_denied403Your plan or account doesn't have API access (the reason field explains why).
insufficient_scope403The key lacks the permission this endpoint needs (see requiredScope).
validation_error400The request body is invalid (the field property names the problem field).
not_found404Link or endpoint not found.
alias_taken409The custom alias is already taken.
url_rejected422The destination URL was rejected for security reasons.
limit_reached403You've reached your plan's total link limit.
quota_exceeded429Your plan's monthly link quota is used up.
rate_limited429Requests per minute exceeded the key's limit.

API FAQ

Short answers to common developer questions.

Is the Kokli API free?

API access is included in the plans marked “API access” on the pricing page. Links created through the API count towards your plan's quota.

Where do I create an API key, and what if it leaks?

Create keys in the “API keys” section of your dashboard. A key is shown only once and we store only its hash. If a key leaks, revoke it there and create a new one; revocation takes effect immediately.

What's the API rate limit?

Each key allows 60 requests per minute by default. Your key's exact limit is in the GET /me response and in the RateLimit-Limit and RateLimit-Remaining headers of every response. If you get rate_limited, wait a moment and retry.

How do I restrict what a key can do?

When creating or editing a key, select only the permissions it needs (e.g. just links:read for reporting). You can also restrict the key to your servers' IPs and set an expiry date.

Do you have an OpenAPI (Swagger) spec?

Yes. The OpenAPI 3 file is available at https://kok.li/api/v1/openapi.json and can be imported into Postman, Insomnia or Swagger UI.

Ready to go?

Create your first API key and shorten a link in under a minute.

Go to API keys