API Documentation

All APIs return UTF-8 JSON. Authentication via X-API-Key or Authorization: Bearer <api_key>.

Base URL: https://tapy.cc

POST /api/v1/shorten

Create a short link for the API key owner.

Body JSON

{"url":"https://example.com","title":"Landing","campaign":"spring-2026","custom_code":"promo26"}

Plan rule: on Free plan, custom_code is ignored and a random short code is generated automatically.

Response 201

{"short_code":"Ab3xK9q","short_url":"https://tapy.cc/Ab3xK9q","destination_url":"https://example.com"}

GET /api/v1/links

Returns all links created by the API key owner.

Response 200

{"data":[{"short_code":"abc123","destination_url":"https://example.com","campaign":"spring-2026","clicks":10}]}

GET /api/v1/stats/{code}

Retrieve stats and metadata for one link.

Response 200

{"data":{"short_code":"abc123","destination_url":"https://example.com","campaign":"spring-2026","clicks":10,"is_active":1}}

Standard errors

  • 401 Missing or invalid API key
  • 404 Link not found
  • 409 Short code in use / plan limit reached
  • 422 Invalid URL

Quick cURL

curl -X POST "https://tapy.cc/api/v1/shorten" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d "{\"url\":\"https://example.com\",\"campaign\":\"spring-2026\"}"

PHP smoke example

Full smoke-style example (replace placeholder with your API key).

<?php

declare(strict_types=1);

$baseUrl = 'https://tapy.cc';
$apiKey = 'YOUR_API_KEY'; // replace with your key

function request_json(string $method, string $url, string $apiKey, ?array $payload = null): array
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);

    $headers = [
        'Accept: application/json',
        'X-API-Key: ' . $apiKey,
    ];

    if ($payload !== null) {
        $headers[] = 'Content-Type: application/json';
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_SLASHES));
    }

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $raw = curl_exec($ch);
    $status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);

    return [$status, json_decode((string) $raw, true) ?: ['raw' => $raw]];
}

[$createStatus, $createBody] = request_json('POST', $baseUrl . '/api/v1/shorten', $apiKey, [
    'url' => 'https://example.com',
    'title' => 'Landing',
    'campaign' => 'spring-2026',
]);

echo "POST /api/v1/shorten => HTTP {$createStatus}\n";
print_r($createBody);

if (!isset($createBody['short_code'])) {
    exit(1);
}

$code = (string) $createBody['short_code'];

[$statsStatus, $statsBody] = request_json('GET', $baseUrl . '/api/v1/stats/' . rawurlencode($code), $apiKey);
echo "GET /api/v1/stats/{$code} => HTTP {$statsStatus}\n";
print_r($statsBody);

[$linksStatus, $linksBody] = request_json('GET', $baseUrl . '/api/v1/links', $apiKey);
echo "GET /api/v1/links => HTTP {$linksStatus}\n";
print_r($linksBody);

Output atteso

Indicative CLI output when the API sequence succeeds.

POST /api/v1/shorten => HTTP 201
Array
(
    [short_code] => Ab3xK9q
    [short_url] => https://tapy.cc/Ab3xK9q
    [destination_url] => https://example.com
)

GET /api/v1/stats/Ab3xK9q => HTTP 200
Array
(
    [data] => Array
        (
            [short_code] => Ab3xK9q
            [destination_url] => https://example.com
            [campaign] => spring-2026
            [clicks] => 0
            [is_active] => 1
        )
)

GET /api/v1/links => HTTP 200
Array
(
    [data] => Array
        (
            [0] => Array
                (
                    [short_code] => Ab3xK9q
                    [destination_url] => https://example.com
                    [campaign] => spring-2026
                    [clicks] => 0
                )
        )
)