# ZoLinks Developer API
Programmatic access to ZoLinks short URLs, gated links, QR codes, and webhooks.
- Site: https://zolinks.in
- Docs (interactive): https://zolinks.in/docs
- Developer Portal (Business Plan): https://zolinks.in/developers
## Authentication
All endpoints require a Bearer token in the `Authorization` header (or `X-API-Key` header). API keys are available to Business plan subscribers and can be generated at https://zolinks.in/developers. Keys are prefixed `zk_live_` and are scoped to the issuing account.
```
Authorization: Bearer zk_live_your_api_key_here
```
## Base URL
All endpoints are served from `https://zolinks.in/developers/api/v1`.
## Credits & rate limits
Every successful call costs 1 credit. Buy credits from the dashboard; usage is reported via `GET /credits`. Rate limits are per-key and surface as HTTP 429.
## Error codes
Errors return JSON `{ "error": string, "code": string }`. Common HTTP statuses: 400 (validation), 401 (missing/invalid key), 402 (no credits), 403 (forbidden), 404 (not found), 409 (conflict), 429 (rate limit), 500 (server).
## Endpoints
### GET /credits
Get your current credit balance and lifetime usage. Costs 1 credit per call.
**Response example**
```json
{
"balance": 974,
"total_used": 26,
"total_purchased": 1000,
"updated_at": "2026-04-29T..."
}
```
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/credits \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/credits", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/credits", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
## Short URLs
### POST /shorturls
Create a short URL. Returns the resolved public URL at https://zolinks.in/s/d/<slug>. Costs 1 credit.
**Request body**
- `target_url` (string, required) — Destination URL (http or https)
- `slug` (string) — Optional custom slug (4–32 alnum/-/_). Auto-generated if omitted.
- `title` (string) — Internal label
- `expires_at` (ISO 8601) — Optional expiry timestamp
- `password` (string) — Optional password — stored as a salted hash
```json
{
"target_url": "https://example.com/some/long/path",
"title": "Summer sale"
}
```
**Response example**
```json
{
"id": "uuid",
"slug": "Ab12Cd3",
"short_url": "https://zolinks.in/s/d/Ab12Cd3",
"target_url": "https://example.com/some/long/path",
"is_active": true,
"click_count": 0,
"created_at": "2026-06-12T..."
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/shorturls \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"target_url":"https://example.com/some/long/path"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ target_url: "https://example.com/some/long/path" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/shorturls", {
target_url: "https://example.com/some/long/path"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /shorturls/bulk
Create up to 50 short URLs in a single request. Perfect for SMS blasts, WhatsApp campaigns, and automated invoice dispatches. Deducts 1 credit per URL created.
**Request body**
- `urls` (array, required) — Array of up to 50 short URL objects
```json
{
"urls": [
{
"target_url": "https://example.com/item/1",
"title": "Item 1",
"utm_params": { "utm_source": "sms", "utm_campaign": "flash_sale" },
"tags": ["sms", "sale"]
},
{
"target_url": "https://example.com/item/2",
"slug": "flash-deal-2",
"geo_targets": { "IN": "https://in.example.com", "US": "https://us.example.com" }
}
]
}
```
**Response example**
```json
{
"created_count": 2,
"shorturls": [
{
"id": "uuid-1",
"slug": "abc1234",
"target_url": "https://example.com/item/1",
"short_url": "https://zolinks.in/s/d/abc1234",
"click_count": 0
},
{
"id": "uuid-2",
"slug": "flash-deal-2",
"target_url": "https://example.com/item/2",
"short_url": "https://zolinks.in/s/d/flash-deal-2",
"click_count": 0
}
]
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/shorturls/bulk \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"urls":[{"target_url":"https://example.com/1"},{"target_url":"https://example.com/2"}]}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/bulk", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
urls: [
{ target_url: "https://example.com/1", title: "Link 1" },
{ target_url: "https://example.com/2", slug: "custom2" }
]
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/shorturls/bulk", {
urls: [
{ target_url: "https://example.com/1" },
{ target_url: "https://example.com/2" }
]
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /shorturls
List short URLs owned by the calling API key, paginated.
**Query parameters**
- `page` (integer) — 1-based page number. Default 1.
- `per_page` (integer) — Clamped to [1, 100]. Default 20.
**Response example**
```json
{
"shorturls": [
{ "id": "uuid", "slug": "Ab12Cd3", "short_url": "https://zolinks.in/s/d/Ab12Cd3", "target_url": "https://...", "click_count": 42, "is_active": true, "created_at": "2026-06-12T..." }
],
"total": 1,
"page": 1,
"per_page": 20
}
```
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/shorturls?page=1&per_page=20" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls?page=1&per_page=20", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/shorturls", {
params: { page: 1, per_page: 20 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /shorturls/:id
Fetch one short URL by id.
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### PUT /shorturls/:id
Update title, expiry, active status, or password.
```json
{
"title": "Updated",
"is_active": false,
"expires_at": "2026-12-31T23:59:59Z"
}
```
**cURL**
```bash
curl -X PUT https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"is_active":false}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
method: "PUT",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ is_active: false })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.put("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
is_active: false
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### DELETE /shorturls/:id
Delete a short URL. Returns { "success": true }.
**cURL**
```bash
curl -X DELETE https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
method: "DELETE",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.delete("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /shorturls/:id/analytics
Daily click time-series, top referrers, and top countries for a short URL.
**Query parameters**
- `days` (integer) — Window in days, 1–90. Default 30.
**Response example**
```json
{
"id": "uuid",
"total_clicks": 142,
"time_series": [ { "date": "2026-06-01", "clicks": 5 } ],
"top_referrers": [ { "source": "twitter.com", "count": 30 } ],
"top_countries": [ { "country": "IN", "count": 88 } ]
}
```
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics?days=30" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics?days=30", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics", {
params: { days: 30 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /shorturls/:id/analytics/export?days=30&format=csv
Export detailed visitor click logs for a specific short link in CSV or JSON format.
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics/export?days=30&format=csv" \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-o link-analytics.csv
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics/export?days=30&format=csv", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const csvText = await res.text();
```
**Node.js (axios)**
```js
const axios = require("axios");
const fs = require("fs");
const res = await axios.get("https://zolinks.in/developers/api/v1/shorturls/SHORTURL_UUID/analytics/export?days=30&format=csv", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
fs.writeFileSync("link-analytics.csv", res.data);
```
## Gated Links
### POST /gated-links
Create a gated link. Public URL is https://zolinks.in/g/d/<slug>. mode 'email' is available on all plans; mode 'payment' requires the Business plan and a configured payment gateway.
**Request body**
- `title` (string, required) — Display title
- `slug` (string) — Optional custom slug
- `destination_url` (string, required) — URL revealed after unlock
- `mode` ('email' | 'payment') — Unlock method. Default 'email'.
- `price_inr` (number) — Price in paise (mode=payment)
- `price_usd` (number) — Price in cents (mode=payment)
- `max_unlocks` (integer) — Optional cap on total unlocks
- `expires_at` (ISO 8601) — Optional expiry
```json
{
"title": "Free eBook",
"destination_url": "https://example.com/ebook.pdf",
"mode": "email"
}
```
**Response example**
```json
{
"id": "uuid",
"slug": "free-ebook",
"public_url": "https://zolinks.in/g/d/free-ebook",
"mode": "email",
"is_active": true,
"view_count": 0,
"unlock_count": 0
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/gated-links \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Free eBook","destination_url":"https://example.com/ebook.pdf","mode":"email"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "Free eBook",
destination_url: "https://example.com/ebook.pdf",
mode: "email"
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/gated-links", {
title: "Free eBook",
destination_url: "https://example.com/ebook.pdf",
mode: "email"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /gated-links
List gated links owned by the calling API key, paginated.
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/gated-links?page=1&per_page=20" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links?page=1&per_page=20", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/gated-links", {
params: { page: 1, per_page: 20 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /gated-links/:id
Fetch one gated link by id, including counters.
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/gated-links/GATED_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### PUT /gated-links/:id
Update title, destination, pricing, caps, or active status.
```json
{
"title": "Updated",
"is_active": true
}
```
**cURL**
```bash
curl -X PUT https://zolinks.in/developers/api/v1/gated-links/GATED_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Updated"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
method: "PUT",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ title: "Updated" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.put("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
title: "Updated"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### DELETE /gated-links/:id
Delete a gated link and its unlocks. Returns { "success": true }.
**cURL**
```bash
curl -X DELETE https://zolinks.in/developers/api/v1/gated-links/GATED_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
method: "DELETE",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.delete("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /gated-links/:id/unlocks
List unlock records (email captures and successful payments) for a gated link.
**Query parameters**
- `page` (integer) — 1-based page. Default 1.
- `per_page` (integer) — Clamped [1, 100]. Default 50.
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/unlocks?page=1" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/unlocks?page=1", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/unlocks", {
params: { page: 1 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /gated-links/:id/analytics
Daily views/unlocks time-series for a gated link.
**Query parameters**
- `days` (integer) — Window 1–90. Default 30.
**Response example**
```json
{
"id": "uuid",
"view_count": 1280,
"unlock_count": 96,
"time_series": [ { "date": "2026-06-01", "views": 42, "unlocks": 3 } ]
}
```
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/analytics?days=30" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/analytics?days=30", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/gated-links/GATED_UUID/analytics", {
params: { days: 30 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
## QR Codes
### POST /qr
Generate a QR image on the fly without persisting anything. Responds directly with the binary/text image. Costs 1 credit per call.
**Request body**
- `data` (string, required) — Payload to encode (URL or text)
- `format` ('svg' | 'png') — Default 'svg'
- `size` (integer) — Pixels per side, 64–2048. Default 512.
- `fg` (string) — Foreground hex (e.g. '#000000')
- `bg` (string) — Background hex
```json
{
"data": "https://zolinks.in",
"format": "svg",
"size": 512
}
```
**Response example**
```json
<svg xmlns="http://www.w3.org/2000/svg" ...>...</svg>
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/qr \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"data":"https://zolinks.in","format":"svg"}' \
-o qr.svg
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ data: "https://zolinks.in", format: "svg" })
});
const svg = await res.text();
```
**Node.js (axios)**
```js
const axios = require("axios");
const fs = require("fs");
const res = await axios.post("https://zolinks.in/developers/api/v1/qr", {
data: "https://zolinks.in", format: "png", size: 512
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" },
responseType: "arraybuffer"
});
fs.writeFileSync("qr.png", res.data);
```
### POST /qr/bulk
Generate up to 20 QR codes simultaneously in a single API call.
```json
{
"items": [
{ "data": "https://zolinks.in/table1", "fg": "#000000", "format": "png" },
{ "data": "https://zolinks.in/table2", "fg": "#dc2626", "format": "svg" }
]
}
```
**Response example**
```json
{
"total": 2,
"qr_codes": [
{
"index": 0,
"data": "https://zolinks.in/table1",
"format": "png",
"size": 512,
"qr_image_url": "https://api.qrserver.com/..."
},
{
"index": 1,
"data": "https://zolinks.in/table2",
"format": "svg",
"size": 512,
"qr_image_url": "https://api.qrserver.com/..."
}
]
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/qr/bulk \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"items":[{"data":"https://zolinks.in/1"},{"data":"https://zolinks.in/2"}]}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/bulk", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
items: [{ data: "https://zolinks.in/1" }, { data: "https://zolinks.in/2" }]
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/qr/bulk", {
items: [{ data: "https://zolinks.in/1" }, { data: "https://zolinks.in/2" }]
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /qr/codes
Save a QR template so it can be rendered repeatedly without re-specifying styling.
```json
{
"name": "Homepage QR",
"data": "https://zolinks.in",
"fg": "#000000",
"bg": "#ffffff"
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/qr/codes \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Homepage QR","data":"https://zolinks.in"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/codes", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ name: "Homepage QR", data: "https://zolinks.in" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/qr/codes", {
name: "Homepage QR", data: "https://zolinks.in"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /qr/codes
List saved QR templates.
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/qr/codes \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/codes", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/qr/codes", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /qr/codes/:id
Fetch a saved QR template by id. Add /render to fetch a rendered image instead.
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/qr/codes/QR_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### PUT /qr/codes/:id
Update a saved QR template's name, data, or styling.
```json
{
"name": "Updated QR",
"fg": "#111827"
}
```
**cURL**
```bash
curl -X PUT https://zolinks.in/developers/api/v1/qr/codes/QR_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Updated QR"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
method: "PUT",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ name: "Updated QR" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.put("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
name: "Updated QR"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### DELETE /qr/codes/:id
Delete a saved QR template. Returns { "success": true }.
**cURL**
```bash
curl -X DELETE https://zolinks.in/developers/api/v1/qr/codes/QR_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
method: "DELETE",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.delete("https://zolinks.in/developers/api/v1/qr/codes/QR_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
## Headless Bio & Store
### GET /bio-pages
Fetch your public bio profile, active theme styling, link blocks, and social profiles.
**Response example**
```json
{
"profile": {
"id": "uuid",
"username": "myname",
"display_name": "My Name",
"bio": "Creator & Builder",
"theme": "gradient",
"public_url": "https://zolinks.in/myname"
},
"links": [
{ "id": "uuid", "title": "My Latest Video", "url": "https://youtube.com/...", "is_active": true }
],
"social_links": [
{ "platform": "instagram", "url": "https://instagram.com/myname" }
]
}
```
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/bio-pages" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/bio-pages", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/bio-pages", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /bio-pages/links
Programmatically add a new link button to your public ZoLinks bio page.
```json
{
"title": "Exclusive Drops",
"url": "https://mywebsite.com/drops",
"icon": "sparkles",
"is_active": true
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/bio-pages/links \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Exclusive Drops","url":"https://mywebsite.com/drops"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/bio-pages/links", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ title: "Exclusive Drops", url: "https://mywebsite.com/drops" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/bio-pages/links", {
title: "Exclusive Drops", url: "https://mywebsite.com/drops"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /products
List all digital and physical products listed in your ZoLinks Mini Store.
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/products" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/products", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/products", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /products
Programmatically list a new product in your ZoLinks Mini Store.
```json
{
"title": "Lightroom Presets Pack 2026",
"description": "10 custom cinematic presets",
"product_type": "digital",
"price_inr": 299,
"external_download_url": "https://drive.google.com/file/..."
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/products \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Presets Pack","price_inr":299,"product_type":"digital"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/products", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ title: "Presets Pack", price_inr: 299, product_type: "digital" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/products", {
title: "Presets Pack", price_inr: 299, product_type: "digital"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
## Analytics
### GET /analytics?days=30
Retrieve comprehensive real-time analytics across all your links, including devices, browsers, operating systems, countries, referrers, hourly breakdown, and top links.
**Request body**
- `days` (number) — Number of past days to analyze (1-90, default: 30)
**Response example**
```json
{
"summary": {
"total_links": 42,
"active_links": 38,
"total_lifetime_clicks": 15420,
"period_clicks": 3840,
"days_analyzed": 30,
"top_country": "IN",
"top_referrer": "Instagram",
"top_device": "Mobile"
},
"daily": [
{ "date": "2026-08-01", "clicks": 142 },
{ "date": "2026-08-02", "clicks": 198 }
],
"devices": [
{ "name": "Mobile", "count": 2880, "percentage": 75 },
{ "name": "Desktop", "count": 840, "percentage": 22 },
{ "name": "Tablet", "count": 120, "percentage": 3 }
],
"browsers": [
{ "name": "Chrome", "count": 2100, "percentage": 55 },
{ "name": "Safari", "count": 1150, "percentage": 30 },
{ "name": "Edge", "count": 380, "percentage": 10 }
],
"os": [
{ "name": "Android", "count": 1920, "percentage": 50 },
{ "name": "iOS", "count": 1150, "percentage": 30 },
{ "name": "Windows", "count": 620, "percentage": 16 }
],
"countries": [
{ "country": "IN", "count": 3200 },
{ "country": "US", "count": 420 }
],
"referrers": [
{ "referrer": "Instagram", "count": 1800 },
{ "referrer": "WhatsApp", "count": 920 },
{ "referrer": "Direct", "count": 450 }
],
"hourly_distribution": [
{ "hour": 0, "count": 45 },
{ "hour": 14, "count": 320 }
],
"top_links": [
{
"id": "slk_123",
"slug": "shoe-deal",
"title": "50% Off Shoes",
"target_url": "https://...",
"short_url": "https://zolinks.in/s/d/shoe-deal",
"clicks": 1840,
"is_active": true
}
]
}
```
**cURL**
```bash
curl -X GET "${BASE_PLACEHOLDER}/analytics?days=30" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("${BASE_PLACEHOLDER}/analytics?days=30", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const analytics = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data: analytics } = await axios.get("${BASE_PLACEHOLDER}/analytics?days=30", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /analytics/export?days=30&format=csv
Export all link click logs across your entire account in standard RFC 4180 CSV or JSON format.
**Query parameters**
- `days` (number) — Past days to export (1-90, default: 30)
- `format` ('csv' | 'json') — Export format (default: 'csv')
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/analytics/export?days=30&format=csv" \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-o analytics.csv
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/analytics/export?days=30&format=csv", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const csvText = await res.text();
```
**Node.js (axios)**
```js
const axios = require("axios");
const fs = require("fs");
const res = await axios.get("https://zolinks.in/developers/api/v1/analytics/export?days=30&format=csv", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" },
responseType: "text"
});
fs.writeFileSync("analytics.csv", res.data);
```
### GET /shorturls/:id/analytics?days=30
Get detailed click analytics for a specific short URL, including device, browser, OS, hourly, country, and referrer breakdowns with recent click logs.
**Request body**
- `id` (string, required) — Short URL UUID
- `days` (number) — Past days (1-90, default 30)
**Response example**
```json
{
"id": "uuid",
"slug": "shoe-deal",
"title": "50% Off Shoes",
"target_url": "https://...",
"short_url": "https://zolinks.in/s/d/shoe-deal",
"total_lifetime_clicks": 1840,
"period_clicks": 620,
"days_analyzed": 30,
"daily": [{ "date": "2026-08-20", "clicks": 45 }],
"devices": [{ "name": "Mobile", "count": 480, "percentage": 77 }],
"browsers": [{ "name": "Chrome", "count": 340, "percentage": 55 }],
"os": [{ "name": "Android", "count": 320, "percentage": 52 }],
"countries": [{ "country": "IN", "count": 520 }],
"referrers": [{ "referrer": "Instagram", "count": 310 }],
"recent_clicks": [
{
"clicked_at": "2026-08-23T10:15:30Z",
"referrer": "Instagram",
"country": "IN",
"device": "Mobile",
"browser": "Chrome",
"os": "Android"
}
]
}
```
**cURL**
```bash
curl -X GET "${BASE_PLACEHOLDER}/shorturls/YOUR_SHORT_URL_ID/analytics?days=30" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("${BASE_PLACEHOLDER}/shorturls/YOUR_SHORT_URL_ID/analytics?days=30", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("${BASE_PLACEHOLDER}/shorturls/YOUR_SHORT_URL_ID/analytics?days=30", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
## Webhooks
### POST /webhooks
Register a new webhook endpoint.
**Request body**
- `url` (string, required) — Your webhook endpoint URL
- `events` (string[], required) — Array of event types, e.g. ["shorturl.clicked"]
```json
{
"url": "https://your-app.com/webhooks/zolinks",
"events": ["shorturl.clicked"]
}
```
**Response example**
```json
{
"id": "uuid",
"url": "https://your-app.com/webhooks/zolinks",
"events": ["shorturl.clicked"],
"secret": "whsec_...",
"message": "Store the secret securely..."
}
```
**cURL**
```bash
curl -X POST ${BASE_PLACEHOLDER}/webhooks \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-app.com/webhook","events":["shorturl.clicked"]}'
```
**JavaScript (fetch)**
```js
const res = await fetch("${BASE_PLACEHOLDER}/webhooks", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
url: "https://your-app.com/webhook",
events: ["shorturl.clicked"]
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("${BASE_PLACEHOLDER}/webhooks", {
url: "https://your-app.com/webhook",
events: ["shorturl.clicked"]
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /webhooks
List all your registered webhooks.
**Response example**
```json
[
{
"id": "uuid",
"url": "https://your-app.com/webhook",
"events": ["shorturl.clicked"],
"is_active": true,
"created_at": "2026-04-02T..."
}
]
```
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/webhooks \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/webhooks", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /webhooks/:id
Fetch a single webhook by ID.
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### PUT /webhooks/:id
Update a webhook's URL, events, or active status.
```json
{
"url": "https://new-url.com/webhooks",
"is_active": false
}
```
**cURL**
```bash
curl -X PUT https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"url":"https://new-url.com/webhooks","is_active":false}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
method: "PUT",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
url: "https://new-url.com/webhooks",
is_active: false
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.put("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
url: "https://new-url.com/webhooks",
is_active: false
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### DELETE /webhooks/:id
Delete a webhook. Returns { "success": true }.
**Response example**
```json
{ "success": true }
```
**cURL**
```bash
curl -X DELETE https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
method: "DELETE",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.delete("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /webhooks/:id/test
Enqueue a synthetic webhook.test delivery so you can verify your endpoint signature/handler.
**Response example**
```json
{
"success": true,
"message": "Test delivery enqueued.",
"payload": { "test": true, "message": "...", "timestamp": "..." }
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/test \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/test", {
method: "POST",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post(
"https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/test",
null,
{ headers: { Authorization: "Bearer zk_live_your_api_key_here" } }
);
```
### GET /webhooks/:id/deliveries
List recent delivery attempts, HTTP response codes, and retry statuses for a webhook endpoint.
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries", {
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.get("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /webhooks/:id/deliveries/:delivery_id/retry
Manually re-enqueue and retry a failed or dead webhook delivery.
**cURL**
```bash
curl -X POST "https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries/DELIVERY_UUID/retry" \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries/DELIVERY_UUID/retry", {
method: "POST",
headers: { "Authorization": "Bearer zk_live_your_api_key_here" }
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/webhooks/WEBHOOK_UUID/deliveries/DELIVERY_UUID/retry", {}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```