TeleAccountHub API
REST API Reference · Wallet · Orders · Sessions

TeleAccountHub API Documentation

Beautiful, developer-friendly documentation converted from your Markdown file. It includes authentication, wallet APIs, API key management, number orders, digital session downloads, referrals, admin endpoints, setup steps, and error handling.

GET endpoints19
POST endpoints9
DELETE endpoints1
Total endpoints29

Authentication

All authenticated endpoints require a Bearer token in the Authorization header.

HTTPAuthorization: Bearer tah_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Admin endpoints use the API_ADMIN_SECRET value from your .env file:

HTTPAuthorization: Bearer YOUR_ADMIN_SECRET_HERE

API keys can be created via POST /api/v1/api-keys or by the admin at POST /api/v1/admin/users/{id}/api-key.


Error Format

All errors return JSON with ok: false:

JSON{
  "ok": false,
  "error": "INSUFFICIENT_BALANCE",
  "message": "Insufficient balance. Required: $3.5000 · Available: $1.2000"
}
Error Code HTTP Meaning
UNAUTHORIZED 401 Missing or invalid Bearer token
INVALID_API_KEY 401 Key not found or wrong
KEY_REVOKED 401 Key has been revoked
ACCOUNT_SUSPENDED 403 User is banned
INSUFFICIENT_SCOPE 403 Key lacks required scope
FORBIDDEN 403 Admin only
NOT_FOUND 404 Resource not found
OUT_OF_STOCK 404 No stock available
INSUFFICIENT_BALANCE 402 Not enough wallet balance
CONFLICT 409 Race condition — retry
RATE_LIMITED 429 Too many requests
SERVER_ERROR 500 Internal error
BAD_REQUEST 400 Invalid input

Rate Limits

  • Default: 60 requests per minute per API key
  • Controlled by API_RATE_LIMIT env var
  • On limit hit: HTTP 429 + Retry-After header

Profile & Wallet

GET /api/v1/me

Returns your full profile, balance, referral info, and endpoint map.

BASHcurl https://yourdomain.com/api/v1/me \
  -H "Authorization: Bearer tah_live_xxx"

Response:

JSON{
  "ok": true,
  "user": {
    "id": 123456789,
    "telegram_id": 123456789,
    "name": "Aditya",
    "username": "@aditya",
    "balance_usd": 12.3400,
    "balance_display": "$12.34",
    "total_spent_usd": 45.00,
    "referral_code": "a1b2c3d4",
    "referral_url": "https://t.me/YourBot?start=ref_a1b2c3d4",
    "referral_count": 5,
    "referral_earned": 2.50,
    "lang": "en",
    "joined_at": 1751234567
  },
  "api": {
    "version": "1.0.0",
    "endpoints": { ... }
  }
}

GET /api/v1/wallet/balance

Scope: read

JSON{
  "ok": true,
  "balance_usd": 12.34,
  "balance_display": "$12.34",
  "total_spent_usd": 45.00
}

GET /api/v1/wallet/transactions

Scope: read
Query params: page (default 0), limit (default 20, max 50)

JSON{
  "ok": true,
  "transactions": [
    {
      "id": 1,
      "user_id": 123456789,
      "event_type": "debit",
      "amount_usd": 3.50,
      "source": "api_checkout",
      "created_at": 1751234567
    }
  ],
  "total": 10,
  "page": 0,
  "limit": 20
}

API Key Management

GET /api/v1/api-keys

List all your API keys (keys are masked — only prefix shown).

JSON{
  "ok": true,
  "api_keys": [
    {
      "id": 1,
      "name": "My App",
      "key_prefix": "tah_live_abc12···",
      "scopes": "read,orders,download",
      "last_used_at": 1751234567,
      "revoked_at": null,
      "created_at": 1751000000
    }
  ]
}

POST /api/v1/api-keys

Create a new API key. The full key is shown only once.

Scope: api_keys

Request:

JSON{
  "name": "Production App",
  "scopes": "read,orders,download"
}

Available scopes: read, orders, download, api_keys

Response:

JSON{
  "ok": true,
  "api_key": "tah_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "prefix": "tah_live_abc12···",
  "name": "Production App",
  "scopes": "read,orders,download",
  "warning": "Store this key securely. It will NOT be shown again."
}

DELETE /api/v1/api-keys/{id}

Revoke an API key immediately.

JSON{ "ok": true, "message": "API key revoked successfully." }

POST /api/v1/api-keys/{id}/rotate

Regenerate a key. Old key becomes invalid immediately.

Scope: api_keys

JSON{
  "ok": true,
  "api_key": "tah_live_new_key_here...",
  "prefix": "tah_live_new···",
  "warning": "Your old key is now invalid. Update all integrations immediately."
}

Catalog — Number Services

GET /api/v1/catalog/services

Public endpoint — no auth required.

Returns all available phone number subcategories grouped by category.

JSON{
  "ok": true,
  "services": [
    {
      "service_id": 3,
      "slug": "number_3",
      "name": "India Premium",
      "type": "number",
      "category_id": 1,
      "category_name": "Virtual Numbers",
      "stock": 120,
      "min_price_usd": 0.50,
      "max_price_usd": 0.50
    }
  ],
  "categories": [
    { "category_id": 1, "category_name": "Virtual Numbers", "total_stock": 120 }
  ]
}

GET /api/v1/catalog/services/{slug}/prices

Public endpoint — no auth required.

Slug format: number_{subcategory_id} (from catalog above)

JSON{
  "ok": true,
  "slug": "number_3",
  "name": "India Premium",
  "prices": [
    { "country": "IN", "price_usd": 0.5, "stock": 120 }
  ],
  "total_stock": 120
}

Number Orders

POST /api/v1/checkout

Buy a phone number using your wallet balance.

Scope: orders

Request:

JSON{
  "service": "number_3"
}

Idempotency: Add X-Idempotency-Key: <unique_uuid> header to prevent duplicate orders.

Response:

JSON{
  "ok": true,
  "order": {
    "id": 42,
    "order_number": "TAH-MNO12-ABC123",
    "type": "number",
    "status": "completed",
    "phone": "+919876543210",
    "sms_code": null,
    "price_charged_usd": 0.50,
    "price_display": "$0.50",
    "item_count": 1,
    "download_ready": false,
    "created_at": 1751234567,
    "completed_at": 1751234567,
    "cancelled_at": null,
    "download_count": 0
  }
}

GET /api/v1/orders

List your number orders.

Scope: read
Query params: page, limit, status


GET /api/v1/orders/{id}

Get one number order.


GET /api/v1/orders/{id}/code

Poll for the SMS/OTP code for a number order.

The bot will fetch the code from the account's Telegram session and fulfill it. Poll every 5–10 seconds.

Response when pending:

JSON{
  "ok": true,
  "code": null,
  "status": "pending",
  "phone": "+919876543210",
  "message": "Code is being fetched. Poll this endpoint again in 5–10 seconds."
}

Response when fulfilled:

JSON{
  "ok": true,
  "code": "12345",
  "status": "fulfilled",
  "phone": "+919876543210"
}

POST /api/v1/orders/{id}/cancel

Cancel an order in processing or pending_sms status. Balance is automatically refunded.

Scope: orders

JSON{
  "ok": true,
  "message": "Order cancelled. Refund applied.",
  "refunded_usd": 0.50
}

Catalog — Digital Products

These are session file products (sold as encrypted archives).

GET /api/v1/catalog/digital/categories

Public — no auth required.

JSON{
  "ok": true,
  "categories": [
    { "category_id": 2, "category_name": "Session Files", "total_stock": 48 }
  ]
}

GET /api/v1/catalog/digital/categories/{id}/products

Public — no auth required.

JSON{
  "ok": true,
  "category_id": 2,
  "category_name": "Session Files",
  "products": [
    {
      "product_id": 7,
      "product_name": "India Session 6M+",
      "total_stock": 20,
      "retail_price_usd": 3.50,
      "max_price_usd": 4.00,
      "wallet_price": "$3.50"
    }
  ]
}

Digital Orders

POST /api/v1/digital/checkout

Purchase session files. Deducts from wallet. Returns a time-limited download URL.

Scope: orders

Request:

JSON{
  "product_id": 7,
  "quantity": 3
}

Response:

JSON{
  "ok": true,
  "order": {
    "id": 55,
    "order_number": "TAH-XYZ-123ABC",
    "type": "digital",
    "status": "completed",
    "price_charged_usd": 10.50,
    "item_count": 3,
    "download_ready": true,
    "created_at": 1751234567
  },
  "download_url": "https://yourdomain.com/api/v1/digital/orders/55/download?token=abc123...",
  "download_expires_in": "300s",
  "download_expires_at": 1751234867,
  "note": "Download URL expires in 300 seconds. Request a fresh URL anytime from GET /api/v1/digital/orders/{id}/link"
}

GET /api/v1/digital/orders

List your digital orders. Scope: read


GET /api/v1/digital/orders/{id}

Get one digital order.


Get a fresh download URL (5-minute window) for a completed order.

Scope: download

JSON{
  "ok": true,
  "order_id": 55,
  "download_url": "https://yourdomain.com/api/v1/digital/orders/55/download?token=def456...",
  "download_expires_in": "300s",
  "download_expires_at": 1751235167,
  "download_count": 2
}

GET /api/v1/digital/orders/{id}/download?token={token}

Download the session ZIP archive.

Scope: download

Returns binary application/zip containing .session files named by phone number.

BASHcurl "https://yourdomain.com/api/v1/digital/orders/55/download?token=abc123" \
  -H "Authorization: Bearer tah_live_xxx" \
  -o sessions_TAH-XYZ-123ABC.zip

⚠️ Token expires in 300 seconds. If expired, call /link to get a fresh one.


Referral Program

GET /api/v1/referral

Get your referral code, URL, earnings, and current program rules.

JSON{
  "ok": true,
  "referral_code": "a1b2c3d4",
  "referral_url": "https://t.me/YourBot?start=ref_a1b2c3d4",
  "referrals_count": 5,
  "total_earned_usd": 2.50,
  "program": {
    "enabled": true,
    "trigger": "purchase",
    "reward_type": "percent",
    "reward_value": 5.0,
    "reward_label": "5% of purchase",
    "min_purchase": 0.0,
    "once_per_user": true,
    "max_uses": 0
  }
}

GET /api/v1/referral/stats

View your referral event history (last 100 events).

JSON{
  "ok": true,
  "events": [
    {
      "id": 1,
      "trigger_type": "purchase",
      "purchase_amount": 10.00,
      "reward_usd": 0.50,
      "created_at": 1751234567,
      "first_name": "Bob",
      "username": "bob_user"
    }
  ],
  "total_earned_usd": 0.50
}

Admin Endpoints

All admin endpoints require Authorization: Bearer <API_ADMIN_SECRET>.


GET /api/v1/admin/referral-settings

View current referral configuration.


POST /api/v1/admin/referral-settings

Update referral program settings. All fields are optional.

JSON{
  "enabled": 1,
  "trigger_on": "purchase",
  "reward_type": "percent",
  "reward_value": 5.0,
  "min_purchase": 1.00,
  "once_per_refer": 1,
  "max_uses": 0
}
Field Type Values Description
enabled int 1/0 Enable/disable program
trigger_on str signup, purchase, both When to give reward
reward_type str percent, fixed Reward calculation method
reward_value float e.g. 5.0 % or USD amount
min_purchase float e.g. 1.00 Min purchase to trigger
once_per_refer int 1/0 Referrer earns once per referred user
max_uses int 0 = unlimited Max total rewards per referrer

POST /api/v1/admin/users/{telegram_id}/balance

Adjust a user's wallet balance.

JSON{
  "amount": 5.00,
  "direction": "add"
}

direction: "add" or "deduct"

JSON{
  "ok": true,
  "user_id": 123456789,
  "adjustment_usd": 5.00,
  "new_balance_usd": 17.34,
  "message": "Balance updated."
}

POST /api/v1/admin/users/{telegram_id}/api-key

Create an API key on behalf of a user (they can use this to access the API).

JSON{
  "name": "User's App",
  "scopes": "read,orders,download,api_keys"
}
JSON{
  "ok": true,
  "api_key": "tah_live_xxxxxxxx...",
  "prefix": "tah_live_abc12···",
  "for_user_id": 123456789,
  "scopes": "read,orders,download,api_keys",
  "warning": "Store this key securely. It will NOT be shown again."
}

GET /api/v1/admin/code-requests

Poll for pending OTP code requests. Your bot should call this endpoint regularly and fulfill codes.

JSON{
  "ok": true,
  "pending_code_requests": [
    {
      "id": 3,
      "api_order_id": 42,
      "status": "pending",
      "requested_at": 1751234567,
      "phone": "+919876543210",
      "user_id": 123456789
    }
  ]
}

POST /api/v1/admin/orders/{id}/fulfill-code

Post the OTP code for a pending code request.

JSON{ "code": "12345" }
JSON{
  "ok": true,
  "message": "Code fulfilled.",
  "order_id": 42,
  "code": "12345"
}

Status Codes

Number Orders

Status Meaning
processing Order created, not yet delivered
pending_sms Awaiting OTP code
completed Phone delivered
cancelled Cancelled, balance refunded
failed Failed delivery

Digital Orders

Status Meaning
processing Order created
completed Sessions ready to download
failed Delivery failed
refunded Refunded by admin

Referral System Rules

CODEHow it works:
1. User shares their referral URL (https://t.me/YourBot?start=ref_CODE)
2. New user starts the bot with that link → bot stores referral relationship
3. When referred user triggers the configured event → referrer earns reward

Trigger options:
  signup   → Referrer earns when referred user first starts the bot
  purchase → Referrer earns when referred user completes a purchase
  both     → Referrer earns on both events

Reward types:
  percent → Referrer earns X% of each qualifying purchase
  fixed   → Referrer earns a flat $X per qualifying event

once_per_refer = 1:
  Referrer earns at most once per referred user (per trigger type)
  E.g. if trigger=purchase, referrer earns only on the FIRST purchase

max_uses = 0 → unlimited total referrals
max_uses = N → referrer can only earn from N total referred users

min_purchase → purchase must be at least $X to qualify for percent reward

Idempotency

To prevent duplicate orders on retries, include:

HTTPX-Idempotency-Key: <unique-uuid-per-request>

If a request with the same key already succeeded, the same order is returned with "idempotent": true.


Setup Guide

1. Add to .env

ENVAPI_ADMIN_SECRET=your_strong_admin_secret_here_change_this
BOT_USERNAME=YourBotUsername
API_RATE_LIMIT=60
FERNET_KEY=your_existing_fernet_key_from_bot_env

2. Place api.php and .htaccess in your web root

Same directory as your bot (where data/store.db lives).

3. Enable PHP extensions

Required: pdo_sqlite, openssl, zip

4. Test the API

BASH# Health check
curl https://yourdomain.com/api/v1

# Create your first API key (as admin)
curl -X POST https://yourdomain.com/api/v1/admin/users/YOUR_TELEGRAM_ID/api-key \
  -H "Authorization: Bearer YOUR_ADMIN_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"name":"My App","scopes":"read,orders,download,api_keys"}'

# Browse catalog
curl https://yourdomain.com/api/v1/catalog/services

# Buy a number
curl -X POST https://yourdomain.com/api/v1/checkout \
  -H "Authorization: Bearer tah_live_xxx" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{"service":"number_1"}'

5. Bot integration for OTP codes

Have your bot poll GET /api/v1/admin/code-requests every 30 seconds, fetch the OTP from the session, then call POST /api/v1/admin/orders/{id}/fulfill-code with the code.


TeleAccountHub API v1.0.0 — Powered by the Telegram Bot's SQLite database