Reseller API

TGLift API

Connect your service to the catalog, balance and orders of your TGLift account.

Access

Your API key

Checking authentication...

Keep the key on your server. Never put it in a URL, browser JavaScript, repository or analytics.

Connection

Core rules

Base URLhttps://tglift.ru/api/v1
AuthenticationX-API-Key: tgl_...
FormatJSON or form-urlencoded; responses are always JSON
New orderA unique Idempotency-Key is required
Rate limit120 requests per minute per account

Contract

API endpoints

HTTPURLPurposeMain parameters
GET/api/v1/servicesAvailable TGLift serviceslocale, currency
GET/api/v1/balanceAccount balancecurrency
GET/api/v1/ordersOrders, newest firstlimit 1-100, offset
POST/api/v1/ordersCreate an orderservice, fields from orderRequirements
GET/api/v1/orders/{RQ-ID}Get one orderTGLift order ID only
POST/api/v1/orders/{RQ-ID}/cancelRequest cancellationThe service must support cancellation
POST/api/v1/orders/{RQ-ID}/refillRequest a refillThe service must support refill

Mutating operations accept POST only. Calling add, cancel or refill through GET returns 405 method_not_allowed.

GET /services

Service contract

Fetch the catalog before creating an order. The rate field is your public TGLift price in the selected currency. pricingUnit=1000_units means a price per 1,000 units; package means a fixed package price.

Response example
[
  {
    "service": "631",
    "name": "Telegram subscribers",
    "type": "Default",
    "category": "Telegram - Subscribers",
    "rate": "250.00",
    "ratePer": 1000,
    "pricingUnit": "1000_units",
    "currency": "RUB",
    "min": 100,
    "max": 100000,
    "refill": true,
    "cancel": false,
    "orderRequirements": {
      "type": "default",
      "requiresLink": true,
      "requiresQuantity": true,
      "quantityFrom": null,
      "fields": []
    }
  }
]

orderRequirements

Special service types

Do not infer fields from the service name. Use the selected service's orderRequirements; it declares whether a link, quantity and special fields are required.

typeFieldsQuantity source
defaultlink, quantityquantity
packagelinkFixed package
custom_comments, custom_replieslink, fields.commentsNumber of non-empty lines
seolink, quantity, fields.keywordsquantity
polllink, quantity, fields.pollAnswerquantity
invites_from_groupslink, quantity, fields.groupsquantity
comment_likes, comment_replieslink, quantity, fields.usernamequantity
mentions_*username, usernames, hashtag, hashtags or mediaUrl as declared in fieldsAs declared by quantityFrom
subscriptionsusername, min, max, delay; optional posts, oldPosts, expirymax

For JSON requests, put special values inside fields. For application/x-www-form-urlencoded, send them at the top level.

Create an order

curl -X POST "https://tglift.ru/api/v1/orders" \
  -H "X-API-Key: tgl_xxx" \
  -H "Idempotency-Key: order-20260722-0001" \
  -H "Content-Type: application/json" \
  --data '{
    "service": "631",
    "link": "https://t.me/example_channel/10",
    "quantity": 1000,
    "locale": "en",
    "currency": "USD"
  }'

201 response

{
  "order": "RQ-MRX1ABC2-12AB34",
  "status": "pending",
  "idempotentReplay": false
}

For a network retry, send the same request with the same key. The API returns the same order with idempotentReplay: true.

GET /orders/{RQ-ID}

Order contract

{
  "order": "RQ-MRX1ABC2-12AB34",
  "service": "631",
  "status": "in_progress",
  "statusMessage": "",
  "charge": "250.00",
  "currency": "RUB",
  "link": "https://t.me/example_channel/10",
  "quantity": 1000,
  "remains": 420,
  "startCount": 15000,
  "refundedAmount": "0.00",
  "cancelRequestedAt": null,
  "refillRequestedAt": null,
  "createdAt": "2026-07-22T10:00:00.000Z",
  "updatedAt": "2026-07-22T10:05:00.000Z"
}

remains and startCount may be null until values are available. Every public order identifier is a TGLift identifier.

OrderStatus

Status values

StatusMeaningIntegration action
pendingAccepted and waiting to startPoll at a reasonable interval
in_progressCurrently runningContinue polling
completedFully completedFinal status
partialPartially completedFinal; unused remainder may be refunded automatically
canceledCanceledFinal; inspect refundedAmount
failedCould not start or completeDo not automatically retry with a new key; inspect the order
cancel_requestedCancellation requestedWait for a final status
payment_requiredNot enough balance to continueAdd funds
under_reviewTGLift is verifying the processing resultDo not create a duplicate; wait for an update

Unified error object

{
  "ok": false,
  "error": "Error description",
  "code": "invalid_request",
  "requestId": "REQ-...",
  "details": {}
}

Keep requestId for support diagnostics. Never send your secret API key in a support request.

HTTP status codes

400Invalid parameters or a missing Idempotency-Key
401No valid X-API-Key
402Insufficient balance
404Endpoint or TGLift order not found
405Wrong HTTP method
409Idempotency or order state conflict
429Rate limit exceeded; honor Retry-After
5xxTemporary TGLift error; retry with a delay

Reliability

Limits and retries

  • Limit: 120 requests per 60 seconds per account. Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.
  • After 429, honor Retry-After. For 5xx responses, use exponential backoff with jitter.
  • Each logical order gets a new 8-128 character Idempotency-Key. A network retry of that same order uses the original key and identical parameters.
  • After a timeout, do not create a new order until you check the original order or repeat it idempotently.

SDK examples

Integration examples

Node.js
const response = await fetch("https://tglift.ru/api/v1/orders", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.TGLIFT_API_KEY,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ service: "631", link, quantity: 1000 })
});
const data = await response.json();
if (!response.ok) throw new Error(`${data.code}: ${data.error}`);
Python
import os, uuid, requests

response = requests.post(
    "https://tglift.ru/api/v1/orders",
    headers={
        "X-API-Key": os.environ["TGLIFT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"service": "631", "link": link, "quantity": 1000},
    timeout=30,
)
response.raise_for_status()
print(response.json())
PHP
$payload = json_encode([
  "service" => "631",
  "link" => $link,
  "quantity" => 1000
]);
$ch = curl_init("https://tglift.ru/api/v1/orders");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "X-API-Key: " . getenv("TGLIFT_API_KEY"),
    "Idempotency-Key: " . bin2hex(random_bytes(16)),
    "Content-Type: application/json"
  ],
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 30
]);
echo curl_exec($ch);

Compatibility

Legacy action API

Existing integrations may continue to send POST /api/v1 with an action field: services, balance, orders, add, status, cancel or refill. New integrations should use the REST endpoints above. Mutating legacy actions also accept POST only.