مرور کلی API
نشانی پایه، نسخهبندی، قالب درخواست و پاسخ، و مدل فضای کاری که هر فراخوانی بر اساس آن ارزیابی میشود.
آخرین بازنگری: 2026-08-23
API برای چیست
API کلاینتوپرو همان رابطی است که خودِ برنامهٔ وب محصول از آن استفاده میکند. زیرمجموعهٔ محدودشدهٔ «عمومی» و پایگاه دادهٔ جداگانهای برای یکپارچهسازی وجود ندارد: هر چیزی که یک صفحه میتواند نشان دهد، یک توکن مجاز هم میتواند بخواند، و هر چیزی که یک صفحه میتواند تغییر دهد، یک توکن مجاز هم میتواند تغییر دهد.
از آن برای همگامسازی مخاطبان با سامانهای دیگر، ارسال سفارشها از یک فروشگاه، انتقال معاملات به انبار داده برای گزارشگیری، یا اجرای هر جریان کاریای که رابط کاربری اجرا میکند استفاده کنید. برای جهت معکوس - یعنی باخبر شدن از تغییرات بهجای پرسیدن - از وبهوکها استفاده کنید.
نشانی پایه و نسخهبندی
همهٔ منابع زیر یک ریشهٔ نسخهدار قرار دارند. نسخه در مسیر میآید و تنها جایی است که نسخه ظاهر میشود؛ نه هدر نسخهای هست و نه مذاکرهٔ نسخه از راه Accept.
https://<your-cliento-host>/api/v1/api/v1 فقط بهصورت افزایشی تغییر میکند. نقطهٔ پایانی تازه، فیلد اختیاری تازه در درخواست و فیلد تازه در پاسخ ممکن است هر زمان اضافه شود؛ بنابراین کلاینت باید فیلدهای ناشناخته را نادیده بگیرد، نه اینکه خطا بدهد. تغییر ناسازگار یعنی مسیر نسخهٔ جدید و یک دورهٔ منسوخسازی برای نسخهٔ قبلی - چنین تغییری هرگز داخل v1 رخ نمیدهد.
ساختن یک درخواست
- فقط HTTPS. توکنها اعتبارنامهٔ حاملاند؛ درخواست رمزنگارینشده یعنی افشای توکن.
- `Authorization: Bearer <token>` روی همهٔ نقاط پایانی بهجز ثبتنام و ورود. بخش «احراز هویت» را ببینید.
- `Content-Type: application/json` برای هر درخواست دارای بدنه. بدنهها شیء JSON هستند - نه form-encoding و نه آرایهٔ برهنه در سطح بالا.
- `Accept: application/json`. پاسخها JSON هستند؛ خطاها هم JSONاند، از جمله ۴۰۱ و ۵۰۰.
- همهجا UTF-8. فارسی، عربی و ایموجی بدون تغییر ذخیره و بازگردانده میشوند.
curl -sS https://your-host/api/v1/crm/contacts \
-H "Authorization: Bearer ct_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Accept: application/json"قالب پاسخها
سه قالب تقریباً همهٔ نقاط پایانی را پوشش میدهد و دانستن اینکه با کدامیک روبهرو هستید برای نوشتن کلاینت کافی است.
| فراخوانی | وضعیت | بدنه |
|---|---|---|
فهرست (GET /crm/contacts) | ۲۰۰ | { items, page, page_size, total } |
جزئیات (GET /crm/contacts/{id}) | ۲۰۰ | شیء رکورد |
ایجاد (POST /crm/contacts) | ۲۰۱ | رکورد ایجادشده |
بهروزرسانی (PATCH /crm/contacts/{id}) | ۲۰۰ | رکورد بهروزشده |
حذف (DELETE /crm/contacts/{id}) | ۲۰۴ | خالی |
| هر ردشدنی | 4xx / 5xx | { error, message, details } |
{
"id": 4182,
"tenant_id": 17,
"first_name": "Sara",
"last_name": "Ahmadi",
"email": "sara@example.com",
"phone": "+989121234567",
"company": "Horizon Real Estate",
"title": "Managing partner",
"owner_user_id": 5,
"created_by_user_id": 5,
"display_name": "Sara Ahmadi",
"created_at": "2026-08-01T09:14:22",
"updated_at": "2026-08-19T16:02:41"
}PATCH واقعاً جزئی است: فقط فیلدهایی را بفرستید که تغییر میدهید. فرستادن فیلد با مقدار null آن را تهی میکند و نفرستادنش آن را دستنخورده باقی میگذارد. PUT وجود ندارد، چون نوشتن با جایگزینی کامل، فیلدهایی را که پس از نوشتهشدن کلاینت شما به محصول اضافه شدهاند بیسروصدا پاک میکند.
فضای کاری، مجوزها و دیدپذیری
هر اعتبارنامه دقیقاً به یک فضای کاری تعلق دارد و فضای کاری از خودِ اعتبارنامه خوانده میشود، نه از درخواست. هیچ پارامتر مستأجری وجود ندارد که بتوانید بفرستید و همین نکته اصل ماجراست: با تغییر یک URL، یک هدر یا یک فیلد بدنه نمیتوان توکن را به دادهٔ مشتری دیگری نشانه رفت.
در هر فراخوانی سه بررسی بهترتیب اجرا میشود. ناکامی در هر کدام یعنی رد شدن، نه نتیجهٔ خالی:
- احراز هویت - توکن زنده، منقضینشده و باطلنشده باشد. در غیر این صورت ۴۰۱.
- مجوز - توکن کد مشخصی را که نقطهٔ پایانی لازم دارد داشته باشد، مثلاً
crm.contacts.writeبرای ایجاد مخاطب. در غیر این صورت ۴۰۳. - دیدپذیری ردیف - درون همان فضای کاری، برخی نقشها فقط رکوردهای خود یا تیمشان را میبینند. ردیفهای بیرون از این دامنه اصلاً در فهرستها نمیآیند و دسترسی مستقیم به آنها ۴۰۴ میشود.
تکتک *فیلدها* هم میتوانند محدود شوند. فراخوانیکنندهای که crm.contacts.view_phone ندارد، phone را ماسکشده دریافت میکند - با همان طول و با جایگزینی همهٔ نویسهها - نه حذفشده. همان مقدار ماسکشده را نمایش دهید و آن را فیلد خالی به حساب نیاورید.
هر کاری که میکنید ثبت میشود
هر تغییر وضعیت یک رویداد مینویسد؛ چه از رابط کاربری آمده باشد، چه از یک جریان کاری، چه از یکپارچهسازی شما. GET /events همان دفتر است و وبهوکها هم بر پایهٔ آن ساخته شدهاند - بنابراین یک یکپارچهسازی میتواند خودش را با همان تاریخچهای تطبیق دهد که نمای حسابرسی فضای کاری نشان میدهد.
{
"id": 91442,
"tenant_id": 17,
"user_id": 5,
"entity_type": "contact",
"entity_type_label": { "en": "Contact", "fa": "مخاطب", "ar": "جهة اتصال" },
"entity_id": 4182,
"event_type": "ContactCreated",
"event_type_label": { "en": "Contact created", "fa": "مخاطب ایجاد شد", "ar": "تم إنشاء جهة الاتصال" },
"source": "api",
"metadata": { "email": "sara@example.com" },
"occurred_at": "2026-08-19T16:02:41"
}event_type و entity_type کدهای ماشینی پایدارند - روی همانها تطبیق بدهید. جفتهای *_label واژگان خودِ محصول را در هر سه زبان میآورند و فقط برای نمایشاند؛ ممکن است بدون اطلاع بازنویسی شوند.
زبان و تقویم
خودِ API نسبت به زبان خنثی است و این یک قرارداد آگاهانه است، نه یک کاستی:
- زمانها به UTC و قالب ISO-8601 بدون پسوند اختلاف زمانیاند (
2026-08-19T16:02:41). نمایش جلالی یا میلادی انتخاب هر کاربر است؛ قالب روی سیم هرگز تغییر نمیکند. - فهرست مقادیر، کد ماشینی است (
open،in_progress،ContactCreated). ترجمه را در کلاینت خودتان انجام دهید و روی برچسب نمایشی تطبیق ندهید. - پیامهای خطا انگلیسیاند. آنها متن تشخیصی برای توسعهدهندهاند. بومیسازی را بر اساس کد
errorانجام دهید که پایدار است، نه بر اساس جمله. - محتوایی که ذخیره میکنید عیناً بازگردانده میشود، با همان خطی که فرستادهاید.