API Documentation

Manage domains, redirects, statistics, and blacklist rules via REST API.

Base URL: https://www.linkvice.com/api/v1/

Quick Start

Get up and running with the LinkVice API in minutes. Here is a quick example that lists all your domains:

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/domains',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

print_r($response['data']);
import requests

response = requests.get(
    'https://www.linkvice.com/api/v1/domains',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

for domain in data['data']:
    print(domain['domain'], domain['status'])
const response = await fetch('https://www.linkvice.com/api/v1/domains', {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

console.log(data.data);

Authentication

All API requests require a valid API key sent via the Authorization header using the Bearer scheme.

Getting Your API Key

  1. Log in to your LinkVice Dashboard
  2. Navigate to Dashboard > Settings
  3. Under the API Keys section, click Generate New Key
  4. Copy your key and store it securely — it will only be shown once

Header Format

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Error Responses

If the API key is missing or invalid, you will receive one of the following responses:

StatusResponseMeaning
401 {"error": true, "message": "Missing or invalid API key."} No Authorization header was sent, or the key format is invalid.
403 {"error": true, "message": "API key revoked or inactive."} The API key exists but has been revoked or the associated account is suspended.

Rate Limiting

The API enforces a rate limit of 100 requests per minute per API key. Rate limit information is included in every response via headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1711305600

If you exceed the rate limit, you will receive a 429 Too Many Requests response:

{
    "error": true,
    "message": "Rate limit exceeded. Please wait before making another request.",
    "retry_after": 34
}

Response Format

All responses are returned as JSON. There are three standard response envelopes:

Success Response

{
    "success": true,
    "data": {
        "id": 42,
        "domain": "example.com",
        "status": "active"
    }
}

Paginated Response

{
    "success": true,
    "data": [
        { "id": 1, "target_url": "https://example.com/page-1" },
        { "id": 2, "target_url": "https://example.com/page-2" }
    ],
    "meta": {
        "page": 1,
        "per_page": 25,
        "total": 100
    }
}

Error Response

{
    "error": true,
    "message": "The domain field is required."
}

Domains

GET /api/v1/domains

Retrieve a list of all domains associated with your account.

Parameters

No parameters required.

Response

{
    "success": true,
    "data": [
        {
            "id": 1,
            "domain": "go.example.com",
            "status": "active",
            "use_ssl": true,
            "created_at": "2025-08-15T10:30:00Z"
        },
        {
            "id": 2,
            "domain": "links.mybrand.com",
            "status": "pending_dns",
            "use_ssl": true,
            "created_at": "2025-09-20T14:22:00Z"
        }
    ]
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/domains',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

foreach ($response['data'] as $domain) {
    echo $domain['domain'] . ' - ' . $domain['status'] . "\n";
}
import requests

response = requests.get(
    'https://www.linkvice.com/api/v1/domains',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

for domain in data['data']:
    print(f"{domain['domain']} - {domain['status']}")
const response = await fetch('https://www.linkvice.com/api/v1/domains', {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

data.data.forEach(domain => {
    console.log(`${domain.domain} - ${domain.status}`);
});

POST /api/v1/domains

Add a new domain to your account. The domain will initially be in pending_dns status until DNS is properly configured.

After adding a domain, point its DNS to 178.162.216.23 (A record) or use nameservers ns1.linkvice.com / ns2.linkvice.com. The domain status will automatically update to active once DNS propagation completes.

Request Body

ParameterTypeRequiredDescription
domain string required The domain name to add (e.g., go.example.com)
use_ssl boolean optional Enable SSL for this domain. Defaults to true.

Response

{
    "success": true,
    "data": {
        "id": 3,
        "domain": "go.example.com",
        "status": "pending_dns",
        "use_ssl": true,
        "created_at": "2026-03-24T12:00:00Z"
    }
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/domains',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode([
        'domain'  => 'go.example.com',
        'use_ssl' => true,
    ]),
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo 'Domain added: ' . $response['data']['domain'];
echo 'Status: ' . $response['data']['status'];
import requests

response = requests.post(
    'https://www.linkvice.com/api/v1/domains',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'domain': 'go.example.com',
        'use_ssl': True,
    }
)
data = response.json()

print(f"Domain added: {data['data']['domain']}")
print(f"Status: {data['data']['status']}")
const response = await fetch('https://www.linkvice.com/api/v1/domains', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        domain: 'go.example.com',
        use_ssl: true,
    })
});
const data = await response.json();

console.log(`Domain added: ${data.data.domain}`);
console.log(`Status: ${data.data.status}`);

GET /api/v1/domains/{id}

Retrieve detailed information about a specific domain, including the total number of redirects.

URL Parameters

ParameterTypeRequiredDescription
id integer required The domain ID

Response

{
    "success": true,
    "data": {
        "id": 1,
        "domain": "go.example.com",
        "status": "active",
        "use_ssl": true,
        "redirect_count": 24,
        "created_at": "2025-08-15T10:30:00Z"
    }
}

Code Examples

<?php
$domainId = 1;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/domains/{$domainId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $response['data']['domain'] . ' has ' . $response['data']['redirect_count'] . ' redirects';
import requests

domain_id = 1

response = requests.get(
    f'https://www.linkvice.com/api/v1/domains/{domain_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

print(f"{data['data']['domain']} has {data['data']['redirect_count']} redirects")
const domainId = 1;

const response = await fetch(`https://www.linkvice.com/api/v1/domains/${domainId}`, {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

console.log(`${data.data.domain} has ${data.data.redirect_count} redirects`);

DELETE /api/v1/domains/{id}

Delete a domain from your account. All redirects associated with this domain must be deleted first.

You must delete all redirects associated with this domain before deleting the domain itself. Attempting to delete a domain with active redirects will return a 400 error.

URL Parameters

ParameterTypeRequiredDescription
id integer required The domain ID to delete

Response

{
    "success": true,
    "data": {
        "message": "Domain deleted successfully."
    }
}

Code Examples

<?php
$domainId = 1;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/domains/{$domainId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $response['data']['message'];
import requests

domain_id = 1

response = requests.delete(
    f'https://www.linkvice.com/api/v1/domains/{domain_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

print(data['data']['message'])
const domainId = 1;

const response = await fetch(`https://www.linkvice.com/api/v1/domains/${domainId}`, {
    method: 'DELETE',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

console.log(data.data.message);

Redirects

GET /api/v1/redirects

Retrieve a paginated list of redirects. Optionally filter by domain.

Query Parameters

ParameterTypeRequiredDescription
domain_id integer optional Filter redirects by domain ID
page integer optional Page number. Defaults to 1.
per_page integer optional Results per page (max 100). Defaults to 25.

Response

{
    "success": true,
    "data": [
        {
            "id": 101,
            "domain_id": 1,
            "redirect_url": "https://go.example.com/abc123",
            "target_url": "https://www.mysite.com/landing-page",
            "redirect_type": "direct",
            "http_code": 301,
            "block_bots": true,
            "favicon_redirect": true,
            "robots_redirect": true,
            "ads_redirect": false,
            "llm_redirect": true,
            "total_clicks": 1543,
            "created_at": "2025-09-10T08:15:00Z"
        },
        {
            "id": 102,
            "domain_id": 1,
            "redirect_url": "https://go.example.com/promo2025",
            "target_url": "https://www.mysite.com/promo",
            "redirect_type": "hash",
            "http_code": 302,
            "block_bots": false,
            "favicon_redirect": true,
            "robots_redirect": true,
            "ads_redirect": true,
            "llm_redirect": false,
            "total_clicks": 892,
            "created_at": "2025-10-01T12:00:00Z"
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 25,
        "total": 48
    }
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/redirects?domain_id=1&page=1&per_page=25',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

foreach ($response['data'] as $redirect) {
    echo $redirect['redirect_url'] . ' -> ' . $redirect['target_url'] . "\n";
}

echo 'Total: ' . $response['meta']['total'];
import requests

response = requests.get(
    'https://www.linkvice.com/api/v1/redirects',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={
        'domain_id': 1,
        'page': 1,
        'per_page': 25,
    }
)
data = response.json()

for redirect in data['data']:
    print(f"{redirect['redirect_url']} -> {redirect['target_url']}")

print(f"Total: {data['meta']['total']}")
const params = new URLSearchParams({
    domain_id: 1,
    page: 1,
    per_page: 25,
});

const response = await fetch(`https://www.linkvice.com/api/v1/redirects?${params}`, {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

data.data.forEach(redirect => {
    console.log(`${redirect.redirect_url} -> ${redirect.target_url}`);
});

console.log(`Total: ${data.meta.total}`);

POST /api/v1/redirects

Create a new redirect. A unique short URL will be automatically generated.

Request Body

ParameterTypeRequiredDescription
domain_id integer required ID of the domain to create the redirect on
target_url string required The destination URL to redirect to
redirect_type string optional direct or hash. Defaults to direct.
http_code integer optional 301, 302, or 307. Defaults to 301.
language_rules object optional Language-based redirect rules. Keys are ISO 639-1 language codes, values are target URLs. Example: {"de": "https://example.de", "fr": "https://example.fr"}
image_redirect_url string optional URL of an image to display on the redirect page (hash type only)
block_bots boolean optional Block known bots from following the redirect. Defaults to false.
favicon_redirect boolean optional Serve a favicon for this redirect. Defaults to true.
robots_redirect boolean optional Serve a robots.txt for this redirect. Defaults to true.
ads_redirect boolean optional Serve an ads.txt for this redirect. Defaults to false.
llm_redirect boolean optional Serve an llms.txt for this redirect. Defaults to true.

Response

{
    "success": true,
    "data": {
        "id": 103,
        "domain_id": 1,
        "redirect_url": "https://go.example.com/x7k9m2",
        "target_url": "https://www.mysite.com/new-campaign",
        "redirect_type": "direct",
        "http_code": 301,
        "language_rules": {
            "de": "https://www.mysite.de/neue-kampagne",
            "fr": "https://www.mysite.fr/nouvelle-campagne"
        },
        "image_redirect_url": null,
        "block_bots": true,
        "favicon_redirect": true,
        "robots_redirect": true,
        "ads_redirect": false,
        "llm_redirect": true,
        "total_clicks": 0,
        "created_at": "2026-03-24T12:00:00Z"
    }
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/redirects',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode([
        'domain_id'      => 1,
        'target_url'     => 'https://www.mysite.com/new-campaign',
        'redirect_type'  => 'direct',
        'http_code'      => 301,
        'block_bots'     => true,
        'language_rules'  => [
            'de' => 'https://www.mysite.de/neue-kampagne',
            'fr' => 'https://www.mysite.fr/nouvelle-campagne',
        ],
        'favicon_redirect' => true,
        'robots_redirect'  => true,
        'ads_redirect'     => false,
        'llm_redirect'     => true,
    ]),
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo 'Redirect created: ' . $response['data']['redirect_url'];
import requests

response = requests.post(
    'https://www.linkvice.com/api/v1/redirects',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'domain_id': 1,
        'target_url': 'https://www.mysite.com/new-campaign',
        'redirect_type': 'direct',
        'http_code': 301,
        'block_bots': True,
        'language_rules': {
            'de': 'https://www.mysite.de/neue-kampagne',
            'fr': 'https://www.mysite.fr/nouvelle-campagne',
        },
        'favicon_redirect': True,
        'robots_redirect': True,
        'ads_redirect': False,
        'llm_redirect': True,
    }
)
data = response.json()

print(f"Redirect created: {data['data']['redirect_url']}")
const response = await fetch('https://www.linkvice.com/api/v1/redirects', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        domain_id: 1,
        target_url: 'https://www.mysite.com/new-campaign',
        redirect_type: 'direct',
        http_code: 301,
        block_bots: true,
        language_rules: {
            de: 'https://www.mysite.de/neue-kampagne',
            fr: 'https://www.mysite.fr/nouvelle-campagne',
        },
        favicon_redirect: true,
        robots_redirect: true,
        ads_redirect: false,
        llm_redirect: true,
    })
});
const data = await response.json();

console.log(`Redirect created: ${data.data.redirect_url}`);

GET /api/v1/redirects/{id}

Retrieve full details of a specific redirect including all configuration options.

URL Parameters

ParameterTypeRequiredDescription
id integer required The redirect ID

Response

{
    "success": true,
    "data": {
        "id": 101,
        "domain_id": 1,
        "redirect_url": "https://go.example.com/abc123",
        "target_url": "https://www.mysite.com/landing-page",
        "redirect_type": "direct",
        "http_code": 301,
        "language_rules": null,
        "image_redirect_url": null,
        "block_bots": true,
        "favicon_redirect": true,
        "robots_redirect": true,
        "ads_redirect": false,
        "llm_redirect": true,
        "total_clicks": 1543,
        "unique_visitors": 1102,
        "created_at": "2025-09-10T08:15:00Z",
        "updated_at": "2026-03-20T16:45:00Z"
    }
}

Code Examples

<?php
$redirectId = 101;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/redirects/{$redirectId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

$redirect = $response['data'];
echo "URL: {$redirect['redirect_url']}\n";
echo "Target: {$redirect['target_url']}\n";
echo "Clicks: {$redirect['total_clicks']}\n";
echo "Type: {$redirect['redirect_type']} ({$redirect['http_code']})";
import requests

redirect_id = 101

response = requests.get(
    f'https://www.linkvice.com/api/v1/redirects/{redirect_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

redirect = data['data']
print(f"URL: {redirect['redirect_url']}")
print(f"Target: {redirect['target_url']}")
print(f"Clicks: {redirect['total_clicks']}")
print(f"Type: {redirect['redirect_type']} ({redirect['http_code']})")
const redirectId = 101;

const response = await fetch(`https://www.linkvice.com/api/v1/redirects/${redirectId}`, {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

const redirect = data.data;
console.log(`URL: ${redirect.redirect_url}`);
console.log(`Target: ${redirect.target_url}`);
console.log(`Clicks: ${redirect.total_clicks}`);
console.log(`Type: ${redirect.redirect_type} (${redirect.http_code})`);

PUT /api/v1/redirects/{id}

Update an existing redirect. Only include the fields you want to change; omitted fields will remain unchanged.

URL Parameters

ParameterTypeRequiredDescription
id integer required The redirect ID to update

Request Body

ParameterTypeRequiredDescription
target_url string optional New destination URL
redirect_type string optional direct or hash
http_code integer optional 301, 302, or 307
language_rules object optional Language-based redirect rules. Set to null to remove.
image_redirect_url string optional Image URL for hash redirects. Set to null to remove.
block_bots boolean optional Block known bots
favicon_redirect boolean optional Serve a favicon
robots_redirect boolean optional Serve a robots.txt
ads_redirect boolean optional Serve an ads.txt
llm_redirect boolean optional Serve an llms.txt

Response

{
    "success": true,
    "data": {
        "id": 101,
        "domain_id": 1,
        "redirect_url": "https://go.example.com/abc123",
        "target_url": "https://www.mysite.com/updated-landing",
        "redirect_type": "direct",
        "http_code": 302,
        "language_rules": null,
        "image_redirect_url": null,
        "block_bots": true,
        "favicon_redirect": true,
        "robots_redirect": true,
        "ads_redirect": true,
        "llm_redirect": true,
        "total_clicks": 1543,
        "created_at": "2025-09-10T08:15:00Z",
        "updated_at": "2026-03-24T14:30:00Z"
    }
}

Code Examples

<?php
$redirectId = 101;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/redirects/{$redirectId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => json_encode([
        'target_url'   => 'https://www.mysite.com/updated-landing',
        'http_code'    => 302,
        'ads_redirect' => true,
    ]),
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo 'Redirect updated: ' . $response['data']['target_url'];
echo 'HTTP Code: ' . $response['data']['http_code'];
import requests

redirect_id = 101

response = requests.put(
    f'https://www.linkvice.com/api/v1/redirects/{redirect_id}',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'target_url': 'https://www.mysite.com/updated-landing',
        'http_code': 302,
        'ads_redirect': True,
    }
)
data = response.json()

print(f"Redirect updated: {data['data']['target_url']}")
print(f"HTTP Code: {data['data']['http_code']}")
const redirectId = 101;

const response = await fetch(`https://www.linkvice.com/api/v1/redirects/${redirectId}`, {
    method: 'PUT',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        target_url: 'https://www.mysite.com/updated-landing',
        http_code: 302,
        ads_redirect: true,
    })
});
const data = await response.json();

console.log(`Redirect updated: ${data.data.target_url}`);
console.log(`HTTP Code: ${data.data.http_code}`);

DELETE /api/v1/redirects/{id}

Permanently delete a redirect. This action cannot be undone and all associated statistics will be removed.

URL Parameters

ParameterTypeRequiredDescription
id integer required The redirect ID to delete

Response

{
    "success": true,
    "data": {
        "message": "Redirect deleted successfully."
    }
}

Code Examples

<?php
$redirectId = 101;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/redirects/{$redirectId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $response['data']['message'];
import requests

redirect_id = 101

response = requests.delete(
    f'https://www.linkvice.com/api/v1/redirects/{redirect_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

print(data['data']['message'])
const redirectId = 101;

const response = await fetch(`https://www.linkvice.com/api/v1/redirects/${redirectId}`, {
    method: 'DELETE',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

console.log(data.data.message);

Statistics

GET /api/v1/stats/redirect/{id}

Retrieve detailed statistics for a specific redirect, including click data, geographic breakdown, and referrer information.

URL Parameters

ParameterTypeRequiredDescription
id integer required The redirect ID

Query Parameters

ParameterTypeRequiredDescription
date_from string optional Start date in YYYY-MM-DD format. Defaults to 30 days ago.
date_to string optional End date in YYYY-MM-DD format. Defaults to today.
country string optional Filter by ISO 3166-1 alpha-2 country code (e.g., US, DE)
language string optional Filter by ISO 639-1 language code (e.g., en, de)

Response

{
    "success": true,
    "data": {
        "total_clicks": 1543,
        "unique_visitors": 1102,
        "status_breakdown": {
            "redirected": 1420,
            "js_page": 98,
            "blocked": 25
        },
        "clicks_by_date": [
            { "date": "2026-03-18", "clicks": 52 },
            { "date": "2026-03-19", "clicks": 61 },
            { "date": "2026-03-20", "clicks": 48 },
            { "date": "2026-03-21", "clicks": 73 },
            { "date": "2026-03-22", "clicks": 55 },
            { "date": "2026-03-23", "clicks": 67 },
            { "date": "2026-03-24", "clicks": 39 }
        ],
        "top_countries": [
            { "country": "US", "clicks": 620 },
            { "country": "DE", "clicks": 315 },
            { "country": "GB", "clicks": 198 },
            { "country": "FR", "clicks": 142 },
            { "country": "CA", "clicks": 89 }
        ],
        "top_languages": [
            { "language": "en", "clicks": 890 },
            { "language": "de", "clicks": 315 },
            { "language": "fr", "clicks": 167 },
            { "language": "es", "clicks": 94 }
        ],
        "top_referrers": [
            { "referrer": "https://www.google.com", "clicks": 412 },
            { "referrer": "https://twitter.com", "clicks": 287 },
            { "referrer": "direct", "clicks": 245 },
            { "referrer": "https://www.facebook.com", "clicks": 189 },
            { "referrer": "https://www.reddit.com", "clicks": 76 }
        ]
    }
}

Code Examples

<?php
$redirectId = 101;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/stats/redirect/{$redirectId}?date_from=2026-03-01&date_to=2026-03-24",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

$stats = $response['data'];
echo "Total Clicks: {$stats['total_clicks']}\n";
echo "Unique Visitors: {$stats['unique_visitors']}\n";

echo "\nTop Countries:\n";
foreach ($stats['top_countries'] as $country) {
    echo "  {$country['country']}: {$country['clicks']} clicks\n";
}

echo "\nTop Referrers:\n";
foreach ($stats['top_referrers'] as $referrer) {
    echo "  {$referrer['referrer']}: {$referrer['clicks']} clicks\n";
}
import requests

redirect_id = 101

response = requests.get(
    f'https://www.linkvice.com/api/v1/stats/redirect/{redirect_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={
        'date_from': '2026-03-01',
        'date_to': '2026-03-24',
    }
)
data = response.json()

stats = data['data']
print(f"Total Clicks: {stats['total_clicks']}")
print(f"Unique Visitors: {stats['unique_visitors']}")

print("\nTop Countries:")
for country in stats['top_countries']:
    print(f"  {country['country']}: {country['clicks']} clicks")

print("\nTop Referrers:")
for referrer in stats['top_referrers']:
    print(f"  {referrer['referrer']}: {referrer['clicks']} clicks")
const redirectId = 101;

const params = new URLSearchParams({
    date_from: '2026-03-01',
    date_to: '2026-03-24',
});

const response = await fetch(
    `https://www.linkvice.com/api/v1/stats/redirect/${redirectId}?${params}`, {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

const stats = data.data;
console.log(`Total Clicks: ${stats.total_clicks}`);
console.log(`Unique Visitors: ${stats.unique_visitors}`);

console.log('\nTop Countries:');
stats.top_countries.forEach(c => {
    console.log(`  ${c.country}: ${c.clicks} clicks`);
});

console.log('\nTop Referrers:');
stats.top_referrers.forEach(r => {
    console.log(`  ${r.referrer}: ${r.clicks} clicks`);
});

GET /api/v1/stats/domain/{id}

Retrieve aggregated statistics for all redirects under a specific domain.

URL Parameters

ParameterTypeRequiredDescription
id integer required The domain ID

Query Parameters

ParameterTypeRequiredDescription
date_from string optional Start date in YYYY-MM-DD format. Defaults to 30 days ago.
date_to string optional End date in YYYY-MM-DD format. Defaults to today.

Response

{
    "success": true,
    "data": {
        "total_clicks": 12847,
        "unique_visitors": 9631,
        "status_breakdown": {
            "redirected": 11920,
            "js_page": 712,
            "blocked": 215
        },
        "clicks_by_date": [
            { "date": "2026-03-18", "clicks": 412 },
            { "date": "2026-03-19", "clicks": 389 },
            { "date": "2026-03-20", "clicks": 445 },
            { "date": "2026-03-21", "clicks": 521 },
            { "date": "2026-03-22", "clicks": 398 },
            { "date": "2026-03-23", "clicks": 467 },
            { "date": "2026-03-24", "clicks": 312 }
        ],
        "top_countries": [
            { "country": "US", "clicks": 5120 },
            { "country": "DE", "clicks": 2340 },
            { "country": "GB", "clicks": 1567 },
            { "country": "FR", "clicks": 1023 },
            { "country": "CA", "clicks": 789 }
        ],
        "top_languages": [
            { "language": "en", "clicks": 7230 },
            { "language": "de", "clicks": 2340 },
            { "language": "fr", "clicks": 1245 },
            { "language": "es", "clicks": 876 }
        ],
        "top_referrers": [
            { "referrer": "https://www.google.com", "clicks": 3890 },
            { "referrer": "direct", "clicks": 2456 },
            { "referrer": "https://twitter.com", "clicks": 1987 },
            { "referrer": "https://www.facebook.com", "clicks": 1234 },
            { "referrer": "https://www.reddit.com", "clicks": 567 }
        ]
    }
}

Code Examples

<?php
$domainId = 1;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/stats/domain/{$domainId}?date_from=2026-03-01&date_to=2026-03-24",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

$stats = $response['data'];
echo "Domain-wide Stats\n";
echo "Total Clicks: {$stats['total_clicks']}\n";
echo "Unique Visitors: {$stats['unique_visitors']}\n";
echo "Redirected: {$stats['status_breakdown']['redirected']}\n";
echo "JS Page: {$stats['status_breakdown']['js_page']}\n";
echo "Blocked: {$stats['status_breakdown']['blocked']}\n";

echo "\nClicks by Date:\n";
foreach ($stats['clicks_by_date'] as $day) {
    echo "  {$day['date']}: {$day['clicks']}\n";
}
import requests

domain_id = 1

response = requests.get(
    f'https://www.linkvice.com/api/v1/stats/domain/{domain_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={
        'date_from': '2026-03-01',
        'date_to': '2026-03-24',
    }
)
data = response.json()

stats = data['data']
print("Domain-wide Stats")
print(f"Total Clicks: {stats['total_clicks']}")
print(f"Unique Visitors: {stats['unique_visitors']}")
print(f"Redirected: {stats['status_breakdown']['redirected']}")
print(f"JS Page: {stats['status_breakdown']['js_page']}")
print(f"Blocked: {stats['status_breakdown']['blocked']}")

print("\nClicks by Date:")
for day in stats['clicks_by_date']:
    print(f"  {day['date']}: {day['clicks']}")
const domainId = 1;

const params = new URLSearchParams({
    date_from: '2026-03-01',
    date_to: '2026-03-24',
});

const response = await fetch(
    `https://www.linkvice.com/api/v1/stats/domain/${domainId}?${params}`, {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

const stats = data.data;
console.log('Domain-wide Stats');
console.log(`Total Clicks: ${stats.total_clicks}`);
console.log(`Unique Visitors: ${stats.unique_visitors}`);
console.log(`Redirected: ${stats.status_breakdown.redirected}`);
console.log(`JS Page: ${stats.status_breakdown.js_page}`);
console.log(`Blocked: ${stats.status_breakdown.blocked}`);

console.log('\nClicks by Date:');
stats.clicks_by_date.forEach(day => {
    console.log(`  ${day.date}: ${day.clicks}`);
});

Blacklist

GET /api/v1/blacklist

Retrieve a list of all blacklist rules. Optionally filter by rule type.

Query Parameters

ParameterTypeRequiredDescription
type string optional Filter by rule type: uri, ip, or useragent

Response

{
    "success": true,
    "data": [
        {
            "id": 1,
            "rule_type": "ip",
            "pattern": "192.168.1.100",
            "is_regex": false,
            "note": "Spam bot server",
            "created_at": "2025-11-05T09:30:00Z"
        },
        {
            "id": 2,
            "rule_type": "useragent",
            "pattern": "BadBot\\/.*",
            "is_regex": true,
            "note": "Known scraper bot",
            "created_at": "2025-11-10T14:15:00Z"
        },
        {
            "id": 3,
            "rule_type": "uri",
            "pattern": "/wp-admin",
            "is_regex": false,
            "note": "Block WordPress probes",
            "created_at": "2025-12-01T11:00:00Z"
        }
    ]
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/blacklist?type=ip',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

foreach ($response['data'] as $rule) {
    echo "[{$rule['rule_type']}] {$rule['pattern']}";
    if ($rule['note']) {
        echo " - {$rule['note']}";
    }
    echo "\n";
}
import requests

response = requests.get(
    'https://www.linkvice.com/api/v1/blacklist',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={'type': 'ip'}
)
data = response.json()

for rule in data['data']:
    note = f" - {rule['note']}" if rule['note'] else ""
    print(f"[{rule['rule_type']}] {rule['pattern']}{note}")
const response = await fetch('https://www.linkvice.com/api/v1/blacklist?type=ip', {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

data.data.forEach(rule => {
    const note = rule.note ? ` - ${rule.note}` : '';
    console.log(`[${rule.rule_type}] ${rule.pattern}${note}`);
});

POST /api/v1/blacklist

Add a new blacklist rule to block specific URIs, IP addresses, or user agents from accessing your redirects.

Request Body

ParameterTypeRequiredDescription
rule_type string required uri, ip, or useragent
pattern string required The pattern to match. Can be a literal string or regex (if is_regex is true).
is_regex boolean optional Whether the pattern is a regular expression. Defaults to false.
note string optional An optional note describing the reason for this rule.

Response

{
    "success": true,
    "data": {
        "id": 4,
        "rule_type": "ip",
        "pattern": "10.0.0.0/8",
        "is_regex": false,
        "note": "Block internal network",
        "created_at": "2026-03-24T12:00:00Z"
    }
}

Code Examples

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.linkvice.com/api/v1/blacklist',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode([
        'rule_type' => 'ip',
        'pattern'   => '10.0.0.0/8',
        'is_regex'  => false,
        'note'      => 'Block internal network',
    ]),
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo 'Rule created: [' . $response['data']['rule_type'] . '] ' . $response['data']['pattern'];
import requests

response = requests.post(
    'https://www.linkvice.com/api/v1/blacklist',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'rule_type': 'ip',
        'pattern': '10.0.0.0/8',
        'is_regex': False,
        'note': 'Block internal network',
    }
)
data = response.json()

rule = data['data']
print(f"Rule created: [{rule['rule_type']}] {rule['pattern']}")
const response = await fetch('https://www.linkvice.com/api/v1/blacklist', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        rule_type: 'ip',
        pattern: '10.0.0.0/8',
        is_regex: false,
        note: 'Block internal network',
    })
});
const data = await response.json();

const rule = data.data;
console.log(`Rule created: [${rule.rule_type}] ${rule.pattern}`);

DELETE /api/v1/blacklist/{id}

Remove a blacklist rule. Traffic matching this rule will no longer be blocked.

URL Parameters

ParameterTypeRequiredDescription
id integer required The blacklist rule ID to delete

Response

{
    "success": true,
    "data": {
        "message": "Blacklist rule deleted successfully."
    }
}

Code Examples

<?php
$ruleId = 4;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => "https://www.linkvice.com/api/v1/blacklist/{$ruleId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $response['data']['message'];
import requests

rule_id = 4

response = requests.delete(
    f'https://www.linkvice.com/api/v1/blacklist/{rule_id}',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
data = response.json()

print(data['data']['message'])
const ruleId = 4;

const response = await fetch(`https://www.linkvice.com/api/v1/blacklist/${ruleId}`, {
    method: 'DELETE',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
});
const data = await response.json();

console.log(data.data.message);

Error Codes

The API uses standard HTTP status codes to indicate success or failure. Below is a summary of the error codes you may encounter:

CodeNameDescription
400 Bad Request The request body is malformed or missing required fields. Check the error message for details.
401 Unauthorized No API key was provided, or the key is invalid. Ensure the Authorization: Bearer YOUR_API_KEY header is set correctly.
403 Forbidden The API key is valid but does not have permission to perform this action. This can also occur if your account is suspended.
404 Not Found The requested resource does not exist. Verify the ID in your request URL.
429 Too Many Requests You have exceeded the rate limit of 100 requests per minute. Wait for the retry_after period before making another request.
500 Internal Server Error An unexpected error occurred on our end. If this persists, please contact support.

Error Response Format

All errors follow a consistent JSON format:

{
    "error": true,
    "message": "A human-readable description of what went wrong."
}

Webhooks

Coming Soon

Webhooks will allow you to receive real-time notifications when events occur in your account, such as:

  • Redirect click thresholds reached
  • Domain DNS status changes
  • Blacklist rule triggered
  • SSL certificate renewals

Stay tuned for updates. Contact us if you have specific webhook needs.

SDKs & Libraries

Official SDKs are in development and will be released soon. They will provide a convenient wrapper around the REST API with built-in error handling, pagination, and rate limiting.

PHP SDK

Coming Soon

composer require linkvice/php-sdk

Python SDK

Coming Soon

pip install linkvice

Node.js SDK

Coming Soon

npm install @linkvice/sdk

Changelog

v1.0 March 2026 Current
  • Initial API release
  • Full CRUD for domains, redirects, and blacklist rules
  • Statistics endpoints for redirect and domain-level analytics
  • Bearer token authentication
  • Rate limiting at 100 requests/minute per key