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 | 创建或返回用于在 TON 网络充值的 address 和 memo。 | 201 |
POST | /api/v1/purchase/stars | 为指定的 Telegram username 购买 50 至 1,000,000 个 Telegram Stars。 | 201 |
POST | /api/v1/purchase/premium/{duration} | 购买 3、6 或 12 个月的 Telegram Premium。 | 201 |
POST | /api/v1/purchase/gram | 向指定的 Telegram 收款方购买并发送 1 至 10,000 GRAM。 | 201 |
身份验证
所有方法都需要有效的 API 密钥,并通过 x-api-key HTTP 请求头传递。
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"
}通用 Schema
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/* 方法都需要长度为 8–64 个字符的 idempotency-key 请求头。
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
创建或返回用于在 TON 网络充值的 address 和 memo。
| 请求头 | 必填 | 说明 |
|---|---|---|
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 余额,TON 网络上的 USDT 记入 usdt 余额。
推荐充值流程
POST /wallets/balance- 务必将 memo 放入交易备注或 forward payload 中。如果缺少 memo,转账将无法自动入账。
GET /wallets/balance
购买
购买请求会异步处理。API 验证请求和余额、创建订单、扣除费用,然后返回状态为 processing 的 orderId。
当订单转为 failed 状态时,已扣金额会退回原余额。
POST /api/v1/purchase/stars
为指定的 Telegram username 购买 50 至 1,000,000 个 Telegram Stars。
| 请求头 | 必填 | 说明 |
|---|---|---|
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}
购买 3、6 或 12 个月的 Telegram Premium。
| 请求头 | 必填 | 说明 |
|---|---|---|
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
向指定的 Telegram 收款方购买并发送 1 至 10,000 GRAM。
| 请求头 | 必填 | 说明 |
|---|---|---|
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 Schema
| 字段 | 类型 | 限制 |
|---|---|---|
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 密钥并配置 Webhook URL。