API

Create and manage short links from your own code

The same service the dashboard uses, over HTTPS and JSON. Every plan can use it, the free plan included. Make a key in Settings → API keys (owners and admins), then send it as a bearer token.

Basics

  • Base address: https://intlink.space/api/v1
  • Authentication: Authorization: Bearer il_…. A key works on one workspace and acts as the person who made it, as long as they stay in the workspace. It can use links, campaigns and QR codes; it can never touch billing, the team, the workspace itself or other keys.
  • Limits: 120 requests per minute per key (then 429 with a Retry-After header), up to 10 keys per workspace. The limits of your plan (links, monthly clicks) apply as in the dashboard.
  • Errors: a JSON body { "error": "…" } with the status code (400 invalid input, 401 missing or bad key, 403 not allowed or plan limit, 404 not found, 409 that ending is taken). The text is English unless you send Accept-Language: fr or ar.
  • Keep the key secret. It is shown once, when you make it, and only a hash is stored. Revoke it in Settings and it stops working at once.
curl https://intlink.space/api/v1/links \
  -H "Authorization: Bearer il_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destinationUrl": "https://example.com/spring-offer", "key": "spring"}'

Links

POST/links

Creates a short link and answers 201 with the link. The short address is https://{domain}/{key} (the domain is intlink.xyz).

{
  "destinationUrl": "https://example.com/spring-offer",   // required for a REDIRECT link
  "key": "spring",                // optional: 2–100 letters, digits, - or _ (generated if left out)
  "title": "Spring offer",        // optional, up to 255 characters
  "tags": ["promo", "email"],     // optional, up to 20
  "campaignId": "…uuid…",         // optional: a campaign of this workspace
  "utmSource": "newsletter",      // optional: also utmMedium, utmCampaign, utmTerm, utmContent
  "expiresAt": "2026-12-31T23:59:59Z",    // optional (ISO 8601) …
  "expiredUrl": "https://example.com/offers",   // … and where to send visitors afterwards
  "password": "secret-pass"       // optional, 4–100 characters
}

A bridge link, where the visitor picks the destination, takes "type": "BRIDGE" and bridgeOptions (2 to 10 objects with label and destinationUrl) instead of destinationUrl.

{
  "id": "7b0c…",
  "domain": "intlink.xyz",
  "key": "spring",
  "type": "REDIRECT",
  "destinationUrl": "https://example.com/spring-offer",
  "title": "Spring offer",
  "tags": ["promo", "email"],
  "isActive": true,
  "totalClicks": 0,
  "uniqueClicks": 0,
  "createdAt": "2026-11-12T10:00:00.000Z",
  …
}

GET/links

Lists the workspace's links, newest first, 20 to a page. Optional query: q (searches the destination, title and ending), status (active or inactive), tag, page.

{ "links": [ … ], "total": 132, "page": 1, "pageSize": 20, "totalPages": 7 }

PATCH/links/{id}

Changes a link. Send only what changes: the fields of the creation body, plus isActive (switch a link off and on) and removePassword. Changing key changes the short address, so codes already printed with the old one stop working.

curl -X PATCH https://intlink.space/api/v1/links/7b0c… \
  -H "Authorization: Bearer il_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"destinationUrl": "https://example.com/summer-offer"}'

DELETE/links/{id}

Deletes a link and its statistics. Answers { "ok": true }. This cannot be undone, and the short address stops working.

Smart routing

PUT/links/{id}/rules

Replaces the link's routing rules with the list you send (up to 10); an empty list clears them. Rules are checked from top to bottom and the first match wins. Visitors no rule matches go to the link's destination. A random split is used only when no rule matches, and what share is left goes to the destination. Bridge links take no rules.

{
  "rules": [
    { "type": "GEO",      "countries": ["DZ", "TN"], "targetUrl": "https://example.com/maghreb" },
    { "type": "OS",       "os": "ios",               "targetUrl": "https://apps.apple.com/app/id…" },
    { "type": "DEVICE",   "device": "mobile",        "targetUrl": "https://example.com/m" },
    { "type": "LANGUAGE", "language": "ar",          "targetUrl": "https://example.com/ar" },
    { "type": "AB_TEST",  "weight": 30,              "targetUrl": "https://example.com/variant-b" }
  ]
}

os is one of ios, android, windows, mac, linux; device one of mobile, tablet, desktop; language the first part of the browser's language (fr matches fr-DZ); weight is a share from 1 to 99, and the shares add up to at most 100. Country codes are ISO 3166-1 alpha-2. Destinations must start with http:// or https://. The answer is { "rules": [ … ] } as stored.

GET/links/{id}/rules

The rules as saved, in the same shape.

QR codes

GET/links/{id}/qr

The link's QR code as an image. Query: format (svg, the default, or png), size in pixels, fg and bg colours as hex (1a2b3c), margin, ecc (L, M, Q, H) and download=1 to ask for a file download. What you leave out comes from the style saved on the link, then from the defaults. Colour pairs a phone could not read are refused with 400. Scans of the code are counted apart from clicks.

curl "https://intlink.space/api/v1/links/7b0c…/qr?format=png&size=1024" \
  -H "Authorization: Bearer il_YOUR_KEY" -o spring.png

What is not here yet

Reading statistics through the API, webhooks, and read-only keys are not built; every key has the access described above. Other dashboard endpoints (campaigns, bulk actions, duplicating a link) also accept a key but are not part of this reference and may change.

Questions or something missing? The API follows the dashboard: if you can do it there, say so and it is a candidate for a documented endpoint. See the plans, or create a free account to make your first key.