Gramix API v1
Використовуйте цей посібник як контракт під час розробки серверної інтеграції.
Загальна інформація
Публічний API дозволяє отримувати баланс, поповнювати гаманець і купувати Telegram Stars, Telegram Premium та GRAM.
Base URL
https://api.gramix.io/api/v1Формат даних
- Тіло запиту та відповіді API використовують application/json.
- Грошові значення передаються рядками з чотирма знаками після коми. Для точних розрахунків використовуйте decimal-типи або зберігайте значення як рядки.
- Дати у webhook передаються у форматі ISO 8601. Не покладайтеся на невідомі поля JSON.
Список методів
| Метод | Endpoint | Призначення | HTTP-код |
|---|---|---|---|
GET | /api/v1/wallets/balance | Повертає поточний баланс. | 200 |
POST | /api/v1/wallets/balance | Створює або повертає address і memo для поповнення в мережі TON. | 201 |
POST | /api/v1/purchase/stars | Купує від 50 до 1 000 000 Telegram Stars для вказаного Telegram username. | 201 |
POST | /api/v1/purchase/premium/{duration} | Купує Telegram Premium на 3, 6 або 12 місяців. | 201 |
POST | /api/v1/purchase/gram | Купує та надсилає від 1 до 10 000 GRAM вказаному Telegram-одержувачу. | 201 |
Авторизація
Усі методи потребують активного API-ключа, переданого в HTTP-заголовку x-api-key.
x-api-key: YOUR_API_KEYПриклад запиту
curl --request GET 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'Якщо заголовок відсутній, ключ невірний, відкликаний або неактивний, API повертає 401 Unauthorized.
Загальний формат відповіді
Успішна відповідь
Успішна відповідь містить statusCode і data. Для POST-запитів API повертає HTTP-код 201.
{
"statusCode": 200,
"data": {}
}Відповідь з помилкою
Відповідь з помилкою містить statusCode і зрозуміле для людини message. Клієнтська логіка має насамперед спиратися на HTTP-код.
{
"statusCode": 400,
"message": "Idempotency-Key header is required"
}Типові помилки
| HTTP-код | message |
|---|---|
400 | Bad Request |
401 | Unauthorized |
403 | Insufficient balance |
404 | Not Found |
405 | Method Not Allowed |
500 | Internal server error |
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"statusCode": 401,
"message": "Unauthorized"
}HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"statusCode": 403,
"message": "Insufficient balance"
}Загальні схеми
PaymentCurrency
paymentCurrency визначає баланс, з якого буде сплачено покупку. Допустимі лише gram і usdt у нижньому регістрі.
type PaymentCurrency = "gram" | "usdt";RecipientName
recipientName — Telegram username одержувача без @. Довжина від 5 до 32 символів; дозволені малі латинські літери, цифри та _.
durov
user_123
telegram_user@durov
User123
1username
user-name
abcPurchaseRequestBase
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt"
}PurchaseResponse
Усі методи покупки повертають orderId, status і idempotencyKey. Нове замовлення зазвичай має статус processing.
{
"statusCode": 201,
"data": {
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "processing",
"idempotencyKey": "order_20260713_0001"
}
}type OrderStatus = "created" | "processing" | "completed" | "failed" | "canceled";Ідемпотентність покупок
Усі методи /purchase/* потребують заголовка idempotency-key завдовжки від 8 до 64 символів.
idempotency-key: UNIQUE_REQUEST_KEY- Дозволені латинські літери, цифри, _ і -. Ключ має бути унікальним у межах API-ключа.
- У разі мережевої помилки повторіть той самий запит із тим самим ключем. Для нової покупки використовуйте новий ключ.
order_20260713_0001
01J2Y5VN7CV8ZQ7DPZ9J0P6E4M
client-req-12345678Можливі помилки
{
"statusCode": 400,
"message": "Idempotency-Key header is required"
}{
"statusCode": 400,
"message": "Idempotency-Key must be between 8 and 64 characters"
}{
"statusCode": 400,
"message": "Idempotency-Key contains invalid characters"
}Гаманці
GET /api/v1/wallets/balance
Повертає поточний баланс.
| Заголовки | Обов'язково | Опис |
|---|---|---|
x-api-key | так | Авторизація |
Accept | ні | application/json |
Приклад запиту
curl --request GET 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'{
"statusCode": 200,
"data": {
"gram": "14.2500",
"usdt": "125.5000"
}
}POST /api/v1/wallets/balance
Створює або повертає address і memo для поповнення в мережі TON.
| Заголовки | Обов'язково | Опис |
|---|---|---|
x-api-key | так | Авторизація |
Accept | ні | application/json |
curl --request POST 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'{
"statusCode": 201,
"data": {
"address": "UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"memo": "a1b2c3d4e5f6g7h8"
}
}Зарахування виконується асинхронно. GRAM зараховується на gram, USDT у мережі TON — на usdt.
Рекомендований сценарій поповнення
POST /wallets/balance- Обов'язково передайте memo у коментарі або forward payload. Без нього переказ не буде зараховано автоматично.
GET /wallets/balance
Покупки
Покупки обробляються асинхронно. API перевіряє запит і баланс, створює замовлення, списує кошти та повертає orderId зі статусом processing.
Після переходу замовлення в failed списана сума повертається на той самий баланс.
POST /api/v1/purchase/stars
Купує від 50 до 1 000 000 Telegram Stars для вказаного Telegram username.
| Заголовки | Обов'язково | Опис |
|---|---|---|
x-api-key | так | Авторизація |
idempotency-key | так | 8–64 |
Accept | ні | application/json |
Content-Type | так | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}curl --request POST 'https://api.gramix.io/api/v1/purchase/stars' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: stars_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}'{
"statusCode": 201,
"data": {
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "processing",
"idempotencyKey": "stars_20260713_0001"
}
}POST /api/v1/purchase/premium/{duration}
Купує Telegram Premium на 3, 6 або 12 місяців.
| Заголовки | Обов'язково | Опис |
|---|---|---|
x-api-key | так | Авторизація |
idempotency-key | так | 8–64 |
Accept | ні | application/json |
Content-Type | так | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "gram"
}curl --request POST 'https://api.gramix.io/api/v1/purchase/premium/6' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: premium_6_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "gram"
}'{
"statusCode": 201,
"data": {
"orderId": "18ca3cce-8441-4de6-874a-fd34792ae1b5",
"status": "processing",
"idempotencyKey": "premium_6_20260713_0001"
}
}{
"statusCode": 400,
"message": "Invalid premium duration. Allowed values: 3, 6, 12"
}POST /api/v1/purchase/gram
Купує та надсилає від 1 до 10 000 GRAM вказаному Telegram-одержувачу.
| Заголовки | Обов'язково | Опис |
|---|---|---|
x-api-key | так | Авторизація |
idempotency-key | так | 8–64 |
Accept | ні | application/json |
Content-Type | так | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"gram": 2.5
}curl --request POST 'https://api.gramix.io/api/v1/purchase/gram' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: gram_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"gram": 2.5
}'{
"statusCode": 201,
"data": {
"orderId": "882dd8ca-5d68-4b85-bb26-c25ee38d9a98",
"status": "processing",
"idempotencyKey": "gram_20260713_0001"
}
}Webhook статусу замовлення
Якщо для API-ключа вказано webhookUrl, API надсилає POST після завершення замовлення.
POST {webhookUrl}
Content-Type: application/jsonДля успішного замовлення надсилається подія order.completed, для неуспішного — order.failed.
{
"event": "order.completed",
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "completed",
"processingStatus": "completed_fragment_purchase",
"type": "stars",
"amount": "7.6500",
"currency": "usd",
"recipientName": "telegram_user",
"createdAt": "2026-07-13T10:20:30.000Z"
}{
"event": "order.failed",
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "failed",
"processingStatus": "failure_fragment_purchase",
"type": "stars",
"amount": "7.6500",
"currency": "usd",
"recipientName": "telegram_user",
"createdAt": "2026-07-13T10:20:30.000Z"
}Схема webhook
| Поле | Тип | Обмеження |
|---|---|---|
event | string | order.completed | order.failed |
orderId | UUID | — |
status | string | completed | failed |
type | string | stars | gram | premium_* |
amount | decimal(4) | — |
currency | string | gram | usd |
recipientName | string | — |
createdAt | ISO 8601 | — |
Вимоги до обробника webhook
Якнайшвидше поверніть HTTP 2xx, обробляйте події ідемпотентно та не покладайтеся на порядок їх доставки.
Повний приклад клієнтського сценарію
- Перевірте баланс.
- За потреби отримайте реквізити, поповніть гаманець і дочекайтеся зміни балансу.
- Створіть покупку з унікальним idempotency-key.
- Збережіть orderId, status і idempotencyKey. Відповідь 201 означає, що замовлення прийнято в обробку.
- Дочекайтеся order.completed або order.failed і зіставте подію за orderId.
GET /api/v1/wallets/balance
x-api-key: YOUR_API_KEYPOST /api/v1/wallets/balance
x-api-key: YOUR_API_KEYPOST /api/v1/purchase/stars
x-api-key: YOUR_API_KEY
idempotency-key: order_20260713_0001
Content-Type: application/json
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}Приклад TypeScript-клієнта
type SuccessResponse<T> = {
statusCode: number;
data: T;
};
type ApiError = {
statusCode: number;
message: string;
};
type PurchaseResponse = {
orderId: string;
status: "created" | "processing" | "completed" | "failed" | "canceled";
idempotencyKey: string;
};
type WalletBalance = {
gram: string;
usdt: string;
};
const BASE_URL = "https://api.gramix.io";
async function apiRequest<T>(path: string, apiKey: string, init: RequestInit = {}): Promise<T> {
const response = await fetch(
`${BASE_URL}${path}`,
{
...init,
headers: {
Accept: "application/json",
"x-api-key": apiKey,
...(init.body ? { "Content-Type": "application/json" } : {}),
...init.headers,
},
},
);
const payload = (await response.json()) as SuccessResponse<T> | ApiError;
if (!response.ok) {
const error = payload as ApiError;
throw new Error(`[${error.statusCode}] ${error.message}`);
}
return (payload as SuccessResponse<T>).data;
}
export function getBalance(apiKey: string): Promise<WalletBalance> {
return apiRequest<WalletBalance>("/api/v1/wallets/balance", apiKey);
}
export function purchaseStars(
apiKey: string,
idempotencyKey: string,
input: {
recipientName: string;
paymentCurrency: "gram" | "usdt";
stars: number;
},
): Promise<PurchaseResponse> {
return apiRequest<PurchaseResponse>("/api/v1/purchase/stars", apiKey, {
method: "POST",
headers: { "idempotency-key": idempotencyKey },
body: JSON.stringify(input),
});
}Готові почати інтеграцію?
Створіть API-ключ і налаштуйте URL для webhook.