Chizga API
Resell digital products (gift cards, game top-ups, subscriptions) from your own system through one JSON API.
Base URL: https://api.chizga.com
All endpoints below are relative to the base URL and return JSON. Every response uses the same envelope:
{
"status": "success" | "error",
"message": "Human readable message",
"data": { ... } | null
}
Use HTTPS only. Requests over plain HTTP are not supported.
Authentication
Every request must include your API key in the X-Api-Key header. Keys are generated from your Chizga account (Account → API). Treat a key like a password: keep it on your server, never in a browser or a mobile app.
X-Api-Key: YOUR_API_KEY
401.Requests with a missing or invalid key return 401. If your server IP is restricted in your account, requests from other IPs return 403.
Response and status codes
| Code | Meaning |
|---|---|
| 200 / 201 | Success. data holds the result. |
| 400 | Bad request: malformed JSON or a missing parameter. |
| 401 | Missing or invalid API key. |
| 403 | Key valid but not allowed (IP restriction, account disabled, product not enabled for your account). |
| 404 | Unknown route, product, variant or order. |
| 409 | An identical request with the same Idempotency-Key is still being processed. Wait 3 seconds and retry. |
| 422 | Validation failed (for example quantity outside 1–50). See message. |
| 429 | Rate limit exceeded. Back off and retry after the time given in Retry-After. |
| 500 / 502 / 503 | Server or supplier problem. Retry later with the same Idempotency-Key for purchases. |
Idempotency for purchases
Send a unique Idempotency-Key header (for example a UUID) with each purchase. If your connection drops, retry with the same key: you get the original response back with the header Idempotent-Replay: true and you are not charged twice.
Rate limits
The default limit is 60 requests per minute per API key / client IP. Every response includes these headers when a limit applies:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per window. |
X-RateLimit-Remaining | Requests left in the current window. |
Retry-After | Seconds to wait (sent with 429). |
Need a higher limit for your volume? Contact support.
Status
Health check. No key needed. Returns 200 when the service is up.
Account & balance
Returns your account profile (name, email, level, currency and status). Does not include secrets.
Returns your available balance and currency. Use it before purchasing.
Catalog
Lists the products available to your account, grouped with their variants and prices in your currency.
| Query | Description |
|---|---|
category_id | Only products in this category. |
lang | en, fr or ar: language of product titles and activation guides. |
Checks that a catalog item is still available and returns its current price. Call it right before a purchase if prices may have changed.
Validates the account input some game products require (for example a player ID) before purchase. Send the product and the fields it asks for.
Products & variants
Lists products with their ids, names and categories.
Lists the variants (denominations or plans) of one product with their ids, sell price and availability. Use the variant id for purchases.
Purchase
Buys a variant. Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
quantity | integer | yes | 1 to 50. |
| account fields | string | when the product asks | For example player ID or account e-mail. Check /api/products/{productId}/variants for the required fields. |
Send an Idempotency-Key header. The response contains the order id(s). Digital codes are delivered in the response when the product is instant, otherwise poll /api/products/order/{orderId}.
Returns the status and delivery data of one order.
Retrieves several orders at once. Body: {"order_ids": ["123", "124"]}. Only orders that belong to your account are returned.
Orders
Lists your orders.
Stock
Shows the stock level of each variant you can sell.
Shows the stock level of one variant. Stock is informational: the purchase call is the final check.
Examples
Check your balance
curl -s https://api.chizga.com/api/balance \
-H "X-Api-Key: $CHIZGA_API_KEY"
Buy one variant
curl -s -X POST https://api.chizga.com/api/products/purchase/123 \
-H "X-Api-Key: $CHIZGA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2b0e-8d4a-4f7e-9a51-2c3d4e5f6a7b" \
-d '{"quantity": 1}'
Buy one variant (PHP 8.1+, cURL extension)
<?php
$key = getenv('CHIZGA_API_KEY');
$ch = curl_init('https://api.chizga.com/api/products/purchase/123');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . $key,
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => json_encode(['quantity' => 1]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($res['status'] ?? '') !== 'success') {
throw new RuntimeException($res['message'] ?? 'Purchase failed');
}
print_r($res['data']);
Buy one variant (Node 18+ or browser server-side)
const res = await fetch('https://api.chizga.com/api/products/purchase/123', {
method: 'POST',
headers: {
'X-Api-Key': process.env.CHIZGA_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({ quantity: 1 }),
});
const json = await res.json();
if (json.status !== 'success') throw new Error(json.message);
console.log(json.data);
Support
Questions, key requests or higher rate limits: support@chizga.com.
Chizga