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.