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
429with aRetry-Afterheader), 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 (400invalid input,401missing or bad key,403not allowed or plan limit,404not found,409that ending is taken). The text is English unless you sendAccept-Language: frorar. - 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.pngWhat 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.