ADVANCED

Docs

Links over the API

The link is the core object in Kilo, and five endpoints cover its whole life over HTTP: create it, list your links, read one, update where it points, and retire it. Every example below uses a write-scoped key in $KILO_API_KEY; a read key is enough for the two GET calls.

Create a link

POST /api/links mints a link. For a plain URL link the only required field is default_target, an http(s) URL. You may also pass a custom slug (3–32 base62 characters), a human name (up to 80), a group_id, an expires_at epoch-milliseconds timestamp, and a placement of active (default) or archived.

POST /api/links
curl https://qr2r.com/api/links \
  -H "Authorization: Bearer $KILO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "default_target": "https://example.com/landing", "name": "Spring flyer" }'

A successful create returns 201 with the full link object. The slug is the permanent public handle; default_target is the editable destination behind it:

201 Created
{
  "id": 8231,
  "slug": "aA3k9",
  "name": "Spring flyer",
  "kind": "url",
  "data": null,
  "default_target": "https://example.com/landing",
  "expires_at": null,
  "disabled": false,
  "override_target": null,
  "expired_fallback_url": null,
  "group_id": null,
  "domain": null,
  "rule_count": 0,
  "created_at": 1719000000000,
  "updated_at": 1719000000000,
  "deleted_at": null,
  "reclaim_until": null,
  "paused_at": null,
  "pause_reason": null,
  "placement_country": null,
  "placement_region": null
}

The destination guard

A destination cannot point back to a Kilo-owned host or at another URL shortener - that blocks the redirect-chaining trick abusers use to launder a bad link through a trusted one. Those are rejected as 400 invalid_body. A destination that trips the live safety check is refused with 422 destination_unsafe, before any slug is spent.

List and read

GET /api/links returns your links a page at a time. Narrow it with status (active, archived, paused, or deleted - default active), group_id, and the limit/offset pair (limit defaults to 50, caps at 200). The response carries the page plus account-wide counters:

GET /api/links?status=active&limit=50
{
  "links": [ /* link objects, newest first */ ],
  "limit": 50,
  "offset": 0,
  "status": "active",
  "counts": { "active": 12, "archived": 3, "paused": 0, "deleted": 1 },
  "limits": { "active_links_max": 25, "archived_links_max": 100, "reclaim_window_days": 30 }
}

Read a single link by slug with GET /api/links/:slug; it returns the same object shape as create. An unknown slug returns 404 not_found. For a link on one of your custom domains, add ?domain=go.acme.com so the right link resolves.

Update where it points

PUT /api/links/:slug takes a partial body - send only the fields you’re changing. The common one is default_target; you can also change the name, move it to a group_id, set expires_at, or archive it with disabled. Editing the destination takes effect on the very next scan, everywhere at once - which is the whole point of routing a printed code through Kilo.

PUT /api/links/aA3k9
curl -X PUT https://qr2r.com/api/links/aA3k9 \
  -H "Authorization: Bearer $KILO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "default_target": "https://example.com/new-landing" }'

The call returns the updated link object, with a fresh updated_at.

Retire a link

DELETE /api/links/:slug soft-deletes a link: it stops forwarding and moves to the Deleted tab, but it is not gone.

DELETE /api/links/aA3k9
{ "ok": true, "soft": true }

You can bring it back with POST /api/links/:slug/reclaim while it’s inside the reclaim window, or remove it for good with POST /api/links/:slug/purge. Nothing is ever hard-deleted out from under you by a plain delete - the same never-a-dead-end principle the link lifecycle guide describes, expressed as endpoints.

That’s the full object over HTTP. The last API guide covers the two things you’ll most often automate around a link: reading its stats and steering its traffic.

Analytics and rules over the API
NextAnalytics and rules over the APIRead a link's stats and manage geo, device, and A/B routing rules over HTTP.Read the guide