API Reference

A RESTful HTTP API that lets any platform programmatically create direct and in-page safety links, manage existing links, and retrieve analytics — all authenticated with a personal API key tied to your Klook Up account.

Quick Start

Up and running in under 2 minutes.

Step 1

Create an account

Register for a free Klook Up account. An active profile is required before an API key can be issued.

Step 2

Generate an API key

Go to Settings › API Keys, give your key a name (e.g. My App), and click Generate. Copy the klup_… token — it is shown only once.

Step 3

Make your first request

Send a POST with your Bearer token and destination URL. Receive a short link in milliseconds.

Minimal working example

curl -X POST https://klookup.com/api/v1/links \
  -H "Authorization: Bearer klup_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-site.com/landing","type":"direct"}'

Base URL

https://klookup.com/api/v1

All v1 API endpoints are relative to this base URL. All requests and responses use JSON. TLS (HTTPS) is required — plain HTTP requests will be rejected.

Authentication

Every request must carry a valid API key issued to a registered user.

Bearer Token

Pass your API key in the Authorization header using the Bearer scheme:

Authorization: Bearer klup_a1b2c3d4…64hexchars
Content-Type: application/json

Key Format

All Klook Up API keys follow this format:

klup_<64 lowercase hexadecimal characters>

Keys contain 256 bits of cryptographic randomness. Only a SHA-256 hash is stored server-side — the plaintext key is shown to you once only at creation time.

Account required

API keys can only be issued to registered and logged-in users. You may hold up to 10 active keys per account. Revoke unused keys from Settings › API Keys.

Request & Response Format

Requests

  • Send request bodies as JSON with Content-Type: application/json.
  • All strings must be UTF-8 encoded.
  • Dates must be ISO-8601 strings (e.g. 2026-12-31T23:59:59Z).
  • Boolean-style flags use integers: 1 = true, 0 = false.

Successful Response envelope

HTTP 200 or 201:

{
  "success": true,
  "data": { ... }          // returned resource or array
}

Error Response envelope

{
  "success": false,
  "error": "Human-readable message",
  "details": { ... }       // optional: per-field validation errors
}

Error Handling

Klook Up uses standard HTTP status codes.

HTTP StatusMeaningCommon cause
200 OKSuccessRequest processed successfully
201 CreatedResource createdA new link or API key was created
400 Bad RequestValidation errorMissing / invalid field in request body
401 UnauthorizedMissing or invalid API keyNo Authorization header, or key is revoked
403 ForbiddenAccess deniedYou don't own the resource you are trying to modify
404 Not FoundResource missingLink ID does not exist or belongs to another user
405 Method Not AllowedWrong HTTP methodUsing GET where POST is required, etc.
429 Too Many RequestsRate limit hitExceeded anonymous limit (5 creations / 24 h)
500 Internal Server ErrorServer errorUnexpected server-side failure — contact support

Endpoints

In-Page Safety Link Guide

How the inpage type protects your audience end-to-end.

How it works

  1. Your platform calls POST /api/v1/links with "type":"inpage".
  2. Klook Up returns a short_url ending with /page.
  3. You share that URL with your audience (embed in a message, email, or web page).
  4. The visitor opens the URL and sees a branded preview page on klookup.com showing the destination domain, your title, and description.
  5. They complete a Cloudflare Turnstile captcha (no user-visible puzzle — usually just a checkbox).
  6. After passing, they click Continue to Website to proceed to the destination.

Full curl example

curl -X POST https://klookup.com/api/v1/links \
  -H "Authorization: Bearer klup_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/sensitive-download.zip",
    "type": "inpage",
    "post_id": "post_42",
    "title": "Download: Example App v2.0",
    "description": "This file has been verified safe by our team."
  }'

Response

{
  "success": true,
  "data": {
    "id": 99,
    "short_code": "xYz5678",
    "short_url": "https://klookup.com/xYz5678/page",
    "target_url": "https://example.com/sensitive-download.zip",
    "type": "inpage",
    "title": "Download: Example App v2.0",
    "description": "This file has been verified safe by our team.",
    "expires_at": null,
    "post_id": "post_42",
    "site_url": "https://example.com/sensitive-download.zip",
    "site_verified_at": null,
    "created_at": "2026-02-22T12:00:00Z"
  }
}

The short_url ends with /page — that is the safety preview URL to share with your audience.

When to use in-page links

  • Sharing download links (files, APKs, PDFs) from external storage
  • Redirecting community members to third-party websites you don't fully control
  • Services that want to give users a heads-up before navigating away
  • Affiliate or referral programs where a preview builds visitor confidence
  • Any situation where you want bot/automation filtering before sending traffic

Automatic Site Verification

When you pass site_url pointing to the page where your inpage link is embedded, Klook Up enforces a one active inpage link per site_url rule per account. If you call POST /api/v1/links again with the same site_url, the existing link is returned (HTTP 200 with "existing": true) — no duplicate is created. Klook Up will also automatically verify that the link remains active on your website.

  1. Klook Up periodically fetches site_url using its built-in crawler.
  2. It searches the page HTML for your inpage link's short_code.
  3. If found, site_verified_at is updated and the link remains active.
  4. If not found, scheduled_deletion_at is set to 24 hours from that check.
  5. If the next verification still finds the link missing and the 24-hour window has passed, the link is permanently deleted.
  6. Removing the inpage link from your page and forgetting to delete it via the API will therefore result in automatic cleanup.

Best practice: always delete links you no longer use via the dashboard or DELETE /api/v1/links/:id rather than simply removing them from your page.

Rate Limits

Limits are applied per API key or per IP for unauthenticated access.

ContextLimitWindowScope
Authenticated (API key)UnlimitedPer API key
Authenticated (session)UnlimitedPer user account
Anonymous (no key)5 link creations24 hoursPer IP address

Rate limit response

Only anonymous (unauthenticated) requests can be rate-limited. If an anonymous caller exceeds 5 creations in 24 hours they receive 429 Too Many Requests:

{
  "success": false,
  "error": "Rate limit exceeded. Try again after 2026-02-23T10:00:00Z"
}

Authenticated requests (Bearer API key or logged-in session) are unlimited.

Code Examples

Copy-paste snippets for the most common use-cases.

cURL — create an in-page link

curl -X POST https://klookup.com/api/v1/links \
  -H "Authorization: Bearer klup_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-destination.com",
    "type": "inpage",
    "title": "Visit our partner site",
    "description": "This link has been reviewed by our team."
  }'

JavaScript (fetch)

const API_KEY = process.env.KLOOKUP_API_KEY; // klup_…

async function createInPageLink(url, title, description) {
  const res = await fetch("https://klookup.com/api/v1/links", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url,
      type: "inpage",
      title,
      description,
    }),
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error ?? "Failed to create link");
  }

  const { data } = await res.json();
  return data.short_url; // "https://klookup.com/xYz5678/page"
}

const safeLink = await createInPageLink(
  "https://example.com/file.zip",
  "Download Example App",
  "Verified safe — click proceed to download."
);
console.log(safeLink);

TypeScript — reusable client

interface CreateLinkOptions {
  url: string;
  type?: "direct" | "inpage";
  /** Required when type is "inpage" — unique ID of the post/page on your site */
  post_id?: string;
  title?: string;
  description?: string;
  expires_at?: string;    // ISO-8601
  /**
   * Your website URL where this inpage link will be embedded.
   * Triggers automatic site verification — the link is deleted after 24 h
   * if Klook Up cannot find it on the page.
   */
  site_url?: string;
}

interface KlookUpLink {
  id: number;
  short_code: string;
  short_url: string;
  target_url: string;
  type: "direct" | "inpage";
  post_id?: string | null;
  site_url?: string | null;
  site_verified_at?: string | null;
  created_at: string;
  /** true when post_id was provided and an existing link was returned instead of creating a new one */
  existing?: boolean;
}

class KlookUpClient {
  constructor(private readonly apiKey: string) {}

  async createLink(opts: CreateLinkOptions): Promise<KlookUpLink> {
    const res = await fetch("https://klookup.com/api/v1/links", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(opts),
    });
    const body = await res.json() as { success: boolean; data: KlookUpLink; error?: string };
    if (!res.ok || !body.success) throw new Error(body.error ?? "API error");
    return body.data;
  }
}

// Usage
const client = new KlookUpClient(process.env.KLOOKUP_API_KEY!);
const link = await client.createLink({
  url: "https://example.com",
  type: "inpage",
  title: "Our partner site",
});
console.log(link.short_url);

Python (requests)

import os
import requests

API_KEY = os.environ["KLOOKUP_API_KEY"]  # klup_…
BASE_URL = "https://klookup.com/api/v1"

def create_link(url: str, link_type: str = "direct", **kwargs) -> dict:
    """
    Create a Klook Up short link.
    link_type: "direct" or "inpage"
    kwargs: post_id (required for inpage), title, description, expires_at, site_url
    """
    payload = {"url": url, "type": link_type, **kwargs}
    response = requests.post(
        f"{BASE_URL}/links",
        json=payload,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        timeout=10,
    )
    response.raise_for_status()
    return response.json()["data"]

# Create an in-page safety link
link = create_link(
    url="https://example.com/confidential.pdf",
    link_type="inpage",
    title="Confidential Document",
    description="Please verify you are authorised before proceeding.",
)
print(link["short_url"])  # https://klookup.com/xYz5678/page

PHP (cURL)

<?php

function klookup_create_link(string $apiKey, array $payload): array {
    $ch = curl_init("https://klookup.com/api/v1/links");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($payload),
        CURLOPT_HTTPHEADER     => [
            "Authorization: Bearer $apiKey",
            "Content-Type: application/json",
        ],
        CURLOPT_TIMEOUT        => 10,
    ]);
    $body   = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $json = json_decode($body, true);
    if ($status >= 400 || !$json['success']) {
        throw new RuntimeException($json['error'] ?? 'API error');
    }
    return $json['data'];
}

$link = klookup_create_link(getenv('KLOOKUP_API_KEY'), [
    'url'         => 'https://example.com/download',
    'type'        => 'inpage',
    'title'       => 'Download our software',
    'description' => 'Verified safe by our security team.',
]);

echo $link['short_url']; // https://klookup.com/xYz5678/page

API Key Security

Store keys as environment variables

Never hard-code API keys in source files or commit them to version control. Use environment variables (e.g. KLOOKUP_API_KEY) or a secrets manager.

Use server-side only

API keys must never be included in client-side JavaScript, mobile app binaries, or public HTML. All requests should originate from your backend server.

Rotate keys regularly

Create a new key, update your environment variables, then revoke the old key from Settings › API Keys. Rotation limits exposure if a key is ever compromised.

One key per application

Issue a separate key for each integration or environment (staging vs production). This allows you to revoke access for a single app without disrupting others.

Monitor last-used timestamps

Each key tracks its last-used timestamp in Settings › API Keys. If you see activity for a key you no longer use, revoke it immediately.

Ready to integrate?

Create your free account, issue an API key in seconds, and start protecting your audience with in-page safety links today.