Skip to content

Developers

API reference

Create pages, update links and pull analytics from your own tools. The REST API is included with the Agency plan.

Base URL
https://getkliq.vercel.app/api/v1
Authentication
Bearer API key
Format
JSON

Introduction

The Kliq API lets you manage link pages and read their analytics from your own tools, for example to onboard creators in bulk, sync links from a CRM or build your own reporting. It accepts and returns JSON and uses standard HTTP status codes.

Every request is scoped to the workspace that owns the API key, so you can only read and change that workspace’s pages. API access is part of the Agency plan.

Quick start

  1. Create an API key

    Open API Keys in your dashboard and create a key. Keys start with kliq_ and are shown only once, so store yours somewhere safe, for example in an environment variable:

    Terminal
    # Keep your key out of source control
    export KLIQ_API_KEY="kliq_your_api_key"
  2. Make your first request

    List the pages in your workspace:

    curl https://getkliq.vercel.app/api/v1/pages \
      -H "Authorization: Bearer $KLIQ_API_KEY"
  3. Read the response

    Successful responses wrap their payload in data:

    200 OK
    {
      "data": [
        {
          "id": "8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10",
          "slug": "miarose",
          "type": "landing",
          "published": true,
          "title": "Mia Rose",
          "created_at": "2026-09-14T10:21:07.482913+00:00",
          "updated_at": "2026-10-18T16:42:55.019274+00:00"
        },
        {
          "id": "3d7a9e21-6b4f-4c8a-a0e5-91f2c6d8b734",
          "slug": "kaibeats",
          "type": "landing",
          "published": false,
          "title": "KAI",
          "created_at": "2026-10-02T08:03:44.120551+00:00",
          "updated_at": "2026-10-02T08:03:44.120551+00:00"
        }
      ]
    }

    From here you can create a page, update its links or pull its stats.

Authentication

Authenticate every request with your API key in the Authorization header, using the Bearer scheme. The X-Api-Key header works too.

HTTP
GET /api/v1/pages HTTP/1.1
Host: getkliq.vercel.app
Authorization: Bearer kliq_your_api_key
Accept: application/json

Only workspace Owners and Admins can create keys, and the workspace needs the Agency plan. Requests without a valid key return 401 invalid_api_key, and workspaces without API access return 403 feature_locked.

Keep your keys secret. Only call the API from your own server, never from client-side code, mobile apps or public repositories. If a key leaks, revoke it in the dashboard and create a new one.

Errors

Failed requests return a 4xx or 5xx status and an error object with a machine-readable code and a human-readable message:

409 Conflict
{
  "error": {
    "code": "slug_taken",
    "message": "That slug is already taken."
  }
}
invalid_api_key401
The key is missing or malformed, or it was revoked.
feature_locked403
The workspace’s plan doesn’t include API access (Agency plan required).
not_found404
The page doesn’t exist, belongs to another workspace, or the ID isn’t a valid UUID.
slug_taken409
Another page already uses this slug.
limit_reached409
The workspace has reached its plan’s page limit.
validation_error422
A field is missing or invalid, or the slug is reserved. The message says which field and why.
server_error500
Something went wrong on our side.
feature_disabled503
Kliq has switched this off for now: the whole API, or creating new pages. See below.
maintenance503
Kliq is down for maintenance. See below.

Maintenance and switched-off features

Both of these return status 503. They are temporary, so retry later rather than treating them as a failure of your request.

  • maintenance: Kliq is down for maintenance, and every request gets this response before your key is even checked. The message can be a note from the Kliq team. If an end time is known, the Retry-After header says how many seconds to wait.
  • feature_disabled: Kliq has switched something off for everyone. With the public API off, every request with a key gets this response. If only part of it is off, such as new pages, saving changes or publishing, just the requests that need it get this response, for example creating a page or updating one. The message says what’s off.
503 Service Unavailable
{
  "error": {
    "code": "maintenance",
    "message": "Kliq is down for maintenance."
  }
}

Pages

A page is a creator’s link in bio: either a landing page with blocks and social icons, or a direct page that sends visitors straight to one destination after an 18+ confirmation. Changes go live immediately.

List pages

GET/pages

Returns every page in the workspace, in the same order as your dashboard. Each item is a summary, so fetch a single page for its full content.

curl https://getkliq.vercel.app/api/v1/pages \
  -H "Authorization: Bearer $KLIQ_API_KEY"
200 OK
{
  "data": [
    {
      "id": "8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10",
      "slug": "miarose",
      "type": "landing",
      "published": true,
      "title": "Mia Rose",
      "created_at": "2026-09-14T10:21:07.482913+00:00",
      "updated_at": "2026-10-18T16:42:55.019274+00:00"
    },
    {
      "id": "3d7a9e21-6b4f-4c8a-a0e5-91f2c6d8b734",
      "slug": "kaibeats",
      "type": "landing",
      "published": false,
      "title": "KAI",
      "created_at": "2026-10-02T08:03:44.120551+00:00",
      "updated_at": "2026-10-02T08:03:44.120551+00:00"
    }
  ]
}

Create a page

POST/pages

Creates a page and returns the full Page object with status 201. Only slug is required. Unknown top-level fields are rejected with validation_error, and creating a page beyond your plan’s limit returns limit_reached.

Body parameters

slugstringrequired
The page’s link name: 2–30 characters of letters, numbers, dots and underscores, starting and ending with a letter or number. Capitals become lowercase. Must be unique across Kliq, and some names are reserved.
titlestring
Display name, up to 80 characters.
biostring
Short bio shown under the name, up to 400 characters.
locationstring
Location line, up to 80 characters.
type"landing" | "direct"
landing (default) is a full page with blocks and socials. direct sends visitors to direct_url after an 18+ confirmation.
publishedboolean
Whether the page is live. Defaults to true.
direct_urlstring | null
Destination of a direct page: a full URL, up to 2,000 characters.
avatar_urlstring | null
Full URL of the profile picture, up to 1,000 characters.
blocksBlock[]
Up to 100 complete block objects, in display order.
socialsSocial[]
Up to 30 social icons, in display order.
themeobject
Design settings, such as colors, fonts and button style. Send any of the keys listed under Page.
social_styleobject
How the social icons look. Send any of the keys listed under Page.
settingsobject
Feature switches, such as verified, deeplink and pixels. Send any of the keys listed under Page.
seoobject
Custom title (up to 70 characters), description (up to 200), share image and noindex. Send any of them.
curl -X POST https://getkliq.vercel.app/api/v1/pages \
  -H "Authorization: Bearer $KLIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "lenafit",
    "title": "Lena · Fitness",
    "bio": "Coach for busy people.",
    "location": "Vienna",
    "published": true,
    "socials": [
      {
        "platform": "instagram",
        "value": "lenafit"
      },
      {
        "platform": "youtube",
        "value": "lenafit"
      }
    ]
  }'

Retrieve a page

GET/pages/{id}

Returns the full Page object, including its theme, blocks, socials and settings.

cURL
curl https://getkliq.vercel.app/api/v1/pages/8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10 \
  -H "Authorization: Bearer $KLIQ_API_KEY"
200 OK
{
  "data": {
    "id": "8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10",
    "slug": "miarose",
    "type": "landing",
    "published": true,
    "title": "Mia Rose",
    "bio": "Daily vlogs, skincare & my secret page",
    "location": "Prague, Czechia",
    "avatar_url": "https://cdn.example.com/avatars/miarose.jpg",
    "direct_url": null,
    "theme": {
      "template": "hero",
      "headerType": "hero",
      "bannerImage": null,
      "bannerColor": "#ffffff1f",
      "avatarShape": 50,
      "avatarSize": 104,
      "avatarRing": "solid",
      "avatarRingColor": "#ffffff40",
      "avatarRingColor2": "#ee2a7b",
      "avatarRingWidth": 4,
      "avatarRingGap": 0,
      "avatarRingGradient": false,
      "avatarGlowOn": false,
      "avatarGlow": 40,
      "avatarGlowColor": "#ffffff",
      "avatarAnimation": "none",
      "backgroundType": "solid",
      "backgroundColor": "#ffb8f9",
      "gradientFrom": "#1b1030",
      "gradientTo": "#0e0b14",
      "gradientAngle": 180,
      "backgroundImage": null,
      "backgroundOverlay": 40,
      "backgroundBlur": 12,
      "heroFade": 60,
      "overlayColor": "#ffb8f9",
      "titleFont": "poppins",
      "bodyFont": "inter",
      "titleColor": "#1a0a18",
      "textColor": "#3b1d3a",
      "buttonStyle": "fill",
      "buttonColor": "#ffffff",
      "buttonTextColor": "#1a0a18",
      "buttonBorderColor": "#ffffff00",
      "buttonBorderWidth": 2,
      "buttonBorderOn": false,
      "buttonHover": "lift",
      "buttonRadius": 18,
      "buttonShadow": "soft",
      "shadowColor": "#b4378f",
      "shadowSize": 6,
      "shadowBlur": 18,
      "shadowOpacity": 40,
      "shadowPosition": "bottom",
      "contentAlign": "center",
      "spacing": 14,
      "buttonSize": 58,
      "buttonTextAlign": "center",
      "nameSize": "lg",
      "pageWidth": "normal",
      "linkIcons": "image"
    },
    "blocks": [
      {
        "id": "5f0c3a8e-1d27-4b9a-8c64-2e7d9b1a0f53",
        "type": "header",
        "enabled": true,
        "title": "Links",
        "lines": true
      },
      {
        "id": "b7e1c2d4-9f3a-4c6b-8e21-5a0d7f9c3b18",
        "type": "link",
        "enabled": true,
        "title": "My exclusive page",
        "subtitle": "",
        "badge": "",
        "url": "https://example.com/mia",
        "layout": "classic",
        "thumbnail": null,
        "autoIcon": true,
        "animation": "pulse",
        "highlight": false,
        "ageGate": true,
        "smartRedirect": true,
        "routing": {
          "instagram": "https://example.com/mia?src=ig",
          "tiktok": "https://example.com/mia?src=tt"
        },
        "scheduleStart": null,
        "scheduleEnd": null
      }
    ],
    "socials": [
      {
        "platform": "tiktok",
        "value": "miarose"
      },
      {
        "platform": "instagram",
        "value": "miarose"
      },
      {
        "platform": "x",
        "value": "miarose"
      },
      {
        "platform": "youtube",
        "value": "miarose"
      }
    ],
    "social_style": {
      "position": "below",
      "brandColors": false,
      "iconColor": "#1a0a18",
      "showBackground": true,
      "brandBackground": false,
      "backgroundColor": "#ffffff",
      "size": "md"
    },
    "settings": {
      "onlineStatus": true,
      "verified": true,
      "verifiedColor": "#1d9bf0",
      "smartLocation": false,
      "deeplink": true,
      "openInBrowserButton": true,
      "iabScreen": true,
      "sensitive": false,
      "hideBranding": false,
      "shareButtons": true,
      "countdown": {
        "enabled": false,
        "minutes": 15,
        "label": "Offer ends in"
      },
      "pixels": {
        "meta": "",
        "metaEvent": "Lead",
        "tiktok": "",
        "ga4": "",
        "x": "",
        "snapchat": "",
        "gtm": ""
      }
    },
    "seo": {
      "title": "",
      "description": "",
      "image": null,
      "noindex": false
    },
    "group_id": null,
    "created_at": "2026-09-14T10:21:07.482913+00:00",
    "updated_at": "2026-10-18T16:42:55.019274+00:00"
  }
}

Update a page

PATCH/pages/{id}

Send only the fields you want to change. It accepts the same fields as Create a page and returns the updated Page object.

  • theme, settings, social_style and seo are merged: only the top-level keys you send change. Nested objects such as settings.pixels are replaced as a whole, so send all of their keys.
  • blocks and socials are replaced, so always send the complete list.
  • Changing slug changes the page’s public link, and the old link stops working.
  • A page’s type can’t be changed after it’s created. Sending it has no effect.
curl -X PATCH https://getkliq.vercel.app/api/v1/pages/8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10 \
  -H "Authorization: Bearer $KLIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Mia Rose ✨",
    "theme": {
      "template": "neon",
      "buttonColor": "#a855f7"
    },
    "settings": {
      "verified": true,
      "deeplink": true
    }
  }'

To replace the links on a page, send the full list of blocks:

Request body
{
  "blocks": [
    {
      "id": "b7e1c2d4-9f3a-4c6b-8e21-5a0d7f9c3b18",
      "type": "link",
      "enabled": true,
      "title": "My exclusive page",
      "subtitle": "",
      "badge": "",
      "url": "https://example.com/mia",
      "layout": "classic",
      "thumbnail": null,
      "autoIcon": true,
      "animation": "pulse",
      "highlight": false,
      "ageGate": true,
      "smartRedirect": true,
      "routing": {
        "instagram": "https://example.com/mia?src=ig",
        "tiktok": "https://example.com/mia?src=tt"
      },
      "scheduleStart": null,
      "scheduleEnd": null
    }
  ]
}

Delete a page

DELETE/pages/{id}

Permanently deletes the page, and its public link stops working right away.

cURL
curl -X DELETE https://getkliq.vercel.app/api/v1/pages/8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10 \
  -H "Authorization: Bearer $KLIQ_API_KEY"
200 OK
{
  "data": {
    "deleted": true,
    "slug": "miarose"
  }
}

Analytics

Page stats

GET/pages/{id}/stats?days=30

Returns totals and a day-by-day breakdown of views and clicks for one page. Bots aren’t counted.

Query parameters

daysinteger
Days to include, counting back from today. From 1 to 365, defaulting to 30, and capped by the plan’s analytics history.
curl "https://getkliq.vercel.app/api/v1/pages/8c0f4b4e-2a51-4f0e-9d3b-6f1a2c7e9b10/stats?days=30" \
  -H "Authorization: Bearer $KLIQ_API_KEY"
200 OK
{
  "data": {
    "days": 30,
    "totals": {
      "views": 48210,
      "clicks": 20977,
      "visitors": 31544
    },
    "daily": [
      {
        "date": "2026-09-21",
        "views": 1402,
        "clicks": 611
      },
      {
        "date": "2026-09-22",
        "views": 1588,
        "clicks": 702
      },
      {
        "date": "2026-09-23",
        "views": 1497,
        "clicks": 655
      }
    ]
  }
}

Response fields

daysinteger
The number of days actually returned.
totals.viewsinteger
Page views in the period.
totals.clicksinteger
Link and social icon clicks in the period.
totals.visitorsinteger
Unique visitors, counted per day. Someone who returns on another day counts again.
daily[]object[]
One entry per day with date (YYYY-MM-DD), views and clicks.

Objects

The Page object

Returned by Retrieve, Create and Update. Keys missing from theme, social_style, settings or seo fall back to Kliq’s defaults when the page is displayed. Unknown keys inside these four objects are ignored.

Attributes

iduuid
Unique ID of the page. Use it in /pages/{id} URLs.
slugstring
The page’s link name. The page lives at /{slug}, and on a connected custom domain.
type"landing" | "direct"
Full landing page, or a direct link behind an 18+ confirmation.
publishedboolean
Whether the page is live.
title · bio · locationstring
Profile text shown at the top of the page.
avatar_urlstring | null
Profile picture URL.
direct_urlstring | null
Destination of a direct page.
themeobject
templateheaderTypebannerImagebannerColoravatarShapeavatarSizeavatarRingavatarRingColoravatarRingColor2avatarRingWidthavatarRingGapavatarRingGradientavatarGlowOnavatarGlowavatarGlowColoravatarAnimationbackgroundTypebackgroundColorgradientFromgradientTogradientAnglebackgroundImagebackgroundOverlaybackgroundBlurheroFadeoverlayColortitleFontbodyFonttitleColortextColorbuttonStylebuttonColorbuttonTextColorbuttonBorderColorbuttonBorderWidthbuttonBorderOnbuttonHoverbuttonRadiusbuttonShadowshadowColorshadowSizeshadowBlurshadowOpacityshadowPositioncontentAlignspacingbuttonSizebuttonTextAlignnameSizepageWidthlinkIcons
blocksBlock[]
Links and content, in display order. See Block.
socialsSocial[]
Social icons. See Social.
social_styleobject
positionsizebrandColorsiconColorshowBackgroundbrandBackgroundbackgroundColor
settingsobject
onlineStatusverifiedverifiedColorsmartLocationdeeplinkopenInBrowserButtoniabScreensensitivehideBrandingshareButtonscountdownpixels
seoobject
titledescriptionimagenoindex
group_iduuid | null
The workspace group the page belongs to, if any. Read-only: groups are managed in the dashboard.
created_at · updated_atstring
ISO 8601 timestamps.

The Block object

Blocks make up a landing page. Every block has id, type and enabled. When you send blocks, each one must be complete, with all the fields of its type.

Link block

idstringrequired
Unique within the page, up to 64 characters.
type"link"required
The block type.
enabledbooleanrequired
Hidden from visitors when false.
titlestringrequired
Button label, up to 120 characters.
subtitlestringrequired
Second line, up to 160 characters. Use an empty string for none.
badgestringrequired
Small label on the corner, up to 24 characters. Use an empty string for none.
urlstringrequired
Destination, up to 2,000 characters.
layout"classic" | "row" | "card" | "featured" | "mini"required
Shape of the link: Button, Row, Card, Featured or Tile in the editor.
thumbnailstring | nullrequired
Full URL of the image or icon, up to 1,000 characters.
autoIconbooleanrequired
Show the destination’s own icon when there is no thumbnail.
animation"none" | "shake" | "pulse" | "bounce" | "wobble"required
Attention animation for the button.
highlightbooleanrequired
Adds a shine effect that draws the eye.
ageGatebooleanrequired
Visitors confirm they are 18+ before the link opens. Always on for links to 18+ platforms.
smartRedirectbooleanrequired
Resolve the destination on Kliq’s server so it never appears in the page HTML. Always on for links to 18+ platforms.
routingobjectrequired
A different URL per traffic source. Keys: instagram, tiktok, x, reddit, telegram, snapchat, youtube, facebook, threads, direct. Use {} for none.
scheduleStart · scheduleEndstring | nullrequired
ISO 8601 date-times. The link is only shown inside this window.
Link block
{
  "id": "b7e1c2d4-9f3a-4c6b-8e21-5a0d7f9c3b18",
  "type": "link",
  "enabled": true,
  "title": "My exclusive page",
  "subtitle": "",
  "badge": "",
  "url": "https://example.com/mia",
  "layout": "classic",
  "thumbnail": null,
  "autoIcon": true,
  "animation": "pulse",
  "highlight": false,
  "ageGate": true,
  "smartRedirect": true,
  "routing": {
    "instagram": "https://example.com/mia?src=ig",
    "tiktok": "https://example.com/mia?src=tt"
  },
  "scheduleStart": null,
  "scheduleEnd": null
}

The other block types:

"header"

title, lines

A section heading up to 120 characters. lines is a boolean: thin lines on each side.

"text"

text, align

A paragraph up to 1,000 characters. align is "left" or "center".

"image"

image, url, caption

image is a full URL or null, url is the link when tapped (an empty string for none), and caption is up to 160 characters.

"embed"

url, title

A YouTube, Spotify, SoundCloud or Vimeo player. title is up to 120 characters.

"countdown"

label, style, mode, minutes, endsAt, endText, showProgress, accent

A timer. style is "tiles" | "compact" | "minimal". mode is "evergreen" (minutes, 1–1440, per visitor) or "date" (endsAt, an ISO 8601 date-time or null). accent is a hex color.

"faq"

items

Up to 20 questions, each { "q": string, "a": string }, up to 200 and 1,000 characters.

"divider"

style

style is "line" | "dots" | "space".

The Social object

A social icon is { "platform": string, "value": string }. The value is a username, handle or full URL of up to 300 characters, a phone number for whatsapp and an address for email. It can’t be empty.

Supported platforms (27)

instagramtiktokxsnapchatfacebookyoutuberedditthreadswhatsapptelegramtwitchkickdiscordlinkedinpatreononlyfansfanvuestackedmyywispotifysoundcloudpinterestblueskygithubpaypalemailwebsite

Ready to build?

Create a key in your dashboard and make your first call in minutes.

Open API Keys

Search the docs

Find a guide or a section