ONPChat API v1
FA EN AR

API آنپی‌چت

پیام‌هایت را از هر برنامه یا سروری، در کانال و گروه و کلاس و سانترالِ خودت منتشر کن.

https://api.onpchat.ir

دانلود openapi.yaml

فایلِ OpenAPI 3.1 است: در Postman و Insomnia مستقیم import می‌شود و از رویش برای زبانِ خودت SDK ساخته می‌شود.

curl https://api.onpchat.ir/v1/me \
  -H "Authorization: Bearer $ONP_TOKEN"

شروع سریع

  1. توکن بگیر. با حسابی که مدیرِ آن فضاست وارد شو و این آدرس را باز کن:

    شناسه با پیشوندش می‌آید و در URL باید encode شود — مثلاً کانالِ #1786551855736 می‌شود %231786551855736. اگر توکن نداشته باشی، همان‌جا ساخته می‌شود.

  2. توکن را امتحان کن.
  3. پیام بفرست.
1
https://onpchat.ir/api/space/api-token?entity_id=<id>
curl -X POST https://api.onpchat.ir/v1/channels/%231786551855736/messages \
  -H "Authorization: Bearer $ONP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello from the API"}'

احراز هویت

هر فضا یک توکنِ مستقل دارد که فقط روی همان فضا کار می‌کند. توکن را در هدر بفرست:

کوکی و ?token= پذیرفته نمی‌شود. این API مخاطبش سرور است نه مرورگر، و هدرِ CORS هم ندارد. توکن را در جاوااسکریپتِ سمتِ کاربر نگذار — هر بازدیدکننده‌ای می‌تواند بردارَدش و از طرفِ فضای تو پیام بفرستد. اگر توکنی لو رفت، از همان پنل باطلش کن؛ توکنِ تازه فوراً جایگزین می‌شود.
Header
Authorization: Bearer onp_2e09e8f0bb35088c795e5f75dc...

شکل پاسخ

شرط‌هایت را روی error.code بگذار، نه روی message. متنِ پیام برای خواندنِ آدم است و ممکن است عوض شود؛ کد نه.

پاسخ
{ "ok": true,  "result": { ... } }

{ "ok": false, "error": {
    "code": "invalid_token",
    "message": "..."
} }

فضاها

چهار نوع فضا هست و هر کدام پیشوندِ خودش را دارد. پیشوند بخشی از شناسه است و در URL باید encode شود.

نوعدر مسیرپیشوندفرستنده دیده می‌شود؟
کانالchannels#%23نه — پیام از طرفِ خودِ کانال
گروهgroups@%40بله
کلاسclasses%%25بله
سانترالsantrals&%26بله

اندپوینت‌ها

متدمسیرکار
GET/v1/meتوکن مالِ کدام فضاست
GET/v1/{type}/{id}مشخصاتِ فضا
GET/v1/{type}/{id}/messagesتاریخچه
POST/v1/{type}/{id}/messagesانتشارِ پیام

تاریخچه

جدیدترین اول. صفحه‌بندی با seq است نه با زمان — یک شمارندهٔ یکنواخت که ترتیبِ قطعی می‌دهد، حتی برای دو پیامِ هم‌زمان. مقدارِ next_cursor را در before_seq صفحهٔ بعد بگذار؛ null یعنی به انتها رسیده‌ای.

درخواست
GET /v1/channels/%231786551855736/messages
      ?limit=30&before_seq=42
پاسخ
{
  "ok": true,
  "result": {
    "messages": [
      {
        "id": "a1b2c3",
        "text": "...",
        "seq": 42,
        "timestamp": 1788301362311
      }
    ],
    "next_cursor": 41
  }
}

کارت (پستِ تمیز)

به‌جای متنِ خام می‌توانی «کارت» بفرستی — همان چیزی که در اپ با «ساختِ کارت» می‌سازی: کاور، عنوان، متن و لینک، در یک قابِ تمیز.

به‌جای text فیلدِ card را بفرست. این دو با هم نمی‌آیند؛ متنِ همراهِ کارت در caption می‌رود.

فیلدلازم؟توضیح
urlبلهلینکی که کارت به آن می‌رود
titleنهعنوانِ کارت
descriptionنهمتنِ داخلِ کارت
imageنهکاور — باید نشانیِ کاملِ http/https باشد
captionنهمتنِ بیرونِ کارت، به‌عنوانِ حرفِ خودت

عکس باید جایی میزبانی شده باشد که از اینترنت باز شود؛ آپلود در این نسخه نیست. نشانیِ نسبی رد می‌شود، چون کارت روی گوشیِ کاربر رندر می‌شود و آن آدرس آن‌جا به جایی نمی‌رسد.

curl -X POST https://api.onpchat.ir/v1/groups/%401786579451315/messages \
  -H "Authorization: Bearer $ONP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "card": {
      "url": "https://example.com/post",
      "title": "...",
      "description": "...",
      "image": "https://example.com/cover.jpg",
      "caption": "..."
    }
  }'

پیامِ تکراری نفرست

اگر درخواست تایم‌اوت گرفت، نمی‌دانی پیام رسیده یا نه. هدرِ Idempotency-Key را بگذار تا تلاشِ دوباره پیامِ تکراری نسازد:

همان کلید، همان پیام. این کلید id پیام هم می‌شود.

Header
Idempotency-Key: order-2026-09-02-001

سهمیه

به‌ازای هر توکن، در هر دقیقه:

عملیاتسقف
انتشار20
خواندن120

هر پاسخ هدرهای X-RateLimit-Limit، X-RateLimit-Remaining و X-RateLimit-Reset دارد. اگر سهمیه پر شود 429 می‌گیری به‌همراهِ Retry-After — همان‌قدر صبر کن، نه کمتر.

پاسخ
HTTP/2 429
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 0
Retry-After: 37

خطاها

کد HTTPerror.codeیعنی
400empty_messagetext خالی است
400bad_requestبدنه یا پارامتر نامعتبر
401missing_tokenهدرِ Authorization نیست
401invalid_tokenتوکن شناخته نشد
401revoked_tokenتوکن باطل شده
403entity_mismatchاین توکن مالِ فضای دیگری است
403wrong_entity_kindنوعِ فضا در مسیر با توکن نمی‌خوانَد
403missing_scopeتوکن این مجوز را ندارد
403sender_not_memberسازندهٔ توکن دیگر عضوِ فضا نیست
403read_onlyکانال فقط-خواندنی است
404entity_not_foundفضا پیدا نشد
413message_too_longمتن از ۸۰۰۰ کاراکتر بلندتر است
429rate_limitedسهمیه پر شده
sender_not_member گرفتی؟ توکن به مدیری گره خورده که ساخته‌اش. اگر آن شخص از فضا خارج شده باشد، انتشار متوقف می‌شود. راه‌حل: یکی از مدیرانِ فعلی از پنل توکن را دوباره بسازد.

در این نسخه نیست

ارسالِ عکس و فایل، حذفِ پیام از API، و webhook (خبردار شدن از رویدادهای فضا) هنوز نیامده‌اند. توکن‌ها از همین حالا فیلدِ scopes دارند، پس وقتی webhook اضافه شود توکنِ تو باطل نمی‌شود.