Create

REST API v1

Kverton API

Dynamic codes, statistics, rendering and webhooks from your own system. REST, JSON, key in a header. Static codes stay free in the browser — the API is for what cannot work without our server.

Getting started

  1. In team settings (Teams → team → API keys) create a key. It is shown once.
  2. Every request carries the header Authorization: Bearer kv_…
  3. Base URL: https://kverton.cz/api/v1
Format
JSON in and out (Content-Type: application/json), UTF-8, timestamps in ISO 8601 (UTC). Version in the path (/v1) — a breaking change gets a new one.
Errors
{"error":{"code":"quota","message":"…"}} · 401 · 403 · 404 · 422 · 429 · 500
Limits
Daily quota by plan (per team; headers X-RateLimit-Quota and X-RateLimit-Remaining) and 120 calls per minute per key. 429 when exceeded.
OpenAPI
/api/v1/openapi.json — machine-readable description for client generators
GET /me Scope: read

Tým, tarif a kvóta

Komu klíč patří, jaký tarif tým má a kolik volání dnes zbývá.

Response

{
    "team": {
        "id": 12,
        "name": "Kavárna U Lípy",
        "plan": "pro"
    },
    "limits": {
        "dynamic_codes": 50,
        "api_calls_per_day": 5000
    },
    "usage": {
        "api_calls_today": 42,
        "dynamic_codes": 7
    }
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/me' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
GET /codes Scope: read

Seznam dynamických kódů

Stránkovaný seznam. Filtr podle skupiny a textu v popisku.

ParameterinType
groupqueryintegerID skupiny
qquerystringHledání v popisku
pagequeryintegerStránka (od 1)
per_pagequeryintegerVelikost stránky (1–200, výchozí 50)

Response

{
    "data": [
        {
            "id": 1234,
            "slug": "a7k2m",
            "short_url": "https://kvrt.net/a7k2m",
            "label": "Podzimní menu",
            "target_url": "https://eshop.cz/menu-podzim",
            "active": true,
            "expires_at": null,
            "group_id": null,
            "password_protected": false,
            "utm": {
                "source": "kverton",
                "medium": "qr",
                "campaign": null
            },
            "safety_state": "clear",
            "created_at": "2026-09-01T10:00:00Z",
            "last_scan_at": "2026-09-03T08:12:00Z"
        }
    ],
    "page": 1,
    "per_page": 50,
    "total": 1
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/codes' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
POST /codes Scope: write

Založit dynamický kód

Vrátí kód včetně krátké adresy. Kód vytiskněte jako QR s obsahem short_url (SVG umí /render).

Request body

{
    "label": "Podzimní menu",
    "target_url": "https://eshop.cz/menu-podzim",
    "expires_at": "2026-12-31",
    "group_id": null,
    "password": null,
    "utm": {
        "source": "kverton",
        "medium": "qr",
        "campaign": "podzim"
    }
}

Response

{
    "id": 1234,
    "slug": "a7k2m",
    "short_url": "https://kvrt.net/a7k2m",
    "label": "Podzimní menu",
    "target_url": "https://eshop.cz/menu-podzim",
    "active": true,
    "expires_at": null,
    "group_id": null,
    "password_protected": false,
    "utm": {
        "source": "kverton",
        "medium": "qr",
        "campaign": null
    },
    "safety_state": "clear",
    "created_at": "2026-09-01T10:00:00Z",
    "last_scan_at": "2026-09-03T08:12:00Z"
}
Samples: curl · PHP · JavaScript · Java
curl -X POST 'https://kverton.cz/api/v1/codes' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…' \
  -H 'Content-Type: application/json' \
  -d '{"label":"Podzimní menu","target_url":"https://eshop.cz/menu-podzim","expires_at":"2026-12-31","group_id":null,"password":null,"utm":{"source":"kverton","medium":"qr","campaign":"podzim"}}'
GET /codes/{id} Scope: read

Detail kódu

Jeden kód včetně pravidel přesměrování.

ParameterinType
id *pathintegerID kódu

Response

{
    "id": 1234,
    "slug": "a7k2m",
    "short_url": "https://kvrt.net/a7k2m",
    "label": "Podzimní menu",
    "target_url": "https://eshop.cz/menu-podzim",
    "active": true,
    "expires_at": null,
    "group_id": null,
    "password_protected": false,
    "utm": {
        "source": "kverton",
        "medium": "qr",
        "campaign": null
    },
    "safety_state": "clear",
    "created_at": "2026-09-01T10:00:00Z",
    "last_scan_at": "2026-09-03T08:12:00Z",
    "rules": [
        {
            "kind": "device",
            "match": "ios",
            "target_url": "https://apps.apple.com/app/x"
        }
    ]
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/codes/1234' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
PATCH /codes/{id} Scope: write

Upravit kód

Změna cíle se zapíše do historie (rollback níže). Pošlete jen pole, která měníte. active=false kód pozastaví.

ParameterinType
id *pathintegerID kódu

Request body

{
    "target_url": "https://eshop.cz/menu-zima",
    "label": "Zimní menu",
    "active": true,
    "expires_at": null,
    "password": "-",
    "utm": {
        "campaign": "zima"
    },
    "rules": [
        {
            "kind": "country",
            "match": "SK",
            "target_url": "https://eshop.sk/menu"
        }
    ]
}

Response

{
    "id": 1234,
    "slug": "a7k2m",
    "short_url": "https://kvrt.net/a7k2m",
    "label": "Podzimní menu",
    "target_url": "https://eshop.cz/menu-podzim",
    "active": true,
    "expires_at": null,
    "group_id": null,
    "password_protected": false,
    "utm": {
        "source": "kverton",
        "medium": "qr",
        "campaign": null
    },
    "safety_state": "clear",
    "created_at": "2026-09-01T10:00:00Z",
    "last_scan_at": "2026-09-03T08:12:00Z"
}
Samples: curl · PHP · JavaScript · Java
curl -X PATCH 'https://kverton.cz/api/v1/codes/1234' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…' \
  -H 'Content-Type: application/json' \
  -d '{"target_url":"https://eshop.cz/menu-zima","label":"Zimní menu","active":true,"expires_at":null,"password":"-","utm":{"campaign":"zima"},"rules":[{"kind":"country","match":"SK","target_url":"https://eshop.sk/menu"}]}'
DELETE /codes/{id} Scope: write

Smazat kód

Nevratné — vytištěný kód přestane fungovat. Zvažte spíš active=false.

ParameterinType
id *pathintegerID kódu

Response

{
    "deleted": true
}
Samples: curl · PHP · JavaScript · Java
curl -X DELETE 'https://kverton.cz/api/v1/codes/1234' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
GET /codes/{id}/stats Scope: read

Statistika skenů

Po dnech (podle historie tarifu), země, regiony, města, jazyky. Bez IP adres — ty neukládáme.

ParameterinType
id *pathintegerID kódu

Response

{
    "total": 166,
    "last_24h": 12,
    "days": [
        {
            "day": "2026-09-02",
            "visits": 11,
            "impressions": 13
        }
    ],
    "countries": [
        {
            "key": "CZ",
            "count": 106
        }
    ],
    "cities": [
        {
            "key": "Praha",
            "count": 61
        }
    ],
    "langs": [
        {
            "key": "cs",
            "count": 120
        }
    ]
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/codes/1234/stats' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
GET /codes/{id}/history Scope: read

Historie cílů

Verze cíle, nejnovější první.

ParameterinType
id *pathintegerID kódu

Response

{
    "data": [
        {
            "id": 501,
            "target_url": "https://eshop.cz/menu-podzim",
            "changed_at": "2026-09-01T10:00:00Z"
        }
    ]
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/codes/1234/history' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
POST /codes/{id}/rollback Scope: write

Vrátit starší cíl

Návrat na verzi z historie; sám se zapíše jako nová verze.

ParameterinType
id *pathintegerID kódu

Request body

{
    "history_id": 501
}

Response

{
    "id": 1234,
    "slug": "a7k2m",
    "short_url": "https://kvrt.net/a7k2m",
    "label": "Podzimní menu",
    "target_url": "https://eshop.cz/menu-podzim",
    "active": true,
    "expires_at": null,
    "group_id": null,
    "password_protected": false,
    "utm": {
        "source": "kverton",
        "medium": "qr",
        "campaign": null
    },
    "safety_state": "clear",
    "created_at": "2026-09-01T10:00:00Z",
    "last_scan_at": "2026-09-03T08:12:00Z"
}
Samples: curl · PHP · JavaScript · Java
curl -X POST 'https://kverton.cz/api/v1/codes/1234/rollback' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…' \
  -H 'Content-Type: application/json' \
  -d '{"history_id":501}'
GET /groups Scope: read

Skupiny kódů

Skupiny týmu s počty kódů.

Response

{
    "data": [
        {
            "id": 3,
            "name": "Akce",
            "codes": 12
        }
    ]
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/groups' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
POST /render Scope: read

Vykreslit QR jako SVG

Obsah → SVG (vektor, čistý vzhled, klidová zóna). Pro dynamický kód pošlete jeho short_url. Formáty: qr, datamatrix, azteccode, rmqr.

Request body

{
    "content": "https://kvrt.net/a7k2m",
    "format": "qr",
    "ecl": "M",
    "module_color": "#302B23",
    "background": "#FFFFFF"
}

Response

{
    "svg": "<svg …>",
    "size": 29
}
Samples: curl · PHP · JavaScript · Java
curl -X POST 'https://kverton.cz/api/v1/render' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…' \
  -H 'Content-Type: application/json' \
  -d '{"content":"https://kvrt.net/a7k2m","format":"qr","ecl":"M","module_color":"#302B23","background":"#FFFFFF"}'
GET /webhooks Scope: read

Webhooky týmu

Adresy, události, stav posledního doručení.

Response

{
    "data": [
        {
            "id": 7,
            "url": "https://example.cz/hooks/kverton",
            "events": [
                "scan",
                "code.updated"
            ],
            "active": true,
            "last_status": 200
        }
    ]
}
Samples: curl · PHP · JavaScript · Java
curl -X GET 'https://kverton.cz/api/v1/webhooks' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
POST /webhooks Scope: write

Přidat webhook

Jen https. Tajemství (secret) se vrátí jednou — ověřujte jím podpis X-Kverton-Signature (sha256=HMAC-SHA256 těla).

Request body

{
    "url": "https://example.cz/hooks/kverton",
    "events": [
        "scan",
        "code.updated"
    ]
}

Response

{
    "id": 7,
    "secret": "3f9c…"
}
Samples: curl · PHP · JavaScript · Java
curl -X POST 'https://kverton.cz/api/v1/webhooks' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.cz/hooks/kverton","events":["scan","code.updated"]}'
DELETE /webhooks/{id} Scope: write

Odebrat webhook

Nedoručené události se zahodí.

ParameterinType
id *pathintegerID webhooku

Response

{
    "deleted": true
}
Samples: curl · PHP · JavaScript · Java
curl -X DELETE 'https://kverton.cz/api/v1/webhooks/1234' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'
POST /webhooks/{id}/test Scope: write

Zkušební událost

Zařadí událost webhook.test; doručí se do minuty.

ParameterinType
id *pathintegerID webhooku

Response

{
    "queued": true
}
Samples: curl · PHP · JavaScript · Java
curl -X POST 'https://kverton.cz/api/v1/webhooks/1234/test' \
  -H 'Authorization: Bearer kv_XXXXXXXX_…'

Webhooks

On an event we POST a JSON body to your https URL. Verify the body signature with the webhook secret (returned once on creation).

POST https://example.cz/hooks/kverton
Content-Type: application/json
X-Kverton-Event: scan
X-Kverton-Delivery: 8812
X-Kverton-Signature: sha256=<HMAC-SHA256(secret, body)>

scanNěkdo načetl dynamický kód (bez IP adresy; země a jazyk podle GeoIP).

{
    "event": "scan",
    "created_at": "2026-09-03T08:12:00Z",
    "data": {
        "code_id": 1234,
        "slug": "a7k2m",
        "country": "CZ",
        "lang": "cs",
        "kind": "visit"
    }
}

code.createdVznikl dynamický kód.

{
    "event": "code.created",
    "created_at": "2026-09-03T08:12:00Z",
    "data": {
        "code_id": 1234,
        "slug": "a7k2m",
        "target_url": "https://eshop.cz/menu"
    }
}

code.updatedZměnil se cíl kódu (i rollbackem).

{
    "event": "code.updated",
    "created_at": "2026-09-03T08:12:00Z",
    "data": {
        "code_id": 1234,
        "target_url": "https://eshop.cz/menu-zima"
    }
}

code.deletedKód byl smazán.

{
    "event": "code.deleted",
    "created_at": "2026-09-03T08:12:00Z",
    "data": {
        "code_id": 1234
    }
}

A delivery counts on a 2xx response. Otherwise we retry after 1 min, 5 min, 30 min, 2 h and 12 h; after 20 consecutive failures the webhook is disabled and shown as such in team settings.

// PHP: verify the signature
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
if (!hash_equals($expected, $_SERVER['HTTP_X_KVERTON_SIGNATURE'] ?? '')) { http_response_code(401); exit; }

Libraries

Official thin libraries: PHP (Composer kverton/kverton-php), JavaScript/TypeScript (npm @kverton/sdk) and an MCP server for AI assistants (npm @kverton/mcp) — all on GitHub under the kverton organisation. For other languages the OpenAPI description generates a client (openapi-generator).