API
API HTTP در TelegramOS: با کلید API احراز هویت کنید و اکانتها، اینباکس، باتها، آنالیتیکس و ورکفلوها را بهصورت برنامهنویسیشده مدیریت کنید.
هر کاری که داشبورد انجام میدهد، از طریق همین API HTTP انجام میشود. تکتک مسیرها، بدنهها و کدهای وضعیتی که در ادامه میبینید پیش از انتشار این صفحه روی یک فضای کاری واقعی آزمایش شدهاند.
آدرس پایه
https://telegramos.netدرخواستها و پاسخها JSON هستند (Content-Type: application/json). خروجیهای Export یک فایل برمیگردانند (.xlsx / .csv) و دانلود رسانهها بایت خام برمیگرداند.
احراز هویت
یک کلید در Settings → API keys بسازید و آن را در هدر X-API-Key بفرستید:
curl -H "X-API-Key: tgp_your_key_here" \
https://telegramos.net/api/accountsکلید فقط یک بار، در لحظهی ساخت، نمایش داده میشود. بهصورت هش SHA-256 ذخیره میشود، بنابراین هیچکس — حتی خود ما — نمیتواند آن را بازیابی کند. اگر گمش کردید، یک کلید جدید بسازید.
| ویژگی | مقدار |
|---|---|
| هدر | X-API-Key |
| قالب | tgp_ و بهدنبال آن 54 کاراکتر URL-safe |
| طول عمر پیشفرض | 90 روز (expires_days، بین 1 تا 365) |
| تعداد کلید در هر فضای کاری | 20 |
| ابطال | آنی، از Settings → API keys |
تغییر رمز عبور، بازنشانی آن، غیرفعالکردن 2FA یا خروج از همهی دستگاهها تمام کلیدهایی را که پیش از آن لحظه صادر شدهاند برای همیشه باطل میکند.
نشست (session) مرورگر بهجای کلید از کوکی استفاده میکند. این دو مسیر هرگز با هم قاطی نمیشوند: درخواستی که X-API-Key دارد صرفاً با همان کلید احراز هویت میشود، و مدیریت کلیدها (/api-keys) عمداً کلید را نمیپذیرد — یک کلید نمیتواند کلید دیگری بسازد یا باطل کند (403).
دسترسیها
دسترسیهایی که هنگام ساخت کلید تیک میزنید روی تکتک درخواستها اعمال میشوند.
فعلها — همیشه یکی از اینها لازم است:
| دسترسی | چه چیزی میدهد |
|---|---|
read | GET، HEAD |
write | POST، PUT، PATCH، DELETE |
حوزهها — اختیاری. کلیدی که هیچ حوزهای را تیک نزده باشد به همهی حوزهها میرسد؛ کلیدی که یک یا چند حوزه را تیک زده باشد فقط به همانها محدود است:
| دسترسی | چه چیزی را پوشش میدهد |
|---|---|
accounts | اکانتها، پروکسیها، گرمکردن (warm-up)، اسکرپینگ، نیچیاب، پیام انبوه، پکیجهای لید |
inbox | گفتگوها، پیامها، گروهها، پاسخهای ذخیرهشده، قوانین پاسخ خودکار، اعلانها |
bots | باتها، فلوها، کمپینها، همگامسازی کانالها، دیتابیس بات |
analytics | endpointهای آنالیتیکس و AI |
tasks | ورکفلوها و اجراها |
read بهتنهایی یک کلید فقطخواندنی روی کل پلتفرم است. read + write + inbox میتواند فقط در اینباکس هر کاری بکند — روی /api/accounts پاسخ 403 میگیرد.
شناسهی درخواست
هر پاسخ یک X-Request-ID دارد. اگر خودتان بفرستید همان را استفاده میکنیم؛ اگر چیزی نفرستید، یکی تولید میکنیم:
curl -i -H "X-API-Key: $KEY" -H "X-Request-ID: my-job-42" \
https://telegramos.net/api/accounts
...
x-request-id: my-job-42هر درخواست در سمت ما با همان شناسه، مسیر، وضعیت، مدتزمان، پیشوند کلید (هرگز خود کلید) و فضای کاری لاگ میشود:
api.request service=account-service request_id=my-job-42 method=GET
path=/api/accounts status=200 duration_ms=144 auth=key:tgp_t24zIO user=<workspace>شناسه را در سمت خودتان هم لاگ کنید. تا وقتی پلتفرم در بتاست، این سریعترین راه برای پیداکردن دقیقاً همان فراخوانی شماست — آن را در تیکت پشتیبانی ذکر کنید تا بتوانیم کل مسیر درخواست را بدون حدسزدن بیرون بکشیم.
خطاها
| وضعیت | معنی |
|---|---|
400 | درخواست بدشکل، یا شناسهای در مسیر که UUID نیست |
401 | کلید وجود ندارد، ناشناخته است، منقضی یا باطل شده |
402 | پلن شما این قابلیت را شامل نمیشود، یا کیف پول هزینهی اجرا را پوشش نمیدهد |
403 | کلید معتبر است، اما دسترسیهایش این فراخوانی را پوشش نمیدهد |
404 | چنین منبعی وجود ندارد، یا متعلق به فضای کاری دیگری است |
409 | اکانت الان نمیتواند این کار را بکند (محدودیت اسپم دارد، هنوز در حال گرمشدن است) |
422 | بدنه از اعتبارسنجی رد شد — پاسخ نام فیلد را میگوید |
429 | درخواستهای بیش از حد، یا اکانت به بودجهی ارسال ساعتی/روزانهاش رسیده |
503 | یکی از وابستگیها از دسترس خارج است؛ دوباره تلاش کنید |
خطاها فیلد detail دارند:
{"detail": "This API key is scoped to inbox — not 'accounts'."}شیء متعلق به فضای کاری دیگر 404 است، هرگز 403 — API هیچوقت وجود یک شناسه را تأیید نمیکند.
قراردادها
- شناسهها UUID هستند. یک بخش مسیر که UUID نباشد
400یا404میگیرد، هرگز 500. - ارسال صف میشود، همزمان نیست. endpointهایی که اکانت را وادار به انجام کاری میکنند
202به همراه یکtask_idبرمیگردانند. سپس اکانت طبق قوانین زمانبندی ضدبن ارسال میکند (به محدودیتها و سهمیهها نگاه کنید). برای دیدن نتیجه، خود منبع را poll کنید. - همهچیز در محدودهی فضای کاری است. هیچوقت شناسهی فضای کاری را نمیفرستید؛ کلید آن را با خود دارد.
- endpointهای لیست بسته به منبع،
limit/offsetیاpage/page_sizeمیگیرند؛ هر دو اختیاریاند.
اکانتها
حوزه: accounts.
| متد | مسیر | کار |
|---|---|---|
GET | /api/accounts | لیست اکانتها |
POST | /api/accounts | افزودن اکانت |
GET | /api/accounts/{id} | یک اکانت |
PATCH | /api/accounts/{id} | تغییر نام، تغییر تگ، تغییر تنظیمات |
DELETE | /api/accounts/{id} | حذف اکانت |
POST | /api/accounts/import | ایمپورت فایل نشست (session) |
POST | /api/accounts/batch-import | ایمپورت چندتایی |
POST | /api/accounts/login/phone/send-code | شروع ورود با شماره تلفن |
POST | /api/accounts/login/phone/verify-code | ارسال کد |
POST | /api/accounts/login/phone/verify-2fa | ارسال رمز 2FA |
POST | /api/accounts/login/qr/start | شروع ورود با QR |
POST | /api/accounts/login/qr/poll | poll کردن آن (long-poll، حدود 20 ثانیه) |
POST | /api/accounts/login/cancel | انصراف از ورود |
POST | /api/accounts/{id}/power | خواباندن یا بیدارکردن اکانت |
POST | /api/accounts/{id}/safety | شلکردن یا خاموشکردن محدودیتهای ضدبن (پلنهای پولی) |
POST | /api/accounts/bulk/safety | همان، برای همهی اکانتها یکجا |
POST | /api/accounts/{id}/profile | تنظیم نام، بیو، عکس |
POST | /api/accounts/{id}/clone-profile | کپی پروفایل یک اکانت دیگر |
GET | /api/accounts/{id}/privacy | تنظیمات حریم خصوصی |
GET | /api/accounts/{id}/photos | عکسهای پروفایل |
GET | /api/accounts/{id}/stats | پیامهای ارسالی/دریافتی امروز |
GET | /api/accounts/{id}/health-log | تاریخچهی امتیاز سلامت |
GET | /api/accounts/{id}/risk | وضعیت فعلی ریسک بن |
GET | /api/accounts/{id}/connections | لاگ ممیزی اتصالها |
GET | /api/accounts/{id}/sessions | درخواستهای ورود — فقط اکانتهای اجارهای |
GET | /api/accounts/{id}/vault | وضعیت گاوصندوق نشست |
GET POST | /api/accounts/{id}/backfill-history | خواندن / شروع واکشی چتهای قدیمی (?discover_only=true = فقط لیست چتها) |
POST | /api/accounts/{id}/backfill-history/cancel | توقف یک واکشی در حال اجرا |
POST | /api/accounts/{id}/reset-status | برگرداندن اکانت error یا paused به active |
GET | /api/accounts/{id}/avatar | عکس پروفایل، بهصورت بایت |
DELETE | /api/accounts/{id}/photos/{photoId} | حذف یک عکس پروفایل |
POST | /api/accounts/{id}/username-check | آیا یک نام کاربری آزاد است، پیش از آنکه بگیریدش |
POST | /api/accounts/{id}/contact-policy | قانون «هر نفر، یک اکانت» — {"single_contact": false} اجازه میدهد این اکانت به کسی پیام بدهد که یکی دیگر از اکانتهای شما از قبل با او صحبت میکند |
POST | /api/accounts/{id}/group-invites | افزودن افراد به گروه — یادداشت پایین را ببینید |
POST | /api/accounts/{id}/skip-warmup | عقببردن ساعت گرمکردن — اکانتهای خودتان هر زمان، اکانتهای اجارهای بعد از 3 روز |
GET | /api/accounts/{id}/session/export | دانلود نشست — فقط اکانتهای خودتان |
POST | /api/accounts/{id}/sessions/{hash}/decision | تأیید یا رد یک درخواست ورود |
POST | /api/accounts/bulk | فعال / غیرفعال / حذف چندتایی |
POST | /api/accounts/bulk/listener | روشن یا خاموشکردن شنوندهی ورودی در کل ناوگان |
POST | /api/accounts/bulk/contact-policy | همان قانون روی همهی اکانتها |
هر ردیف اکانت، بهمحض اینکه worker متصل شد، هویت تلگرامی خود اکانت را هم دارد: tg_user_id (شناسهی عددی تلگرام)، tg_username، tg_first_name، tg_last_name. tg_user_id همان مقداری است که وقتی رشتهی گفتگوی شخص دیگری به این اکانت اشاره میکند، بهعنوان peer_id ظاهر میشود.
گاوصندوق نشست زیر همان اکانت قرار دارد: POST /api/accounts/{id}/vault/enable، /disable، /lock، /unlock، /rotate، و GET /api/accounts/{id}/vault برای وضعیت فعلی.
یادداشت/group-invitesسختگیرترین endpoint محصول است، چون افزودن افراد سریعترین راه از دست دادن اکانت است. مگر اینکه اکانت گرمکردن را تمام کرده باشد، یک رأی پاک از @SpamBot با عمر کمتر از 36 ساعت داشته باشد و در حالت فقطپاسخ نباشد، با409رد میکند.
یادداشت/sessionsمخصوص اکانتهای اجارهای است. روی اکانتی که مال خودتان است پاسخ404 no live allocation for this account on your workspaceمیدهد — این پاسخ درست است، نه یک خطا.
پروکسیها
| متد | مسیر | کار |
|---|---|---|
GET | /api/proxies | لیست پروکسیها |
POST | /api/proxies | افزودن یکی |
POST | /api/proxies/bulk | افزودن چندتایی |
PATCH | /api/proxies/{id} | ویرایش |
POST | /api/proxies/{id}/rotate | چرخش IP خروجی |
DELETE | /api/proxies/{id} | حذف |
PATCH DELETE | /api/proxies/{id}/assign | اتصال / جداکردن یک اکانت |
GET | /api/proxies/{id}/usage | ترافیک مصرفشده |
POST | /api/proxies/{id}/check | تست اتصال |
گرمکردن
| متد | مسیر | کار |
|---|---|---|
GET PUT | /api/warmup/settings | خواندن / جایگزینی تنظیمات گرمکردن |
GET | /api/warmup/overview | وضعیت گرمکردن ناوگان |
GET | /api/warmup/plan | برنامهی تولیدشده |
POST | /api/warmup/plan/apply | اعمال آن |
DELETE | /api/warmup/plan | دورانداختن آن |
POST | /api/warmup/dry-run | پیشنمایش بدون اعمال |
GET | /api/warmup/pairs | کدام اکانتها با کدامها صحبت میکنند |
GET | /api/warmup/groups | گروههای داخل برنامه |
GET | /api/warmup/events | گرمکردن واقعاً چه کرد |
GET POST | /api/warmup/channels | کانالهایی که ناوگان عضو میشود |
DELETE | /api/warmup/channels/{id} | حذف یکی |
GET | /api/warmup/accounts | وضعیت گرمکردن هر اکانت |
POST | /api/warmup/accounts/{id}/social | روشن/خاموشکردن گرمکردن اجتماعی |
محدودیتهای ضدبن
تکتک throttleهای این API — بودجهی پیام سرد و پاسخ، شیب گرمکردن، کندشدن پس از PeerFlood، سقف روزانهی کمپین، فاصلهگذاری در یک گروه و تأخیرهای انساننما — محافظت خود پلتفرم است، نه تلگرام. در پلن پولی میتوانید آن را برای هر اکانت با POST /api/accounts/{id}/safety تغییر دهید یا خاموش کنید، یا برای همهی اکانتها یکجا با POST /api/accounts/bulk/safety:
{
"mode": "custom",
"cold_hourly": 30, "cold_daily": 200,
"reply_hourly": 120, "reply_daily": 600,
"per_minute": 6, "min_gap_seconds": 3,
"campaign_daily": 200, "group_spacing_minutes": 30,
"content_filter": true, "spam_circuit": true,
"warmup_ramp": false, "human_delay": true,
"trial_cap": true, "spambot_throttle": true,
"join_hourly": 40, "join_daily": 60,
"forward_hourly": 20, "forward_daily": 200,
"invite_hourly": 4, "invite_daily": 20,
"report_hourly": 5, "report_daily": 20,
"massdm_daily": 30, "massdm_delay_min": 45, "massdm_delay_max": 120,
"massdm_warmup_ramp": true, "massdm_flood_hold": true, "massdm_circuit": true
}mode یکی از default (قوانین پلتفرم)، custom (اعدادی که خودتان میفرستید؛ هر چه را جا بگذارید مقدار پلتفرمیاش را نگه میدارد؛ 0 روی per_minute، min_gap_seconds، campaign_daily یا group_spacing_minutes یعنی بدون محدودیت) یا off (هیچ throttle پلتفرمیای اصلاً وجود ندارد) است. جفتهای join_*، forward_*، invite_* و report_* بودجهی هر نوع اقدام هستند؛ فیلدهای massdm_* رفتار dispatcher پیام انبوه را کنترل میکنند (massdm_daily سقف هر اکانت را که یک job میتواند درخواست کند بالا میبرد، massdm_circuit تعیین میکند که وقتی اکانتهای یک job با flood یا بلاک برمیگردند، job متوقف شود یا نه؛ تا وقتی حتی یکی از اکانتهای job آن را روشن نگه داشته باشد، job محافظتشده میماند). پروفایل فعلی بهعنوان safety روی شیء اکانت برمیگردد و از ارسال بعدی اثر میکند — بدون نیاز به اتصال مجدد. FloodWait و محدودیتهای اسپم خود تلگرام هر چه هم تنظیم کنید همچنان اعمال میشوند، و ریسک بن یک اکانت شلشده پای خودتان است. پلن Free پاسخ 402 میدهد. قانون «هر نفر، یک اکانت» از این پروفایل جداست و حتی در حالت off روشن میماند؛ آن را برای هر اکانت با /api/accounts/{id}/contact-policy تغییر دهید.
اسکرپینگ
| متد | مسیر | کار |
|---|---|---|
POST GET | /api/scraping/jobs | شروع / لیست jobها |
GET | /api/scraping/jobs/{id} | وضعیت |
POST | /api/scraping/jobs/{id}/cancel | لغو |
GET | /api/scraping/jobs/{id}/results | نتایج بهصورت JSON |
GET | /api/scraping/jobs/{id}/export | نتایج بهصورت .xlsx |
GET | /api/scraping/jobs/{id}/export.csv | نتایج بهصورت CSV |
POST | /api/scraping/jobs/{id}/webhook | ارسال نتایج به URL شما |
GET | /api/scraping/usage | سهمیهی مصرفشده در این دوره |
اسکرپینگ یک استخراج یکباره است، نه یک مانیتور: یک اکانت یک بار تاریخچهی پیامهای هدف را میگردد و شمارههای تلفن (یا الگوهایی که به آن میدهید) را بیرون میکشد. کانالهای broadcast هم بهعنوان هدف کار میکنند، اما پستهایشان از طرف خود کانال است، بنابراین اجرای روی کانال بهندرت شمارهای برمیگرداند. برای دنبالکردن چیزی که یک کانال منتشر میکند، بهجای آن از مانیتورکردن یک کانال استفاده کنید. دورهی آزمایشی رایگان نتایج را میشمارد، نه پیامهای اسکنشده، بنابراین اجرایی که چیزی پیدا نکند هزینهای ندارد.
POST /api/scraping/jobs
{
"name": "leads",
"group_links": ["https://t.me/somepublicgroup"],
"limit_per_group": 300,
"max_accounts": 5,
"patterns": [],
"keyword_filter": []
}patterns خالی یعنی شمارهی تلفن؛ انواع پیشفرض دیگر email، username، url و price هستند، و الگوی custom regex خودتان را میگیرد. group_links هم گروههای عمومی را میپذیرد و هم کانالهای عمومی.
اجرای عمیق پولی بهازای هر پیام اسکنشده محاسبه میشود و اگر کیف پول بدترین حالت را پوشش ندهد 402 برمیگرداند. دورهی آزمایشی رایگان طور دیگری شمرده میشود: 50 نتیجه است، بنابراین اجرایی که چیزی پیدا نکند هزینهای برای شما ندارد. از آن طرف هم محدود است — اجراهای رایگان بعد از خواندن مجموعاً 2,000 پیام متوقف میشوند، هر چه هم برگردانده باشند. GET /api/scraping/usage هر دو شمارنده را گزارش میکند (used / limit و scanned / scan_limit).
نیچیاب
| متد | مسیر | کار |
|---|---|---|
POST | /api/niche/suggest | پیشنهاد کلیدواژه |
POST GET | /api/niche/jobs | شروع / لیست jobها |
GET | /api/niche/jobs/{id} | وضعیت |
GET | /api/niche/jobs/{id}/sources | کدام گروهها را خوانده |
POST | /api/niche/jobs/{id}/cancel | لغو |
GET | /api/niche/jobs/{id}/results | مخاطبان کشفشده |
GET | /api/niche/jobs/{id}/export | همان، بهصورت .xlsx |
POST /api/niche/jobs
{
"name": "crypto traders",
"keywords": ["trading", "signals"],
"active_within_days": 30,
"msg_scan_limit": 3000,
"max_accounts": 5,
"extract_members": false
}extract_members لیست خام اعضا را بیرون میریزد؛ بهطور پیشفرض خاموش است چون همین خواندن است که ریسک بن دارد.
پکیجهای لید و watchها
| متد | مسیر | کار |
|---|---|---|
GET | /api/packages | پکیجهای در حال فروش |
GET | /api/packages/{id} | یک پکیج |
POST | /api/packages/{id}/buy | خرید آن (از کیف پول کسر میشود) |
GET | /api/packages/{id}/download | دانلود پکیج خریدهشده |
POST | /api/packages/{id}/publish | گذاشتن یکی از پکیجهای خودتان برای فروش |
DELETE | /api/packages/{id} | برداشتن آن از فروش |
GET | /api/watches/plans | پلنهای اسکرپ دورهای |
GET POST | /api/watches | لیست / ساخت watch |
GET | /api/watches/{id} | یک watch |
POST | /api/watches/{id}/pause | توقف موقت |
POST | /api/watches/{id}/resume | ادامه |
DELETE | /api/watches/{id} | حذف |
پیام انبوه
| متد | مسیر | کار |
|---|---|---|
GET | /api/mass-dm/accounts | اکانتهای واجد شرایط ارسال |
POST GET | /api/mass-dm/jobs | ساخت / لیست کمپینها |
GET | /api/mass-dm/jobs/{id} | پیشرفت |
GET | /api/mass-dm/jobs/{id}/recipients | وضعیت هر گیرنده |
GET | /api/mass-dm/jobs/{id}/replies | کی جواب داده |
GET | /api/mass-dm/jobs/{id}/export | همهچیز، بهصورت .xlsx |
GET POST | /api/mass-dm/suppression | لیست «تماس نگیرید» |
DELETE | /api/mass-dm/suppression/{tgUserId} | حذف یک مورد |
POST | /api/mass-dm/jobs/{id}/pause | توقف موقت کمپین در حال اجرا |
POST | /api/mass-dm/jobs/{id}/resume | ادامهی کمپین متوقفشده |
POST | /api/mass-dm/jobs/{id}/cancel | توقف دائمی آن |
GET | /api/mass-dm/contacts/{tgUserId} | آنچه از یک مخاطب میدانیم |
POST /api/mass-dm/jobs
{
"recipients": [{"tg_user_id": 123456789, "username": "someone"}],
"message_text": "hi {first_name}",
"account_ids": ["<account-uuid>"],
"per_account_daily_cap": 20,
"followups": []
}یا recipients را بدهید یا niche_job_id را، نه هر دو. suppression یک لیست میگیرد:
POST /api/mass-dm/suppression
{"tg_user_ids": [777000777], "reason": "opted out"}اینباکس
حوزه: inbox.
| متد | مسیر | کار |
|---|---|---|
GET | /api/conversations | لیست گفتگوها |
POST | /api/conversations | شروع یک چت جدید (202) |
GET | /api/conversations/search | جستوجوی تماممتن (?q=) |
GET | /api/conversations/{id}/messages | پیامهای یک رشتهی گفتگو |
POST | /api/conversations/{id}/messages | ارسال پاسخ (202) |
PATCH | /api/conversations/{id} | واگذاری، تگ، حلشده، بیصدا |
POST | /api/conversations/{id}/mark-read | خواندهشده کردن |
DELETE | /api/conversations/{id} | حذف رشتهی گفتگو |
POST | /api/conversations/media | آپلود پیوست و گرفتن media_key |
GET | /api/conversations/{id}/messages/{msgId}/media | دانلود پیوست |
POST | /api/conversations/{id}/messages/{msgId}/fetch-media | واکشی رسانهی یک placeholder |
GET POST | /api/conversations/{id}/notes | یادداشتهای داخلی |
DELETE | /api/conversations/{id}/notes/{noteId} | حذف یک یادداشت |
POST | /api/conversations/{id}/block | بلاککردن طرف مقابل |
POST | /api/conversations/{id}/leave | خروج از گروه |
GET | /api/conversations/sla-stats | آمار زمان پاسخ |
GET | /api/conversations/account-stats | حجم پیام هر اکانت |
GET | /api/conversations/activity-series | حجم پیام در طول زمان |
GET | /api/conversations/reply-stats | نرخ پاسخ — به ?source= نیاز دارد |
فیلترهای لیست: account_id، peer_type (user / bot / group / channel)، status، tags، unread_only، source (campaign / mass_dm)، campaign_id، job_id، page، page_size.
reply-stats به source=campaign&campaign_id=... یا source=mass_dm&job_id=... نیاز دارد؛ بدون آنها با 422/400 جواب میدهد و میگوید چه چیزی کم است.
مانیتورکردن یک کانال
کانال broadcast هم گفتگویی مثل بقیه است — peer_type آن channel است — اما پستهایش opt-in هستند. یک کانال پرکار میتواند روزانه صدها مگابایت از پروکسی یک اکانت رد کند، بنابراین شنونده پستهای هر کانالی را که خودتان درخواست نکردهاید دور میریزد. به همین دلیل کانالی که عضوش شدهاید تا وقتی آن را اضافه نکنید هیچ چیزی نشان نمیدهد: پشتیبانیاش کم نیست، خاموش است.
روشنکردن یکی:
- با یکی از اکانتهای خودتان (در خود تلگرام) به کانال بپیوندید.
- آن را به فهرست پایش اضافه کنید:
POST /api/groupsبا بدنهی{"identifier": "@thechannel", "type": "channel", "via_account_id": "<uuid>"}. - پستها را بخوانید:
GET /api/conversations?peer_type=channelو بعدGET /api/conversations/{id}/messages?after_msg_id=<last seen>.
identifier یک @username عمومی، یک لینک t.me/name یا یک شناسهی عددی peer میگیرد. type میتواند group، supergroup یا channel باشد؛ هر چه بفرستید در اولین همگامسازی از روی تلگرام تصحیح میشود، همراه با members_count، posts_per_day و شناسهی marked peer.
کانالهای خصوصی @username ندارند، و لینک دعوت (t.me/+…) هم شناسهی peer ندارد، بنابراین هیچکدام نمیتواند یکی را مشخص کند. یک بار لیست چتهای اکانت را همگام کنید و کانال با شناسهی عددیاش ظاهر میشود، که بعد آن را به روش معمول اضافه میکنید:
POST /api/accounts/{account_id}/backfill-history?discover_only=true
→ registers the account's chats, pulls no messages, costs almost no proxy data
GET /api/conversations?peer_type=channel
→ the private channel is now listed, with its peer_id
POST /api/groups
{"identifier": "-1001234567890", "type": "channel", "via_account_id": "<uuid>"}در داشبورد همین جریان همان انتخابگر کانال در Groups → Track group است.
وقتی ردیابی شد، پستهای جدید مثل هر پیام ورودی دیگری میرسند: روی رویداد وبسوکت inbox.new_message و روی وبهوکی که به آن مشترک شده باشد. کانالی که در تلگرام بیصدا کردهاید همچنان هر دو را میفرستد، با conversation.muted: true، بنابراین یک یکپارچهسازی هیچ پستی را از دست نمیدهد؛ فقط داشبورد ساکت میماند.
peer_type چهار مقدار دارد: user، bot، group و channel. سوپرگروهها group هستند — این تفاوت فقط برای /api/groups مهم است، که بعد از اولین همگامسازیاش supergroup را گزارش میکند.
وقتی کانالی مانیتور میشود، پستهایش مثل هر پیام دیگری میرسند: در GET /api/conversations/{id}/messages، روی رویداد وبسوکت inbox.new_message، و از طریق وبهوکی که به inbox.new_message مشترک شده است.
دو چیزی که این قابلیت *نیستند*: /api/channel-syncs پستهای یک کانال را در کانال دیگری که در کنترل شماست آینه میکند (یک forwarder است، نه خواننده)، و /api/warmup/channels لیست کانالهایی است که اکانت جدید در حین گرمشدن عضوشان میشود. هیچکدام محتوای کانال را برنمیگردانند. POST /api/groups/{id}/sync فقط شمار اعضا و پستها را تازه میکند — پستها را واکشی نمیکند.
دنبالکردن یک رشتهی گفتگو
پیامهای ورودی فقط برای اکانتهایی ثبت میشوند که شنوندهی پیامشان روشن است. اکانتی که در GET /api/accounts مقدار power_sender_only: true دارد میفرستد اما هرگز دریافت نمیکند، بنابراین هر چقدر هم poll کنید رشتههایش خالی میمانند — اول شنونده را برایش روشن کنید.
GET /api/conversations/{id}/messages بهطور پیشفرض رو به عقب صفحهبندی میکند (before، before_msg_id، limit تا 200) — همان چیزی که یک UI وقتی به بالا اسکرول میکنید میخواهد.
یک مانیتور برعکسش را میخواهد. after_msg_id را با telegram_msg_id جدیدترین پیامی که از قبل دارید بفرستید و فقط آنچه از آن زمان رسیده را، از قدیمیترین به جدیدترین، میگیرید:
GET /api/conversations/{id}/messages?after_msg_id=19626585&limit=200telegram_msg_id داخل یک چت بهصورت یکنوا افزایش مییابد، بنابراین این cursor هیچ پیامی را تکرار نمیکند و هیچکدام را جا نمیاندازد. بالاترین شناسهای که دیدهاید را نگه دارید، با آن poll کنید، و دیگر چیزی برای حذف تکراریها نمیماند. اگر هر دو را بفرستید، after_msg_id بر before/before_msg_id غلبه میکند.
هر پیام یک direction دارد: in برای پیامهایی که اکانت دریافت کرده، out برای پیامهایی که از طریق این پلتفرم فرستاده شدهاند. پیامهایی که با دست در یک کلاینت تلگرام روی همان اکانت تایپ شدهاند ثبت نمیشوند — تلگرام آنها را بهعنوان آپدیتهای خروجی خودتان میفرستد و شنونده آنها را نادیده میگیرد.
برای push بهجای polling، به وبهوکها و رویدادهای بلادرنگ در ادامه نگاه کنید.
ارسال
پاسخ در یک رشتهی گفتگوی موجود:
POST /api/conversations/{id}/messages
{"content": "Thanks — one moment.", "media_key": null}شروع گفتگو با کسی که هنوز در اینباکس نیست:
POST /api/conversations
{
"account_id": "<account-uuid>",
"recipient_type": "username",
"recipient": "someone",
"content": "hello"
}recipient_type یکی از username، phone یا user_id است. هر دو endpoint پاسخ 202 میدهند:
{"task_id": "...", "conversation_id": null, "queued": true,
"note": "Message queued. It will appear in the inbox once Telegram acknowledges the send."}پیام بهمحض اینکه تلگرام ارسال را تأیید کند در GET /api/conversations/{id}/messages ظاهر میشود — معمولاً چند ثانیه، و اگر اکانت به سقف زمانبندی ساعتیاش رسیده باشد بیشتر.
گاردهای ضدبن پیش از اینکه چیزی صف شود جواب میدهند، پس آنها را مدیریت کنید:
- اکانتی که محدودیت اسپم دارد و میخواهد یک چت را از صفر شروع کند:
Telegram has limited this account, so it can't start new conversations right now — it can still reply to people who messaged it. - اکانت در حال گرمشدن نمیتواند گفتگو را شروع کند، فقط میتواند پاسخ بدهد.
- فیلتر محتوا متن را با
422و یک کد داخل براکت رد میکند —[REPEATED_CHARS]،[EXCESSIVE_CAPS]،[TOO_MANY_LINKS]،[BLOCKED_LINK]،[SPAM_PATTERN]. متن را درست کنید و دوباره بفرستید؛ تلاش مجدد با همان بدنه همیشه شکست میخورد. - بودجهی ارسال لغزان با
429و[HOURLY_MESSAGE_LIMIT]یا[DAILY_MESSAGE_LIMIT]جواب میدهد. پیام سرد به 10 پیام در ساعت و 40 در روز برای هر اکانت محدود است. وقتی طرف مقابل جواب داد، هر پیام بعدی در آن رشته بهعنوان پاسخ شمرده میشود و بهجایش 60 در ساعت و 300 در روز میگیرد — چه از طریقPOST /api/conversations/{id}/messagesبفرستید و چه همچنانPOST /api/conversationsرا با همان گیرنده فراخوانی کنید. پنجرهی ساعتی پیوسته میلغزد، پس بهجای بازنویسی پیام عقب بنشینید. اکانتی که امتیاز سلامتش افت کرده بودجهی متناسباً کوچکتری میگیرد. پلنهای پولی میتوانند این بودجهها را برای هر اکانت تغییر دهند یا حذف کنند — به محدودیتهای ضدبن نگاه کنید؛ پروفایل custom کدهای[MINUTE_MESSAGE_LIMIT]و[MESSAGE_GAP_LIMIT]را هم به کدهای ممکن429اضافه میکند.
فقط 202 یعنی ارسال در راه است. اگر بعداً باز هم شکست بخورد — گیرنده اکانت را بلاک کرده، اکانت آفلاین شده — دلیلش بهصورت وبهوک inbox.message_failed با همان task_id میرسد.
گروهها، پاسخها، قوانین، اعلانها
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/groups | گروهها و کانالهای ردیابیشده |
PATCH DELETE | /api/groups/{id} | ویرایش / حذف از ردیابی |
POST | /api/groups/{id}/sync | تازهکردن شمار اعضا و پستها |
GET | /api/groups/{id}/stats | فعالیت |
GET POST | /api/saved-replies | پاسخهای آماده |
PUT DELETE | /api/saved-replies/{id} | ویرایش / حذف |
GET POST | /api/auto-reply-rules | قوانین پاسخ خودکار |
POST | /api/auto-reply-rules/bulk | ساخت چندتایی |
PATCH DELETE | /api/auto-reply-rules/{id} | ویرایش / حذف |
GET | /api/notifications | فید اعلانها |
GET | /api/notifications/unread-count | شمارندهی badge |
PATCH | /api/notifications/read-all | خواندهشده کردن همه |
GET PUT | /api/notifications/preferences | تنظیمات هر دسته |
PATCH | /api/notifications/{id}/read | خواندهشده کردن یکی |
DELETE | /api/notifications/{id} | رد کردن یکی |
GET POST | /api/api-connectors | کانکتورهای پاسخ خارجی |
GET | /api/api-connectors/kinds | انواع کانکتوری که میتوانید بسازید |
PATCH DELETE | /api/api-connectors/{id} | ویرایش / حذف |
POST | /api/api-connectors/{id}/test | تست یکی |
GET | /api/conversations/{id}/avatar | عکس چت، بهصورت بایت |
GET | /api/conversations/{id}/peer-avatar | عکس طرف مقابل |
POST /api/groups
{"identifier": "https://t.me/somepublicgroup", "type": "group", "via_account_id": "<uuid>"}
POST /api/saved-replies
{"title": "greeting", "content": "Hi {first_name}", "variables": ["first_name"]}
POST /api/auto-reply-rules
{
"account_id": "<account-uuid>",
"match_type": "contains",
"match_value": "price",
"reply_text": "Our pricing is on the site.",
"is_active": true,
"delay_min": 2,
"delay_max": 8
}match_type یکی از any، exact، contains، regex است.
باتها
حوزه: bots.
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/bots | لیست / ثبت باتها |
DELETE | /api/bots/{id} | حذف |
POST | /api/bots/{id}/active | فعال / غیرفعال |
POST | /api/bots/{id}/delivery-mode | polling یا webhook |
POST | /api/bots/{id}/broadcast | ارسال همگانی به چتهایش |
GET | /api/bots/{id}/chats | چتهایی که به آنها دسترسی دارد |
GET POST | /api/bots/{id}/flows | فلوهای بصری |
GET | /api/bots/flows/templates | قالبهای شروع |
POST | /api/bots/{id}/flows/templates/{templateId}/instantiate | ساخت فلو از یک قالب |
GET PUT DELETE | /api/bots/{id}/flows/{flowId} | یک فلو |
POST | /api/bots/{id}/flows/{flowId}/test | اجرای آزمایشی (dry-run) |
GET | /api/bots/{id}/runs | تاریخچهی اجرای فلو |
GET | /api/bots/{id}/runs/{runId}/steps | جزئیات هر مرحله |
کمپینها
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/campaigns | لیست / ساخت (در حالت draft ساخته میشود) |
GET | /api/campaigns/{id} | یک کمپین |
POST | /api/campaigns/{id}/start | شروع |
POST | /api/campaigns/{id}/pause | توقف موقت |
POST | /api/campaigns/{id}/stop | توقف |
PATCH | /api/campaigns/{id}/assignments | واگذاری مجدد اکانتها و گروهها |
POST | /api/campaigns/{id}/import-chatlist | افزودن انبوه گروههای هدف |
GET | /api/campaigns/{id}/metrics | ارسالها، شکستها، دسترسی (reach) |
DELETE | /api/campaigns/{id} | حذف |
POST /api/campaigns
{
"name": "launch",
"message_a": {"text": "..."},
"message_b": {"link": "https://t.me/channel/123"},
"interval_minutes": 30,
"delay_min_seconds": 15,
"delay_max_seconds": 90,
"assignments": [{"account_id": "<uuid>", "group_chat_ids": [-1001234567890]}]
}ساختن، آن را شروع نمیکند — /start را فراخوانی کنید.
همگامسازی کانالها و دیتابیس بات
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/channel-syncs | آینههای کانالبهکانال — پستها را فوروارد میکند، برای شما نمیخواند |
GET PATCH DELETE | /api/channel-syncs/{id} | یک آینه |
POST | /api/channel-syncs/{id}/arm | مسلحکردن (arm) |
POST | /api/channel-syncs/{id}/disarm | خلع سلاح (disarm) |
POST | /api/channel-syncs/{id}/run | یک بار همین حالا اجرا |
GET POST | /api/botdb/collections | کالکشنها |
GET PUT DELETE | /api/botdb/collections/{id} | یک کالکشن |
GET POST | /api/botdb/collections/{id}/records | رکوردها |
POST | /api/botdb/collections/{id}/query | فیلتر / مرتبسازی / صفحهبندی |
PUT DELETE | /api/botdb/collections/{id}/records/{recordId} | یک رکورد |
GET POST | /api/botdb/collections/{id}/views | نماهای ذخیرهشده |
POST /api/botdb/collections
{"name": "leads", "schema": {"fields": [{"key": "email", "type": "text"}]}}
POST /api/botdb/collections/{id}/records
{"data": {"email": "a@b.com"}}تعریف فیلدها از key استفاده میکند (نه name)، و رکوردی که در data کلیدی اعلامنشده داشته باشد با unknown field(s): ... رد میشود.
آنالیتیکس
حوزه: analytics.
| متد | مسیر | کار |
|---|---|---|
GET | /api/analytics/summary | مجموعهای دوره |
GET | /api/analytics/daily | سری روزبهروز |
GET | /api/analytics/timeline | خط زمانی رویدادها |
GET | /api/analytics/accounts/{id}/timeline | خط زمانی یک اکانت |
GET | /api/analytics/velocity | سرعت ارسال |
GET | /api/analytics/anomalies | ناهنجاریهای شناساییشده |
GET | /api/analytics/anomalies/{accountId} | ناهنجاریهای یک اکانت |
POST | /api/analytics/ai/anomalies/detect | اجرای شناسایی همین حالا |
GET | /api/analytics/ai-insights | بینشهای روایی روی ناوگان |
GET | /api/analytics/report | payload کامل گزارش |
GET | /api/analytics/ai/summary | خلاصهی روایی AI |
GET | /api/analytics/ai/daily-digest | خلاصهی روزانه (بر حسب ثانیه، نه میلیثانیه) |
POST | /api/analytics/ai/suggest-replies | پیشنهاد پاسخ |
POST | /api/analytics/ai/summarize-conversation | خلاصهکردن یک رشتهی گفتگو |
POST | /api/analytics/ai/sentiment | احساسات یک رشتهی گفتگو |
POST | /api/analytics/ai/send-risk | امتیاز ریسک بن برای یک پیشنویس |
POST | /api/analytics/ai/compose-message | پیشنویس یک پیام |
POST | /api/analytics/ai/suggest-posts | ایدههای محتوا |
POST | /api/analytics/ai/template-variations | تولید نسخههای متفاوت از یک قالب |
GET | /api/analytics/ai/quota | اعتبار AI باقیمانده |
وقتی سوییچ آنالیتیکس فضای کاری خاموش باشد، اینها بهجای خطا سریهای خالی برمیگردانند. endpointهای AI از سهمیهی AI مصرف میکنند: اول /api/analytics/ai/quota را چک کنید، و وقتی تمام شد انتظار 429 داشته باشید.
ورکفلوها
حوزه: tasks.
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/workflows | لیست / ساخت |
GET PUT DELETE | /api/workflows/{id} | یک ورکفلو |
POST | /api/workflows/{id}/run | اجرای همین حالا |
GET | /api/workflows/{id}/stats | تعداد اجراها و نرخ موفقیت |
POST DELETE | /api/workflows/{id}/schedule | اتصال / حذف زمانبندی cron |
GET | /api/executions | تاریخچهی اجراها |
POST | /api/executions | شروع یک اجرا |
GET | /api/executions/{id} | یک اجرا |
GET | /api/executions/{id}/steps | وضعیت هر گره |
DELETE | /api/executions/{id} | لغو یک اجرای در حال انجام |
POST /api/workflows
{"name": "nightly", "definition": {"nodes": [], "edges": []}}پشتیبانی
بدون حوزه — هر کلیدی به اینها میرسد.
| متد | مسیر | کار |
|---|---|---|
GET POST | /api/support/tickets | لیست / ثبت تیکت |
GET | /api/support/tickets/{id} | یک تیکت با رشتهی گفتگویش |
POST | /api/support/tickets/{id}/messages | پاسخ |
POST | /api/support/tickets/{id}/close | بستن آن |
POST | /api/support/tickets/{id}/seen | خواندهشده کردن رشته |
GET | /api/support/unread-count | شمارندهی badge |
هویت
| متد | مسیر | کار |
|---|---|---|
GET | /auth/me | این کلید متعلق به کیست، و پلن او |
ویرایش پروفایل (PATCH /auth/me)، مثل مدیریت کلیدها، به نشست مرورگر نیاز دارد — کلید پاسخ 403 میگیرد.
وبهوکها
وبهوک راه پایدار دریافت رویدادهاست: ما اول رویداد را در دیتابیس خودمان مینویسیم، بعد آن را به URL شما POST میکنیم و در صورت شکست دوباره تلاش میکنیم. سوکتی که در حین دیپلوی شما قطع شده رویداد را از دست میدهد؛ وبهوک نه.
آنها را در Settings → API keys → Webhooks مدیریت کنید، یا از طریق API (حوزهی inbox):
| متد | مسیر | کار |
|---|---|---|
GET | /api/webhooks | لیست endpointهای شما |
POST | /api/webhooks | ثبت یکی — پاسخ secret امضا را با خود دارد |
PATCH | /api/webhooks/{id} | تغییر URL، لیست رویدادها، یا خاموشکردن |
DELETE | /api/webhooks/{id} | حذف آن |
GET | /api/webhooks/events | کاتالوگ رویدادها |
GET | /api/webhooks/{id}/secret | خواندن دوبارهی secret امضا |
POST | /api/webhooks/{id}/rotate-secret | صدور secret جدید |
POST | /api/webhooks/{id}/test | صفکردن یک تحویل webhook.test (202) |
GET | /api/webhooks/{id}/deliveries | آخرین تحویلها، با وضعیت و خطا |
POST /api/webhooks
{"url": "https://your-server.example/telegramos",
"events": ["inbox.new_message"],
"description": "prod monitor"}لیست events خالی یعنی همهی انواع. حداکثر ده endpoint برای هر کاربر؛ URL باید یک آدرس عمومی http(s) باشد (آدرسهای خصوصی و loopback رد میشوند).
رویدادها
| نوع | زمان اجرا |
|---|---|
inbox.new_message | پیامی به یک گفتگو رسید، یا از آن فرستاده شد |
inbox.message_failed | یک ارسال صفشده انجام نشد — error_code، یک message قابلخواندن برای انسان، task_id و recipient را با خود دارد |
inbox.read | یک گفتگو خواندهشده شد |
account.status_change | وضعیت یک اکانت تغییر کرد (active، paused، error، banned) |
account.health_update | امتیاز سلامت یک اکانت تغییر کرد |
account.trust_changed | سطح اعتماد یک اکانت تغییر کرد |
account.power_changed | یک اکانت خوابانده یا بیدار شد |
account.presence | worker یک اکانت به تلگرام متصل شد یا از آن جدا شد |
notification.new | یک اعلان پلتفرم صادر شد |
webhook.test | فقط از دکمه/endpoint تست |
بستن حلقهی یک ارسال. یک ارسال با 202 و یک task_id جواب میدهد و دیگر هیچ — اکانت هنوز باید آن را از زمانبندی تلگرام رد کند. به هر دو رویداد inbox.new_message و inbox.message_failed مشترک شوید و میفهمید کدام اتفاق افتاده: موفقیت بهصورت پیامی با direction: "out" میرسد، شکست بهصورت inbox.message_failed با همان task_id، یک error_code (blocked_by_user، privacy_restricted، account_offline، cannot_write، account_banned، …) و یک جمله که میتوانید به کاربر نشان دهید.
درخواستی که ما میفرستیم
POST /your-path
Content-Type: application/json
X-TGP-Event: inbox.new_message
X-TGP-Delivery: 82a91c75-7446-4ebe-8f79-3013cceaa1d7
X-TGP-Timestamp: 1787308800
X-TGP-Signature: v1=<hex>
{"id": "<delivery id>", "type": "inbox.new_message",
"created_at": "2026-08-20T10:27:04+00:00",
"data": {"user_id": "...", "account_id": "...", "conversation_id": "...",
"message": {"id": "...", "direction": "in", "sender_id": 123, "sender_username": "...",
"content": "...", "sent_at": "..."},
"conversation": {"id": "...", "title": "...", "peer_id": 123,
"peer_username": "...", "peer_type": "channel", "muted": false}}}conversation.id برای رشتهی گفتگوی یک اکانت با یک peer ثابت است، پیام از هر طرفی که برود: پیام خروجی یک اکانت و پاسخ به آن همان conversation.id را دارند، پس همین کلیدی است که باید روی آن مشترک شوید. peer_id همیشه شناسهی تلگرام طرف مقابل است، هرگز شناسهی خود اکانت نیست، و message.direction میگوید کی آن را نوشته: out اکانت است، in طرف مقابل. message.sender_id / message.sender_username آن را صریح میکنند: در in شناسه و نام کاربری تلگرام طرف مقابل، در out شناسه و نام کاربری خود اکانت (null برای عضو گروه یا کانال، که هویتش را حمل نمیکنیم). دو اکانت خودتان که با هم صحبت میکنند دو رشتهی گفتگو تولید میکنند (یکی برای هر اکانت)، هر کدام با شناسهی خودش.
تأیید امضا. HMAC-SHA256 روی {timestamp}.{raw body} با secret شما، که با مقدار hex بعد از v1= مقایسه میشود. از بایتهای خام استفاده کنید — سریالسازی دوبارهی JSON آنها را تغییر میدهد.
import hmac, hashlib
def verify(secret: str, headers, raw_body: bytes) -> bool:
ts = headers["X-TGP-Timestamp"]
expected = "v1=" + hmac.new(
secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(headers["X-TGP-Signature"], expected)timestamp داخل محتوای امضاشده است، بنابراین هر چیزی را که بیش از چند دقیقه قدمت دارد رد کنید تا یک تحویل ضبطشده بعداً نتواند دوباره روی شما replay شود.
قواعد تحویل
- هر
2xxبهمعنای پذیرش است. سریع جواب بدهید و کار را بعدش انجام دهید — ما بعد از 10 ثانیه از یک درخواست دست میکشیم و آن را شکست حساب میکنیم. - شکستها بعد از 10 ثانیه، 1 دقیقه، 5 دقیقه، 30 دقیقه و 2 ساعت دوباره تلاش میشوند — در مجموع شش تلاش — و بعد تحویل
failedعلامت میخورد. - پنج رویداد پشتسرهم که همهی تلاشهای مجدد را تمام کنند endpoint را خاموش میکنند؛ داشبورد دلیلش را نشان میدهد. روشنکردن دوباره شمارنده را صفر میکند.
- ریدایرکتها دنبال نمیشوند. ما را به URL نهایی هدایت کنید.
- شناسهی تحویل در تلاشهای مجدد ثابت میماند — حذف تکراریها را روی آن کلید کنید.
- رکوردهای تحویلشده 7 روز نگه داشته میشوند، شکستخوردهها 30 روز.
رویدادهای بلادرنگ
داشبورد آپدیتهای زنده را از طریق Socket.IO استریم میکند:
wss://telegramos.net/wsبا JWT نشست (auth.token)، کوکی نشست، یا یک کلید API احراز هویت کنید — آن را بهصورت auth.apiKey در handshake یا بهصورت هدر X-API-Key بفرستید. کلید به read نیاز دارد، و اگر اصلاً محدود به حوزه است باید inbox را شامل شود.
import { io } from 'socket.io-client'
const socket = io('https://telegramos.net', {
path: '/ws',
transports: ['websocket'],
auth: { apiKey: process.env.TGP_API_KEY },
})
socket.on('inbox.new_message', (e) => console.log(e.conversation_id, e.message.content))رویدادها بهصورت پیامهای نامدار Socket.IO میرسند: system.connected هنگام اتصال، بعد inbox.new_message، notification.new، account.status_change، account.power_changed و امثال آن؛ برای اشتراک روی یک اکانت از subscribe:account استفاده کنید.
دو چیز که پیش از ساختن روی آن باید بدانید:
- مرورگرها محدود هستند. handshake هدر
Originرا چک میکند و فقط دامنههای خود ما مجازند. کلاینت سمت سرورOriginنمیفرستد و بیمشکل متصل میشود؛ صفحهای روی دامنهی خودتان رد میشود. از طریق بکاند خودتان پروکسی کنید. - سوکت فقط یک بار تحویل میدهد. هر چیزی که در زمان قطعبودن شما منتشر شده باشد از دست رفته است. برای تحویلی که نمیتوانید از دستش بدهید از وبهوک استفاده کنید، یا هنگام اتصال مجدد با
after_msg_idوضعیت را همگام کنید.
چه چیزهایی را API پوشش نمیدهد
- تیمها، صورتحساب، کیف پول و مارکتپلیس فقط با نشست کار میکنند:
/wallet،/payments/*،/subscriptions/*،/billing/*،/bundles/purchase،/account-resale/*،/referrals/*و/teams/*به کلید API، با هر محدودهای که داشته باشد،401میدهند. هیچ مسیر مبتنی بر کلیدی برای خرجکردن پول، اجارهی اکانت یا تغییر seatها وجود ندارد — اینها را در داشبورد انجام دهید. دو استثنا خواندنهای کاتالوگ عمومیGET /listingsوGET /bundles/availabilityهستند که اصلاً به احراز هویت نیاز ندارند. - SDK ندارد. HTTP ساده؛ از هر کلاینتی که دارید استفاده کنید.
- محدودیت نرخ بهازای کلید ندارد. درخواستها ارزاناند، اما اقدامات پشت آنها بهازای هر اکانت با محدودیتهای ضدبن در محدودیتها و سهمیهها زمانبندی میشوند، بنابراین یک رگبار ارسال صف میشود، نه اینکه یکجا شلیک شود.
یک مثال عملی
پاسخ به جدیدترین گفتگوی خواندهنشده و انتظار برای رسیدن ارسال:
KEY="tgp_your_key_here"
BASE="https://telegramos.net"
CONV=$(curl -s -H "X-API-Key: $KEY" \
"$BASE/api/conversations?unread_only=true&page_size=1" \
| python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])")
curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-H "X-Request-ID: reply-$CONV" \
-d '{"content":"Thanks for reaching out — one moment."}' \
"$BASE/api/conversations/$CONV/messages"
# -> 202 {"task_id": "...", "queued": true, ...}
curl -s -H "X-API-Key: $KEY" "$BASE/api/conversations/$CONV/messages" | tail -c 400مانیتورکردن یک گفتگو
سه جزء متحرک، به ترتیبی که راهشان میاندازید.
1. اگر تاریخچه را میخواهید، یک بار backfill کنید. POST /api/accounts/{id}/backfill-history یک ایمپورت یکباره از چتهای موجود را صف میکند (اکانتهای خودتان، بدون رسانه، تا 1000 پیام در هر چت؛ کانالهای broadcast فقط وقتی شامل میشوند که از طریق POST /api/groups ردیابی شده باشند). GET /api/accounts/{id}/backfill-history را poll کنید تا state به done برسد — وضعیتها queued، running، done، cancelled هستند، و idle یعنی هیچ jobای ثبت نشده (یا هرگز شروع نشده یا وضعیتش بعد از 6 ساعت منقضی شده). برای هر اکانت یک بار اجرایش کنید؛ روی دادهی پروکسی سنگین است و هر چه بعد از آن باشد خودش میرسد.
2. استریم زنده را بگیرید. یک وبهوک برای inbox.new_message ثبت کنید. برای اینکه پیامها همچنان به اینباکس بریزند چیز دیگری لازم نیست — worker اکانت از قبل در حال شنیدن است.
3. همگام کنید. بعد از هر قطعی در سمت شما، هر گفتگو را با after_msg_id از آخرین شناسهای که ذخیره کردهاید رو به جلو بگردید. این کار شکاف را بدون بازخوانی کل رشته میبندد.
KEY="tgp_your_key_here"
BASE="https://telegramos.net"
curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"url":"https://your-server.example/telegramos","events":["inbox.new_message"]}' \
"$BASE/api/webhooks"
# -> 201 {"id": "...", "secret": "whsec_...", ...} <- store the secret
curl -s -H "X-API-Key: $KEY" \
"$BASE/api/conversations/$CONV/messages?after_msg_id=$LAST_SEEN&limit=200"