# ZoLinks Developer API
Programmatic access to ZoLinks smartlinks, short URLs, gated links, QR codes, and webhooks.
- Site: https://zolinks.in
- Docs (interactive): https://zolinks.in/docs
- Get an API key: https://zolinks.in/dashboard/api-keys
## Authentication
All endpoints require a Bearer token in the `Authorization` header. Issue keys at https://zolinks.in/dashboard/api-keys. 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" }
});
```
## Smartlinks
### POST /smartlinks
Create a new smartlink with platform-specific URLs.
**Request body**
- `title` (string, required) — Title of the smartlink
- `slug` (string, required) — URL-friendly slug (unique)
- `artwork_url` (string) — Artwork/cover image URL
- `platforms` (array) — Array of { platform, url } objects
```json
{
"title": "My New Song",
"slug": "my-new-song",
"artwork_url": "https://example.com/cover.jpg",
"platforms": [
{ "platform": "spotify", "url": "https://open.spotify.com/track/..." },
{ "platform": "apple_music", "url": "https://music.apple.com/..." }
]
}
```
**Response example**
```json
{
"id": "uuid",
"developer_id": "uuid",
"title": "My New Song",
"slug": "my-new-song",
"artwork_url": "https://example.com/cover.jpg",
"is_active": true,
"click_count": 0,
"created_at": "2026-04-12T...",
"platforms": [
{ "id": "uuid", "smartlink_id": "uuid", "platform": "spotify", "url": "https://...", "position": 0, "click_count": 0 }
]
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/smartlinks \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"My New Song","slug":"my-new-song","platforms":[{"platform":"spotify","url":"https://open.spotify.com/track/..."}]}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/smartlinks", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "My New Song",
slug: "my-new-song",
platforms: [{ platform: "spotify", url: "https://open.spotify.com/track/..." }]
})
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post("https://zolinks.in/developers/api/v1/smartlinks", {
title: "My New Song",
slug: "my-new-song",
platforms: [{ platform: "spotify", url: "https://open.spotify.com/track/..." }]
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /smartlinks
List all smartlinks owned by the calling API key, sorted by created_at descending. Pagination is offset-based; total reflects the full owned set so you can build pagers without extra requests.
**Query parameters**
- `page` (integer) — 1-based page number. Values < 1 are clamped to 1. Default: 1.
- `per_page` (integer) — Results per page. Clamped to the inclusive range [1, 100]. Default: 20.
**Response fields**
- `smartlinks` (array) — Smartlink rows for the requested page (see body below). Platforms are NOT included here — call GET /v1/smartlinks/:id for the full record.
- `total` (integer) — Total number of smartlinks owned by your account (across all pages).
- `page` (integer) — Echo of the resolved page parameter.
- `per_page` (integer) — Echo of the resolved per_page parameter.
**Response example**
```json
{
"smartlinks": [
{
"id": "1f8c8e2a-…",
"developer_id": "9a2b3c4d-…",
"title": "My New Song",
"slug": "my-new-song",
"artwork_url": "https://cdn.zolinks.in/smartlink-artwork/…/cover.jpg",
"is_active": true,
"click_count": 42,
"created_at": "2026-04-12T08:30:12.000Z"
}
],
"total": 27,
"page": 1,
"per_page": 20
}
```
**cURL**
```bash
curl "https://zolinks.in/developers/api/v1/smartlinks?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/smartlinks?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/smartlinks", {
params: { page: 1, per_page: 20 },
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### GET /smartlinks/:id
Fetch one smartlink by id along with the full ordered list of platform destinations. Each platform row carries its own click_count so you can render a per-destination breakdown without a separate analytics call.
**Query parameters**
- `id` (uuid (path), required) — Smartlink id. 404 if not found OR not owned by the calling API key.
**Response fields**
- `id` (uuid) — Smartlink id.
- `title` (string) — Display title (≤255 chars).
- `slug` (string) — URL slug, unique across the entire smartlinks namespace.
- `artwork_url` (string | null) — Optional cover artwork URL.
- `is_active` (boolean) — If false, the public smartlink page returns 404 and clicks are ignored.
- `click_count` (integer) — Total clicks across all platforms (sum of platforms[].click_count).
- `created_at` (timestamp) — ISO-8601 UTC creation timestamp.
- `platforms` (array) — Ordered by position ascending. Each row: { id, platform, url, position, click_count }.
**Response example**
```json
{
"id": "1f8c8e2a-…",
"title": "My New Song",
"slug": "my-new-song",
"artwork_url": "https://cdn.zolinks.in/smartlink-artwork/…/cover.jpg",
"is_active": true,
"click_count": 42,
"created_at": "2026-04-12T08:30:12.000Z",
"platforms": [
{ "id": "p1-…", "platform": "spotify", "url": "https://open.spotify.com/track/…", "position": 0, "click_count": 10 },
{ "id": "p2-…", "platform": "apple_music", "url": "https://music.apple.com/…", "position": 1, "click_count": 8 },
{ "id": "p3-…", "platform": "youtube", "url": "https://youtu.be/…", "position": 2, "click_count": 24 }
]
}
```
**cURL**
```bash
curl https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_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/smartlinks/SMARTLINK_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### PUT /smartlinks/:id
Update a smartlink's title, slug, artwork, active status, or platforms. Providing platforms replaces the entire list.
**Request body**
- `title` (string) — New title
- `slug` (string) — New slug
- `artwork_url` (string) — New artwork URL (null to remove)
- `is_active` (boolean) — Enable or disable the smartlink
- `platforms` (array) — Replacement array of { platform, url } objects
```json
{
"title": "Updated Song Title",
"platforms": [
{ "platform": "spotify", "url": "https://open.spotify.com/track/..." },
{ "platform": "youtube", "url": "https://youtube.com/watch?v=..." }
]
}
```
**cURL**
```bash
curl -X PUT https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Updated Song Title"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID", {
method: "PUT",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ title: "Updated Song Title" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.put("https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID", {
title: "Updated Song Title"
}, {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### DELETE /smartlinks/:id
Delete a smartlink and all its platform URLs. Returns { "success": true }.
**Response example**
```json
{ "success": true }
```
**cURL**
```bash
curl -X DELETE https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID \
-H "Authorization: Bearer zk_live_your_api_key_here"
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_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/smartlinks/SMARTLINK_UUID", {
headers: { Authorization: "Bearer zk_live_your_api_key_here" }
});
```
### POST /smartlinks/:id/click
Track a click on a smartlink. If a platform is supplied, BOTH the smartlink's total click_count AND that platform's per-destination click_count are atomically incremented; otherwise only the smartlink total is incremented. Fires the smartlink.clicked webhook with { smartlink_id, platform } to every active subscription.
**Query parameters**
- `id` (uuid (path), required) — Smartlink id. 404 if not found.
**Request body**
- `platform` (string) — Optional. Platform key as stored on the smartlink (e.g. 'spotify', 'apple_music', 'youtube'). If omitted, only the smartlink's total counter increments — useful when you don't yet know which destination the user will pick.
```json
{
"platform": "spotify"
}
```
**Response fields**
- `success` (boolean) — Always true on a 200 response.
- `clicks` (integer) — The smartlink's NEW total click_count after this increment (sum across all platforms).
**Response example**
```json
{
"success": true,
"clicks": 43
}
```
**cURL**
```bash
curl -X POST https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID/click \
-H "Authorization: Bearer zk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"platform":"spotify"}'
```
**JavaScript (fetch)**
```js
const res = await fetch("https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID/click", {
method: "POST",
headers: {
"Authorization": "Bearer zk_live_your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({ platform: "spotify" })
});
const data = await res.json();
```
**Node.js (axios)**
```js
const axios = require("axios");
const { data } = await axios.post(
"https://zolinks.in/developers/api/v1/smartlinks/SMARTLINK_UUID/click",
{ platform: "spotify" },
{ 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" }
});
```
### 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" }
});
```
## 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/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" }
});
```
## 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. ["smartlink.clicked"]
```json
{
"url": "https://your-app.com/webhooks/zolinks",
"events": ["smartlink.clicked"]
}
```
**Response example**
```json
{
"id": "uuid",
"url": "https://your-app.com/webhooks/zolinks",
"events": ["smartlink.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":["smartlink.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: ["smartlink.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: ["smartlink.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": ["smartlink.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" } }
);
```