API డాక్యుమెంటేషన్
REST API v1 for searching and exporting Telegram channels. JSON, cursor pagination, the same filter schema as the UI and exports. The machine-readable schema is the backend OpenAPI (/openapi.json).
Authentication
Create a key in Dashboard → API keys (Premium and Super plans). Key format: mk_live_<prefix>_<secret>, shown only once. Send it in the header:
Authorization: Bearer mk_live_ab12cd34_xxxxxxxxxxxxxxxx
# or
X-API-Key: mk_live_ab12cd34_xxxxxxxxxxxxxxxxScopes: read (default) and export — for POST /v1/exports. At most two active keys, so you can rotate without downtime.
Billing
You pay for data returned, not for calls. Everything is charged in credits: 1 credit = $0.001.
- Each paid request — 1 credit ($1 per 1,000 requests).
- Each channel row — at the field-set rate: Base 0.5 credits, +Metrics 1.5, +Ads 2, History 3.
- Each post — 0.5 credits.
- A channel this key already paid for within 30 days is returned for free.
- /count and facets — request fee only.
The amount charged is returned in the X-Credits-Charged header. Balance and usage — GET /v1/usage. Export prices — see pricing.
Endpoints
| Method | Path | Description | Cost |
|---|---|---|---|
| GET | /v1/categories | Category tree | free |
| GET | /v1/languages | Languages with channel counts | free |
| GET | /v1/usage | Balance, daily usage, limits | free |
| POST | /v1/channels/search | Filters + q, cursor, up to 100 per page | request + rows |
| POST | /v1/channels/count | Counts and facets | request |
| GET | /v1/channels/{id|username} | Channel card (?fields=base,metrics,ads) | request + row |
| GET | /v1/channels/{id}/history | Daily subscribers & metrics (?days=) | request + History |
| GET | /v1/channels/{id}/posts | Recent posts (?limit= up to 100) | request + posts |
| GET | /v1/channels/{id}/references | Cited by / cites | request + rows |
| POST | /v1/posts/search | Full-text post search | request + posts |
| POST | /v1/exports | Async export (export scope) | export price |
| GET | /v1/exports/{id} | Status and download link | free |
Filters (ChannelQuery)
The query object is the same for /channels/search, /channels/count and /exports. Omit empty fields.
| q | string | text: title, username, description, posts |
| category_ids / exclude_category_ids | int[] | categories (areas or subcategories) |
| channel_ids | int[] | specific channels |
| languages | string[] | language codes: ru, en, uk… |
| kind | all | channel | group | type |
| subscribers_min / subscribers_max | int | subscribers |
| avg_views_min, reach_24h_min | number | views and 24h reach |
| er_min, err_24h_min | number | ER / ERR, % |
| growth_7d_min, growth_30d_min, growth_pct_30d_min | number | growth |
| posts_30d_min, last_post_after | int, date | activity |
| created_after / created_before | date | creation date |
| has_ads_contact, ad_share_max | bool, 0..1 | ads |
| fraud_max | 0..1 | fraud score threshold |
| verified_only, exclude_scam | bool | flags (exclude_scam=true by default) |
| sort, order | string | same values; desc|asc |
Examples
Search channels
curl -X POST https://api.tgmarket.example/v1/channels/search \
-H "Authorization: Bearer $MK_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {"q": "stock market", "languages": ["en", "hi"], "subscribers_min": 5000, "sort": "growth_30d"},
"fields": ["base", "metrics"],
"limit": 100
}'Response:
{
"items": [{"id": 2365318039, "username": "GPTronhub", "title": "…", "subscribers": 169432, "er": 0.16, …}],
"total": 605,
"next_cursor": "eyJoIjoi…" // pass as cursor in the next request
}Count only
curl -X POST https://api.tgmarket.example/v1/channels/count -H "Authorization: Bearer $MK_KEY" \
-H "Content-Type: application/json" -d '{"query": {"category_ids": [21]}}'Card and history
curl "https://api.tgmarket.example/v1/channels/durov?fields=base,metrics" -H "Authorization: Bearer $MK_KEY"
curl "https://api.tgmarket.example/v1/channels/1006503122/history?days=90" -H "Authorization: Bearer $MK_KEY"Export
curl -X POST https://api.tgmarket.example/v1/exports -H "Authorization: Bearer $MK_KEY" -H "Content-Type: application/json" \
-d '{"query": {"q": "crypto"}, "fields": ["base","metrics"], "format": "csv", "row_limit": 20000}'
# → {"export_id": "…", "rows": 20000, "price_credits": 32000, "status": "queued"}
curl https://api.tgmarket.example/v1/exports/<export_id> -H "Authorization: Bearer $MK_KEY"
# → {"status": "done", "progress": 100, "download_url": "https://…", …}Rate limits
- Premium — 1 request per second, Super — 10, Enterprise — by contract.
- Every response includes
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset. - Beyond 10,000 results per query — use /v1/exports.
- A hard daily cap on unique channels per key; exceeding it freezes the key until manual review.
Errors
All errors share one format:
{"error": {"code": "payment_required", "message": "…"}}401 invalid_api_key— invalid or revoked key402 payment_required/402 insufficient_funds— balance exhausted, top up in the dashboard (need/have in the body)403 api_not_in_plan,403 scope_required,403 key_frozen,403 ip_not_allowed429 rate_limited— RPS exceeded; wait the number of seconds inRetry-After400 too_deep,400 bad_cursor,422— invalid parameters