Static QR API დოკუმენტაცია

შექმენით გასაღები, გამოიძახეთ POST /v1/generate ბექენდიდან, გამოიყენეთ SVG საიტზე. ნაბიჯ-ნაბიჯ ინსტრუქცია ქვემოთ.

Static QR API-ის დაკავშირება

სრული გზა: შექმენით გასაღები WebQR-ში, გამოიძახეთ API ბექენდიდან, აიღეთ SVG და ჩასვით საიტზე.

ნაბიჯ-ნაბიჯ ინტეგრაცია

გაიარეთ ნაბიჯები რიგით. SDK არ გჭირდებათ — HTTPS და JSON მხოლოდ სერვერიდან. API გასაღები არ ჩადოთ ბრაუზერის JavaScript-ში და არ ჩააშენოთ აპში.

  1. ანგარიში და ტარიფი

    შედით WebQR-ში ტარიფით, რომელსაც აქვს Static QR API. შეადარეთ თვიური გენერაციები და გასაღებების ლიმიტები ტარიფების გვერდზე.

    ტარიფები და ფასები

  2. შექმენით API გასაღები

    კაბინეტში გახსენით API გასაღებები, შექმენით გასაღები და დაუყოვნებლივ დააკოპირეთ საიდუმლო (ერთხელ ჩანს). სურვილისამებრ შეზღუდეთ IP და ჩართეთ მოთხოვნის ხელმოწერა პროდაქშენისთვის.

    API გასაღებები

  3. შეინახეთ გასაღები სერვერზე

    მოათავსეთ საიდუმლო გარემოს ცვლადებში ან secrets მენეჯერში. ყველა გამოძახება — მხოლოდ ბექენდიდან. გასაღები არ გაუშვათ ფრონტზე და არ ჩააშენოთ აპში.

  4. გამოიძახეთ POST /v1/generate

    თავსართები: X-API-Key და Content-Type: application/json. სხეული: სავალდებულო სტრიქონი data (URL ან ტექსტი) და არასავალდებულო design. ქვემოთ მაგალითებია — ჩაანაცვლეთ ნიმუშის გასაღები საკუთარით.

    https://api.webqr.io/v1/generate
    curl -X POST https://api.webqr.io/v1/generate \
      -H "Content-Type: application/json" \
      -H "X-API-Key: wq_xxxxxxxxxx_your_secret" \
      -d '{
        "data": "https://webqr.io",
        "design": {
            "size": 512,
            "color": "#000000",
            "backgroundColor": "#FFFFFF",
            "styleType": "a7k2m9",
            "eyeType": "r2s4t6",
            "showColorGradient": false
        }
    }'
    <?php
    $ch = curl_init('https://api.webqr.io/v1/generate');
    curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-Key: wq_xxxxxxxxxx_your_secret'
      ],
      CURLOPT_POSTFIELDS => '{
        "data": "https://webqr.io",
        "design": {
            "size": 512,
            "color": "#000000",
            "backgroundColor": "#FFFFFF",
            "styleType": "a7k2m9",
            "eyeType": "r2s4t6",
            "showColorGradient": false
        }
    }',
    ]);
    echo curl_exec($ch);
    const res = await fetch('https://api.webqr.io/v1/generate', {
      method: 'POST',
      headers: {
          "Content-Type": "application/json",
          "X-API-Key": "wq_xxxxxxxxxx_your_secret"
      },
      body: JSON.stringify({
        "data": "https://webqr.io",
        "design": {
            "size": 512,
            "color": "#000000",
            "backgroundColor": "#FFFFFF",
            "styleType": "a7k2m9",
            "eyeType": "r2s4t6",
            "showColorGradient": false
        }
    }),
    });
    const data = await res.json();
    console.log(data);
    import requests
    
    r = requests.post(
      "https://api.webqr.io/v1/generate",
      headers={
          "Content-Type": "application/json",
          "X-API-Key": "wq_xxxxxxxxxx_your_secret"
      },
      json={
          "data": "https://webqr.io",
          "design": {
              "size": 512,
              "color": "#000000",
              "backgroundColor": "#FFFFFF",
              "styleType": "a7k2m9",
              "eyeType": "r2s4t6",
              "showColorGradient": false
          }
      },
    )
    print(r.json())
  5. აიღეთ SVG პასუხიდან

    HTTP 200-ზე აიღეთ data.qr_code (SVG) და data.format ("svg"). usage აჩვენებს კვოტის მრიცხველებს. შეცდომებზე გამოიყენეთ HTTP სტატუსი და error.code, თუ არის.

    პასუხი

  6. გამოიყენეთ SVG საიტზე

    შეინახეთ ფაილი, ატვირთეთ CDN-ზე, ჩასვით inline, მიამაგრეთ წერილს ან გაგზავნეთ ბეჭდვაზე. WebQR შედეგს არ ინახავს — შენახვა და id ინტეგრატორის მხარეს რჩება.

  7. აკონტროლეთ კვოტა და ბილინგი

    GET /v1/usage აბრუნებს მრიცხველებს კვოტის ხარჯვის გარეშე. ტარიფის ლიმიტები — Limits-ში; თუ შეიძლება ჩასმული გენერაციების გადაჭარბება, ჩართეთ overage ბილინგი კაბინეტში.

    Usage · API ლიმიტები · API ბილინგი კაბინეტში

  8. დიზაინი, უსაფრთხოება, შეცდომები

    შემდეგ — დიზაინის ველები, გასაღების დაცვა და შეცდომები. პროდაქშენის ჩეკლისტი:

    • პროდაქშენში შეზღუდეთ გასაღები IP allowlist-ით, თუ სერვერებს სტაბილური egress IP აქვთ.
    • ჩართეთ მოთხოვნის ხელმოწერა (HMAC) გასაღებებისთვის დახურული ქსელის გარეთ.
    • 429-ზე გაითვალისწინეთ Retry-After; 402-ზე ჯერ შეამოწმეთ ბილინგი ან ხარჯვის ლიმიტი.

    სხეულის პარამეტრები · უსაფრთხოება · შეცდომები

ჩამოტვირთვა

POST /generate

POST /v1/generate-ის ცნობარი: ავტორიზაცია, URL, თავსართები და სხეულის ზედა დონე. სრული curl/PHP/JS/Python მაგალითები — ინსტრუქციაში.

ავტორიზაცია

ApiKeyAuth

ყველა მოთხოვნაზე გაგზავნეთ X-API-Key. თუ ხელმოწერა სავალდებულოა — ასევე X-WebQR-Timestamp და X-WebQR-Signature.

მოთხოვნის მეთოდი

POST

მოთხოვნის URL

https://api.webqr.io/v1/generate

ჰედერები

პარამეტრი ტიპი აღწერა
X-API-Key სავალდებულო
string API გასაღების საიდუმლო.
Content-Type სავალდებულო
string გაგზავნეთ application/json, თორემ ხშირად data ვალიდაციის შეცდომა ჩნდება.
X-WebQR-Timestamp
string Unix timestamp (წამები). საჭიროა, თუ გასაღები მოითხოვს ხელმოწერას.
X-WebQR-Signature
string HMAC-SHA256 hex კანონიკური სტრიქონისა. საჭიროა ხელმოწერისას.

პარამეტრები

პარამეტრი ტიპი აღწერა
data სავალდებულო
string დასაშიფრი მონაცემები (URL, ტექსტი, Wi‑Fi და სხვ.). მაქს. 1000 სიმბოლო.
design
object არასავალდებულო design ობიექტი. გამოტოვებული ველები — ნაგულისხმევი.

design-ის სრული ველები (styleType, თვალები, ჩარჩოები, ლოგოები, გრადიენტები) — პარამეტრების სექციაში.

სხეულის პარამეტრები · სრული მაგალითები — ინსტრუქციაში

წარმატებული პასუხი (HTTP 200)

JSON: success, SVG data.qr_code-ში (format svg), content, ნორმალიზებული design და სრული usage ობიექტი.

{
    "success": true,
    "data": {
        "qr_code": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">…</svg>",
        "format": "svg",
        "content": "https://webqr.io",
        "design": {
            "size": 512,
            "color": "#000000",
            "backgroundColor": "#FFFFFF",
            "styleType": "a7k2m9",
            "eyeType": "r2s4t6",
            "showColorGradient": false
        }
    },
    "usage": {
        "period": "2026-05",
        "used_count": 42,
        "included_limit": 200,
        "paid_count": 0,
        "charged_cents": 0,
        "spending_cap_cents": 1000,
        "included_quota_resets_at": "2026-06-01T00:00:00+00:00",
        "what_counts_toward_limit": "Successful POST /v1/generate that returns SVG.",
        "what_does_not_count": "GET /v1/usage, validation errors, and failed generations.",
        "included_quota_note": "Included quota resets at the start of each calendar month.",
        "overage_linear_floor_hint": "Overage is billed per 1000 paid generations (linear floor)."
    }
}

Usage

მხოლოდ წაკითხვა: პერიოდის მრიცხველები, data.items ცარიელი. გენერაციის ლიმიტს არ ხარჯავს.

ავტორიზაცია

ApiKeyAuth

ყველა მოთხოვნაზე გაგზავნეთ X-API-Key. თუ ხელმოწერა სავალდებულოა — ასევე X-WebQR-Timestamp და X-WebQR-Signature.

მოთხოვნის მეთოდი

GET

მოთხოვნის URL

https://api.webqr.io/v1/usage

ჰედერები

პარამეტრი ტიპი აღწერა
X-API-Key სავალდებულო
string API გასაღების საიდუმლო.
X-WebQR-Timestamp
string Unix timestamp (წამები). საჭიროა, თუ გასაღები მოითხოვს ხელმოწერას.
X-WebQR-Signature
string HMAC-SHA256 hex კანონიკური სტრიქონისა. საჭიროა ხელმოწერისას.

თუ გასაღებს სჭირდება ხელმოწერა, GET /v1/usage-ზეც გაგზავნეთ X-WebQR-Timestamp და X-WebQR-Signature (ცარიელი body → SHA-256 of "").

პარამეტრები

არ აქვს query/body პარამეტრები. ავტორიზაცია მხოლოდ ჰედერებით.

მაგალითი

curl -X GET https://api.webqr.io/v1/usage \
  -H "X-API-Key: wq_xxxxxxxxxx_your_secret"
<?php
$ch = curl_init('https://api.webqr.io/v1/usage');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'X-API-Key: wq_xxxxxxxxxx_your_secret',
  ],
]);
echo curl_exec($ch);
const res = await fetch('https://api.webqr.io/v1/usage', {
  headers: {
    'X-API-Key': 'wq_xxxxxxxxxx_your_secret',
  },
});
const data = await res.json();
console.log(data);
import requests

r = requests.get(
  "https://api.webqr.io/v1/usage",
  headers={
    "X-API-Key": "wq_xxxxxxxxxx_your_secret",
  },
)
print(r.json())

აბრუნებს usage snapshot-ს. გენერაციის კვოტას არ ხარჯავს. `usage` იგივეა, რაც POST /v1/generate-ში.

სხეულის პარამეტრები

POST /v1/generate-ის სხეული: სავალდებულო data, არასავალდებულო design. კოდები — მოდულები, თვალები, ჩარჩოები, ლოგოები.

პარამეტრი ტიპი აღწერა
data სავალდებულო
string დასაშიფრი მონაცემები (URL, ტექსტი, Wi‑Fi და სხვ.). მაქს. 1000 სიმბოლო.
design
object არასავალდებულო design ობიექტი. გამოტოვებული ველები — ნაგულისხმევი.
design.size
integer ზომა პიქსელებში (100–2048).
design.color
string მოდულების ფერი #RRGGBB.
design.backgroundColor
string ფონის ფერი #RRGGBB.
design.borderColor
string გარე თვალების ფერი #RRGGBB.
design.centerColor
string შიდა თვალების ფერი #RRGGBB.
design.markerOutColor
string borderColor-ის ალიასი.
design.markerInColor
string centerColor-ის ალიასი.
design.styleType
string მოდულის ფორმის კოდი (იხ. მოდულის კოდები).
design.eyeType
string გარე თვალის კოდი (იხ. გარე თვალები).
design.eyeInnerType
string შიდა თვალის კოდი (იხ. შიდა თვალები).
design.showColorGradient
boolean გრადიენტი მოდულებზე.
design.unifiedGradient
boolean ერთი გრადიენტი მოდულებსა და თვალებზე.
design.showAllColorGradient
boolean unifiedGradient-ის ალიასი.
design.showEyeGradient
boolean გრადიენტი თვალებზე.
design.styleColorGradient
string მოდულის გრადიენტის მიმართულება.
design.eyeGradientStyle
string თვალების გრადიენტის მიმართულება.
design.fromColor
string მოდულის გრადიენტის დასაწყისი #RRGGBB.
design.toColor
string მოდულის გრადიენტის დასასრული #RRGGBB.
design.eyeFromColor
string თვალების გრადიენტის დასაწყისი #RRGGBB.
design.eyeToColor
string თვალების გრადიენტის დასასრული #RRGGBB.
design.transparent
boolean გამჭვირვალე ფონი.
design.title
string title მეტამონაცემები (მაქს. 100).
design.frameType
string ჩარჩოს კოდი Frames-დან. გამოტოვეთ ველი ან დატოვეთ ცარიელი, თუ ჩარჩო არ გჭირდებათ.
design.frameColor
string ჩარჩოს ფერი #RRGGBB.
design.showFrameGradient
boolean ჩარჩოს გრადიენტი.
design.frameGradientFrom
string ჩარჩოს გრადიენტის დასაწყისი #RRGGBB.
design.frameGradientTo
string ჩარჩოს გრადიენტის დასასრული #RRGGBB.
design.frameGradientStyle
string ჩარჩოს გრადიენტის მიმართულება.
design.frameGradientTextColor
string წარწერის ფერი ჩარჩოს გრადიენტზე.
design.textColor
string ჩარჩოს ტექსტის ფერი #RRGGBB.
design.textUnderQr
string წარწერა QR-ის ქვეშ (მაქს. 40; ჩარჩოებთან).
design.roundedCorners
boolean QR ტილოს კუთხეების მომრგვალება.
design.cornerRadius
integer რადიუსი px-ში (0–120).
design.logo
string რეკომენდებულია: პრესეტის კოდი (Lxxxxx) ან საჯარო HTTPS URL. Advanced: data URI; ინტეგრაციებისთვის უპირატესობა HTTPS-ს.
design.selectedLogo
string პრესეტის კოდი ან HTTPS URL.
design.logoBackgroundEnabled
boolean ლოგოს ქვედა ფონი.
design.loadLogoBackgroundOut
string ლოგოს ფონის ფერი #RRGGBB (Lxxxxx).
design.loadLogoBackgroundIn
string ლოგოს იკონის ფერი #RRGGBB (Lxxxxx).

პასუხის ფორმატი მხოლოდ SVG (data.format: "svg"). PNG/PDF ამ API-ით მიუწვდომელია.

მოდულის კოდები

გამოიყენეთ კოდის სტრიქონი design.styleType, eyeType, eyeInnerType, frameType ან logo-ში.

  • a7k2m9 კვადრატი
  • b3n5p1 კვადრატი ამოჭრით
  • c8q4r6 სკვირკლი
  • d1s7t9 მომრგვალო დაკავშირებული
  • e6u2v4 მკვეთრი დაკავშირებული
  • f9w5x7 წერტილი
  • g2y8z0 მომრგვალო წერტილი
  • h4a6b8 წერტილი (ჰორიზონტალი)
  • i0c2d4 წერტილი (ვერტიკალი)
  • j6e8f0 რომბი
  • k2g4h6 ვარსკვლავი
  • l8i0j2 პიქსელური ვარსკვლავი
  • m4k6l8 გული
  • n0o2p4 პლუსი
  • p6q8r0 მომრგვალო პლუსი
  • q1r3s5 მომრგვალო კვადრატი
  • s1r3s5 მომრგვალო კვადრატი

გარე იზომები (eyeType)

გამოიყენეთ კოდის სტრიქონი design.styleType, eyeType, eyeInnerType, frameType ან logo-ში.

  • r2s4t6 კვადრატი
  • u8v0w2 მომრგვალო კვადრატი
  • x4y6z8 წრე
  • a1b3c5 რომბი
  • d7e9f1 D-ფორმა
  • g3h5i7 D-ფორმა ინვერსია
  • j9k1l3 ფოთოლი
  • m5n7o9 ფოთოლი წრით
  • p1q3r5 ფოთოლი წრით (ბრუნვა)
  • s7t9u1 ფოთოლი (ვარიანტი)
  • v3w5x7 კვადრატი წრით
  • y9z1a3 მომრგვალო წვეტიანი
  • b5c7d9 სკვირკლი
  • e1f3g5 წვეთი

შიდა იზომები (eyeInnerType)

გამოიყენეთ კოდის სტრიქონი design.styleType, eyeType, eyeInnerType, frameType ან logo-ში.

  • h7i9j1 კვადრატი
  • k3l5m7 სკვირკლი
  • n9o1p3 წრე
  • q5r7s9 დახრილი კვადრატი
  • t1u3v5 D-ფორმა
  • w7x9y1 D-ფორმა ინვერსია
  • z3a5b7 ფოთოლი
  • c9d1e3 ვარსკვლავი
  • f5g7h9 რომბი
  • i1j3k5 X-ფორმა
  • l7m9n1 პლუსი
  • o3p5q7 სამყურა
  • r9s1t3 მომრგვალო X
  • u5v7w9 გული

ჩარჩოები (frameType)

n0f1r2 = ჩარჩოს გარეშე (იგივეა, რაც frameType-ის გამოტოვება ან ცარიელი სტრიქონი). t7r8d9 — სქელი მომრგვალო ჩარჩო წარწერის გარეშე. სხვა ჩარჩოებზე წარწერა შეიძლება იყოს ზოლში; textUnderQr არასავალდებულოა — წინააღმდეგ შემთხვევაში სერვერი ნაგულისხმევ ტექსტს დაამატებს.

  • n0f1r2 ჩარჩოს გარეშე
  • t7r8d9 სქელი მომრგვალო ჩარჩო
  • l4b5t6 ლეიბლი ქვემოთ
  • b3n4t5 ბანერი ზემოთ
  • b7b8d9 ბეჯი ქვემოთ
  • b5d6t7 ბეჯი ზემოთ
  • b9b0t1 ზოლი ქვემოთ
  • b2t3p4 ზოლი ზემოთ
  • w4t5p6 ფართო ზოლი ზემოთ
  • w1d2b3 ფართო ზოლი ქვემოთ
  • p0l1b2 აბი ქვემოთ
  • p8t9p0 აბი ზემოთ
  • s6b7g8 პაკეტი

მზა ლოგოები (design.logo)

იგივე პრესეტები, რაც კონსტრუქტორში: გადააწოდეთ კოდი (La1b2c…) design.logo ან design.selectedLogo-ში. პრესეტებისთვის — loadLogoBackgroundOut და loadLogoBackgroundIn (#RRGGBB). ასევე https-URL და data:image/…; logoBackgroundEnabled — ფონი საკუთარი ლოგოსთვის. დეტალები: docs/qr-logos.md რეპოზიტორიაში.

  • La1b2c Facebook
  • Ld3e4f Messenger
  • Lg5h6i Instagram
  • Lj7k8l LinkedIn
  • Lm9n0o YouTube
  • Ls3t4u Phone
  • Lv5w6x Telegram
  • Ly7z8a SMS
  • Lb9c0d Email
  • Le1f2g Wi‑Fi
  • Lh3i4j Restaurant
  • Lk5l6m Location
  • Ln7o8p Gallery
  • Lq9r0s Profile
  • Lt1u2v WhatsApp
  • Lw3x4y Link
  • Lz5a6b Promo
  • Lc7d8e Lock

ლოგოს ველები

logo და selectedLogo სინონიმებია. loadLogoBackground* მოქმედებს მხოლოდ Lxxxxx პრესეტებზე.

  • design.logo
  • design.selectedLogo
  • design.loadLogoBackgroundOut
  • design.loadLogoBackgroundIn
  • design.logoBackgroundEnabled

გრადიენტის მიმართებები

იგივე სახელები styleColorGradient და eyeGradientStyle ველებში.

  • horizontal
  • vertical
  • diagonal
  • inverse_diagonal
  • radial

API ლიმიტები

თვიური ჩასმული გენერაციები, გასაღებები და rate limit ტარიფის მიხედვით. პროდუქტის ფასები — ტარიფების გვერდზე.

ტარიფების მიხედვით

ჩართული წარმატებული გენერაციები კალენდარულ თვეში, აქტიური გასაღებები და rate limit ტარიფის მიხედვით.

ტარიფი ჩართული / თვე აქტიური გასაღებები Rate limit
Starter 200 გენერაცია მდე 1 30/წთ · burst 2/წმ
Premium 5000 გენერაცია მდე 5 120/წთ · burst 8/წმ
Business 25000 გენერაცია მდე 15 300/წთ · burst 15/წმ
Enterprise 50000 გენერაცია მდე 30 600/წთ · burst 25/წმ

გჭირდებათ მეტი ან ინდივიდუალური პირობები? დაგვიკავშირდით — ლიმიტებსა და პირობებს შეარჩევთ კონკრეტული შემთხვევისთვის.

კვოტა კალენდარული თვის დასაწყისში ახლდება. გასაღების ლიმიტი ავტორიზაციის შემდეგ. გასაღებამდე — IP ლიმიტი.

რა ითვლება და რა არა

  • მხოლოდ წარმატებული POST /v1/generate SVG პასუხით იძლევა +1 used_count-ზე.
  • ჩართული ლიმიტი განახლდება ყოველ კალენდარულ თვეს; გამოუყენებელი არ გადადის.
  • GET /v1/usage კვოტას არ ხარჯავს — დაფებისა და ალერტებისთვის.
  • გასაღებით: ლიმიტი გასაღებზე (წუთში + burst). გასაღების გარეშე / არასწორი: დაახლოებით 45 მოთხოვნა/წთ IP-ზე.
  • API არ ინახავს QR-ს WebQR ბიბლიოთეკაში. SVG და საკუთარი id შეინახეთ თავად.
  • წარმატებული პასუხი მხოლოდ SVGა; PNG/PDF ენდპოინტი არ არის.
  • ჩართული კვოტის შემდეგ overage ≈ $2 / 1000 გენერაცია, თუ ჩართულია კაბინეტში. ნაგულისხმევი spending cap ≈ $10/თვე.

დაკავშირებული

როგორ ითვლება კვოტა

used_count იზრდება მხოლოდ წარმატებული POST /v1/generate-ით SVG-ით. GET /v1/usage კვოტას არ ხარჯავს. ველების სია ქვემოთ — როგორც usage ობიექტში.

  • ერთი წარმატებული გენერაცია = +1 used_count. ვალიდაცია და 4xx/5xx არ ითვლება.
  • GET /v1/usage — დაფებისა და ალერტებისთვის, გახარჯვის გარეშე.
  • თუ overage დაკავშირებულია და სტატუსი payment_failedა — მთელი Static QR API დაბლოკილია ჩართული კვოტითურთ.
  • ტექსტური hints ადამიანებისთვისაა; ავტომატიზაცია — რიცხვებით და error.code-ით.

`usage` ობიექტის ველები generate და usage პასუხებში:

  • period
  • used_count
  • included_limit
  • paid_count
  • charged_cents
  • spending_cap_cents
  • included_quota_resets_at
  • what_counts_toward_limit
  • what_does_not_count
  • included_quota_note
  • overage_linear_floor_hint

API ბილინგი კაბინეტში

ჩვეულებრივი HTTP შეცდომები

მხოლოდ HTTP სტატუსი საკმარისი არაა — JSON ფორმა ფენის მიხედვით იცვლება. Gateway ხშირად აბრუნებს `{ "error": "…" }`. კვოტა/ბილინგი — `{ "success": false, "error": { "code", "message" } }`. ვალიდაცია — `{ "errors": {…} }`. 500 შეიძლება იყოს `{ "success": false, "message" }` უკოდოდ. ტექსტის ენა შეიძლება იყოს EN/RU — მანქანური ლოგიკისთვის გამოიყენეთ სტატუსი და `error.code`.

HTTP error.code მნიშვნელობა
401 X-API-Key ჰედერი არ არის.
401 არასწორი, გაუქმებული ან ვადაგასული გასაღები.
401 ხელმოწერა აკლია/არასწორია, ან სავალდებულო ხელმოწერისას არასწორი/ვადაგასულია.
403 კლიენტის IP არ არის ამ გასაღების allowlist-ში.
402 billing_payment_required Overage ბილინგი payment_failed სტატუსშია — მთელი Static QR API დაბლოკილია, მათ შორის ჩართული კვოტა, სანამ გადახდა არ გამოსწორდება.
402 free_limit_reached თვიური ჩართული კვოტა ამოწურულია და overage ბილინგი არ არის დაკავშირებული.
402 spending_cap_reached Overage-ის თვიური spending cap მიღწეულია.
422 ვალიდაციის შეცდომა (ტიპები, უცნობი სტილის კოდები, HEX, ველების სიგრძე, ლოგოს URL და ა.შ.).
429 rate_limited ძალიან ბევრი მოთხოვნა IP-დან ან გასაღებიდან. სცადეთ მოგვიანებით; გაითვალისწინეთ Retry-After.
500 გენერაციის შეცდომა — სცადეთ მოგვიანებით.

JSON ფორმები სტატუსების მიხედვით

ტიპური პასუხები. ტექსტი შეიძლება განსხვავდებოდეს; სტაბილური სიგნალია `error.code`, როცა არის.

{
    "error": "Invalid API key."
}
{
    "success": false,
    "error": {
        "code": "billing_payment_required",
        "message": "API billing payment failed or is overdue."
    }
}
{
    "message": "The data field is required.",
    "errors": {
        "data": [
            "The data field is required."
        ]
    }
}
{
    "success": false,
    "error": {
        "code": "rate_limited",
        "message": "Too many requests. Try again later."
    }
}
{
    "success": false,
    "message": "QR code generation failed. Please try again later."
}

უსაფრთხოება პროდაქშენში

API გასაღები განულებას არ უნდა გადასცეთ კლიენტს — იგი სერვერული საიდუმლოა.

  • გასაღები შეინახეთ მხოლოდ სერვერზე — არა ბრაუზერში, მობილურ აპში ან საჯარო რეპოში.
  • api.* გამოიძახეთ ბექენდიდან. Static QR API-სთვის ბრაუზერის CORS არ არის განკუთვნილი — გამოიყენეთ სერვერი ან API კონსტრუქტორი კაბინეტში.
  • ოფციონალურად შეზღუდეთ გასაღები სერვერის IP-ებით. ცარიელი allowlist = ნებისმიერი IP.
  • ოფციონალურად ჩართეთ HMAC კაბინეტში. მაშინ ორივე ჰედერი საჭიროა ყველა მარშრუტზე — მათ შორის GET /v1/usage.

HMAC ხელმოწერა (თუ გასაღებზე ჩართულია)

ხელმოწერის სტრიქონი (UTF-8)

1714412345
POST
/v1/generate
<sha256_hex_ნედლი_სხეულისა>

GET-ისთვის სხეული ცარიელია. ბოლო ხაზი — ცარიელი სტრიქონის SHA-256:

1714412345
GET
/v1/usage
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

HMAC საიდუმლო: 40 სიმბოლო მეორე «_»-ის შემდეგ. ხელმოწერა lowercase hex. Timestamp: Unix წამები, ±5 წუთი. Body SHA-256 უნდა ემთხვეოდეს ზუსტ ბაიტებს. Path უნდა ემთხვეოდეს URL path-ს.

ხელმოწერის გამოთვლა

საიდუმლო — 40 სიმბოლო მეორე «_»-ის შემდეგ. ხელმოწერა — lowercase hex HMAC-SHA256. დროის დასაშვები ცდომილება: ±5 წუთი.

# Build signature on your server, then attach headers to curl
TS=$(date +%s)
BODY='{"data":"https://webqr.io"}'
BODY_HASH=$(printf %s "$BODY" | openssl dgst -sha256 -hex | awk '{print $2}')
SECRET="${API_KEY##*_}"  # 40 chars after the second underscore
CANON=$(printf '%s\nPOST\n/v1/generate\n%s' "$TS" "$BODY_HASH")
SIG=$(printf %s "$CANON" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')
curl -X POST https://api.webqr.io/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-WebQR-Timestamp: $TS" \
  -H "X-WebQR-Signature: $SIG" \
  -d "$BODY"
<?php
$apiKey = getenv('WEBQR_API_KEY');
$secret = substr($apiKey, strrpos($apiKey, '_') + 1);
$ts = (string) time();
$body = json_encode(['data' => 'https://webqr.io'], JSON_UNESCAPED_SLASHES);
$canonical = $ts . "\nPOST\n/v1/generate\n" . hash('sha256', $body);
$signature = hash_hmac('sha256', $canonical, $secret);

$ch = curl_init('https://api.webqr.io/v1/generate');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: ' . $apiKey,
    'X-WebQR-Timestamp: ' . $ts,
    'X-WebQR-Signature: ' . $signature,
  ],
  CURLOPT_POSTFIELDS => $body,
]);
echo curl_exec($ch);
import crypto from 'node:crypto';

const apiKey = process.env.WEBQR_API_KEY;
const secret = apiKey.slice(apiKey.lastIndexOf('_') + 1);
const ts = String(Math.floor(Date.now() / 1000));
const body = JSON.stringify({ data: 'https://webqr.io' });
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const canonical = `${ts}\nPOST\n/v1/generate\n${bodyHash}`;
const signature = crypto.createHmac('sha256', secret).update(canonical).digest('hex');

const res = await fetch('https://api.webqr.io/v1/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': apiKey,
    'X-WebQR-Timestamp': ts,
    'X-WebQR-Signature': signature,
  },
  body,
});
console.log(await res.json());
import hashlib, hmac, json, os, time, urllib.request

api_key = os.environ["WEBQR_API_KEY"]
secret = api_key.rsplit("_", 1)[-1]
ts = str(int(time.time()))
body = json.dumps({"data": "https://webqr.io"}, separators=(",", ":"))
body_hash = hashlib.sha256(body.encode()).hexdigest()
canonical = f"{ts}\nPOST\n/v1/generate\n{body_hash}"
signature = hmac.new(secret.encode(), canonical.encode(), hashlib.sha256).hexdigest()

req = urllib.request.Request("https://api.webqr.io/v1/generate", data=body.encode(), method="POST")
req.add_header("Content-Type", "application/json")
req.add_header("X-API-Key", api_key)
req.add_header("X-WebQR-Timestamp", ts)
req.add_header("X-WebQR-Signature", signature)
print(urllib.request.urlopen(req).read().decode())

მოთხოვნა ხელმოწერის ჰედერებით

curl -X POST https://api.webqr.io/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wq_xxxxxxxxxx_your_secret" \
  -H "X-WebQR-Timestamp: 1714412345" \
  -H "X-WebQR-Signature: 64_hex_chars_lowercase_hmac_sha256_placeholder_do_not_use_as_is" \
  -d '{
    "data": "https://webqr.io",
    "design": {
        "size": 512,
        "color": "#000000",
        "backgroundColor": "#FFFFFF",
        "styleType": "a7k2m9",
        "eyeType": "r2s4t6",
        "showColorGradient": false
    }
}'
<?php
$ch = curl_init('https://api.webqr.io/v1/generate');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wq_xxxxxxxxxx_your_secret',
    'X-WebQR-Timestamp: 1714412345',
    'X-WebQR-Signature: 64_hex_chars_lowercase_hmac_sha256_placeholder_do_not_use_as_is'
  ],
  CURLOPT_POSTFIELDS => '{
    "data": "https://webqr.io",
    "design": {
        "size": 512,
        "color": "#000000",
        "backgroundColor": "#FFFFFF",
        "styleType": "a7k2m9",
        "eyeType": "r2s4t6",
        "showColorGradient": false
    }
}',
]);
echo curl_exec($ch);
const res = await fetch('https://api.webqr.io/v1/generate', {
  method: 'POST',
  headers: {
      "Content-Type": "application/json",
      "X-API-Key": "wq_xxxxxxxxxx_your_secret",
      "X-WebQR-Timestamp": "1714412345",
      "X-WebQR-Signature": "64_hex_chars_lowercase_hmac_sha256_placeholder_do_not_use_as_is"
  },
  body: JSON.stringify({
    "data": "https://webqr.io",
    "design": {
        "size": 512,
        "color": "#000000",
        "backgroundColor": "#FFFFFF",
        "styleType": "a7k2m9",
        "eyeType": "r2s4t6",
        "showColorGradient": false
    }
}),
});
const data = await res.json();
console.log(data);
import requests

r = requests.post(
  "https://api.webqr.io/v1/generate",
  headers={
      "Content-Type": "application/json",
      "X-API-Key": "wq_xxxxxxxxxx_your_secret",
      "X-WebQR-Timestamp": "1714412345",
      "X-WebQR-Signature": "64_hex_chars_lowercase_hmac_sha256_placeholder_do_not_use_as_is"
  },
  json={
      "data": "https://webqr.io",
      "design": {
          "size": 512,
          "color": "#000000",
          "backgroundColor": "#FFFFFF",
          "styleType": "a7k2m9",
          "eyeType": "r2s4t6",
          "showColorGradient": false
      }
  },
)
print(r.json())

«Require signed requests» ჩართვისას ორივე ჰედერი სავალდებულოა ყოველ მოთხოვნაზე.

ხშირად დასმული კითხვები

შეიძლება უფასო ტარიფზე API-ით სარგებლობა?

დიახ. Starter უკვე მოიცავს Static QR API-ს: 200 წარმატებული გენერაცია კალენდარულ თვეში; Premium — 5000, Business — 25000. ცალკე API-გამოწერა არ არის. საჭიროების შემთხვევაში overage ჩაირთვება კაბინეტში.

რამდენი გენერაცია მაქვს თვეში?

ჩართული წარმატებული გენერაციები კალენდარულ თვეში: Starter 200, Premium 5000, Business 25000, Enterprise 50000. გამოუყენებელი არ გადადის. დეტალები — ამ გვერდის ლიმიტების სექციაში.

სად შევქმნა API გასაღები?

რეგისტრაციის შემდეგ გახსენით API გასაღებები კაბინეტში, შექმენით გასაღები და ერთხელ დააკოპირეთ საიდუმლო (მხოლოდ შექმნისას ჩანს). გამოიყენეთ მხოლოდ ბექენდზე — არა ბრაუზერის JS-ში და არა მობაილ აპის ბინარში.

შეიძლება API-ის გამოძახება ბრაუზერიდან ან მობაილ აპიდან?

არა. გასაღები სერვერზე უნდა დარჩეს. გამოიძახეთ POST /v1/generate ბექენდიდან, კლიენტს კი მიაწოდეთ მზა SVG ან მისი ბმული.

რას იღებთ წარმატებულ პასუხში? WebQR ინახავს თუ არა ყოველ QR-ს?

JSON-ში მოდის SVG data.qr_code-ში, იგივე content/design და usage კვოტისთვის. API stateless არის: გამოძახება თავისთავად ბიბლიოთეკაში არ ინახება და გრძელვადიან ID-ს არ აბრუნებს — SVG შეინახეთ ინტეგრატორის მხარეს.

რა ფორმატში პასუხობს API?

მხოლოდ SVG (data.format = "svg"). Static QR API-ს PNG/PDF ენდპოინტი არ აქვს — საჭიროების შემთხვევაში კონვერტაცია ინტეგრატორის მხარეს გააკეთეთ.

რა ხდება ჩართული კვოტის ამოწურვისას?

ჩართეთ API ბილინგი კაბინეტში. Overage დაახლოებით $2 / 1000 წარმატებულ გენერაციაზეა, ყოველთვიური ხარჯის ლიმიტით (ნაგულისხმევი დაახლოებით $10). ბილინგის გარეშე კვოტის ზემოთ მოთხოვნები უარყოფილია.

შეიძლება API-ითაც და საიტის კონსტრუქტორითაც?

დიახ. API სერვერული ინტეგრაციებისთვისაა; კონსტრუქტორი და კაბინეტი — ხელით სამუშაოდ. დიზაინის კოდები საერთოა, მაგრამ API გამოძახება თავისთავად ბიბლიოთეკის ჩანაწერს არ ქმნის.

მზად ხართ QR-ის გენერაციისთვის სერვერიდან?

დარეგისტრირდით, შექმენით API გასაღები კაბინეტში და გაიარეთ ინსტრუქცია ამ გვერდზე.

Starter — სამუდამოდ უფასოდ საკრედიტო ბარათის გარეშე გაუქმება ნებისმიერ დროს