مستندات API
احراز هویت
تمامی درخواستها باید با هدر Authorization به
صورت Basic
Authentication ارسال شوند.
فرمت: Basic base64(mobile:api_token)
mobile: شماره موبایل مدیر پنل کاربری بدون صفر ابتدایی
api_token: توکن دریافت شده از قسمت توسعه دهندگان پنل کاربری
Api Url: https://panel-api.videm.ir
/api/__panel/me
دریافت اطلاعات کاربر
اطلاعات کاربر جاری را برمیگرداند
پاسخ موفق:
{
"status": true,
"data": {
"name": "نام کاربر",
"mobile": "09123456789",
"balance": 100000,
...
}
}
/api/__panel/courses
دریافت لیست دورهها
لیست دورههای کاربر را برمیگرداند
پاسخ موفق:
{
"status": "success",
"data": [
{
"id": 1,
"title": "عنوان دوره",
...
}
]
}
/api/__panel/courses/{uuid}
دریافت اطلاعات دوره
اطلاعات دوره مورد نظر را برمیگرداند
پاسخ موفق:
{
"status": "success",
"data": [
{
"id": 1,
"title": "عنوان دوره",
"description": "مدرسه هنرهای دیجیتال ایران",
"types": {
"video": 123
},
"duration": 988992342, // بر حسب ثانیه
"status": "Publish",
"contents_count": 0,
"customers_count": 0,
"chapters": [
{
"id": 280,
"title": "هفته اول",
"description": "",
"sort": 1,
"contents": [
{
"type": "video",
"sort": 1,
"video": {
"id": 1080,
"uuid": "855ad9e3-...",
"title": "شروع دوره",
"description": "",
"status": "منتشر شد",
"duration": 71235 // بر حسب ثانیه
}
}
// ...
]
}
]
}
]
}
/api/__panel/courses/{course}/assistants
دریافت لیست کارکنان
لیست استادیاران را برمیگرداند
نیاز به دسترسی مدیریتی دارد
پاسخ موفق:
{
"status": "success",
"data": [
{
"id": 1,
"name": "نام استادیار",
"mobile": "09123456789",
...
}
]
}
/api/__panel/learning-paths
دریافت لیست مسیرهای آموزشی
مسیرهای آموزشی متعلق به owner فعلی را بهصورت صفحهبندیشده برمیگرداند.
پارامترهای Query:
title: جستوجوی بخشی در عنوان مسیر آموزشی؛ اختیاری.customer: جستوجوی بخشی در نام یا شماره موبایل شرکتکننده؛ اختیاری. شماره با صفر ابتدای آن نیز پذیرفته میشود.page: شماره صفحه، حداقل ۱؛ اختیاری.per_page: تعداد نتیجه در هر صفحه، بین ۱ تا ۱۰۰؛ پیشفرض ۱۵.
فیلترهای title و customer را میتوان همزمان ارسال کرد. هر آیتم شامل uuid دوره، عنوان، تعداد شرکتکنندهها و نام حداکثر دو شرکتکننده است و شناسهٔ عددی مسیر برگردانده نمیشود.
نمونه:
GET /api/__panel/learning-paths?title=طراحی&customer=09123456789&per_page=20&page=1
/api/__panel/learning-paths/{uuid}
دریافت مسیر آموزشی
uuid شناسهٔ UUID دورهٔ مسیر آموزشی است؛ شناسهٔ عددی پذیرفته نمیشود.
پاسخ شامل تصویر دوره در فیلد image، ساختار مسیر، تنظیمات، وضعیت شرکتکنندهها و استادیارهای متصل به هر شرکتکننده است. در پاسخ پنل id و course_id ارسال نمیشوند.
image در صورت نبود تصویر null است؛ در غیر این صورت شامل id، name، url، size و mime است.
/api/__panel/learning-paths
ساخت مسیر آموزشی
مسیر آموزشیِ اختصاصی را همزمان با اتصال به مشتری ایجاد میکند.
در عملیات ساخت هنوز دورهای وجود ندارد که UUID آن در URL ارسال شود؛ UUID دورهٔ ساختهشده در فیلد data.uuid پاسخ برمیگردد و تمام عملیات بعدی با همان UUID انجام میشوند.
نیازی به ارسال customer_id نیست؛ مشتری با mobile پیدا میشود و در صورت نبود ساخته میشود.
بدنهٔ درخواست:
{
"idempotency_key": "8c754c19-7656-4ba6-a45d-f15b3609a7e6",
"name": "نام شرکتکننده",
"mobile": "09123456789",
"code": "+98",
"assistant_id": [12, 24],
"image": "123/image/jpeg/hashed-file-name.jpg",
"expire_date": "2026-12-30",
"first_login_at": "2026-09-25",
"installment_count": 3,
"learning_path": {
"title": "مسیر طراحی محصول",
"description": "توضیحات مسیر آموزشی",
"items": [
{
"type": "section",
"title": "مبانی",
"sort": 1,
"lessons": [
{
"type": "lesson",
"title": "درس اول",
"sort": 1,
"course_id": 12,
"course_content_id": 145
}
]
}
]
},
"drip": {
"interval_days": 7,
"lessons_per_release": 2
},
"settings": {
"devices_limit": 3,
"has_pwa": true,
"downloadable": true
}
}
idempotency_key،name،mobile،codeوlearning_pathاجباریاند.mobileشمارهٔ محلی بدون کد کشور است؛ صفر ابتدای شماره پذیرفته و پیش از اعتبارسنجی حذف میشود.codeکد کشور، مانند+98است.assistant_idاختیاری و آرایهٔ شناسههای استادیار است؛ هر استادیار باید متعلق به همان owner و دارای نقش استادیار باشد، در غیر این صورت پاسخ422است.imageاختیاری است. ابتدا تصویر را با endpoint آپلود تکفایل بفرستید و سپس مقدارdata.pathپاسخ را بدون تغییر در این فیلد قرار دهید؛ URL یا خود فایل را ارسال نکنید.- هر section باید حداقل یک lesson داشته باشد؛
sortsectionها و lessonهای هر section مثبت و یکتا است. هر lesson بایدcourse_idوcourse_content_idمعتبر داشته باشد، محتوا به همان دوره تعلق داشته باشد و هر محتوا فقط یکبار در مسیر بیاید. - دورههای مبدأ باید متعلق به owner پنل باشند.
expire_dateوfirst_login_atاختیاری و با فرمتYYYY-MM-DDهستند. installment_countحداقل ۲ و حداکثر تعداد lessonهای مسیر است. در صورت ارسالdrip، هر دو فیلد آن اجباری و حداقل ۱ هستند؛lessons_per_releaseنمیتواند از تعداد lessonها بیشتر باشد.devices_limitبین ۰ تا ۱۰ است. کلیدهای مجاز settings عبارتاند ازdevices_limit،has_pwaوdownloadable.
idempotency_key باید UUID معتبر باشد. برای retry همان درخواست، همان کلید را ارسال کنید؛ استفاده از همان کلید با payload متفاوت خطای 422 میدهد.
/api/__panel/learning-paths/{uuid}
ویرایش مسیر آموزشی
uuid شناسهٔ UUID دورهٔ مسیر آموزشی است؛ شناسهٔ عددی پذیرفته نمیشود.
ارسال کامل learning_path اجباری است و ساختار موجود را جایگزین میکند. تنظیمات، drip، تاریخ انقضا، تاریخ شروع و تعداد اقساط اختیاریاند و در صورت ارسال همزمان بهروزرسانی میشوند.
{
"learning_path": {
"title": "عنوان جدید",
"description": "توضیحات ویرایششده مسیر آموزشی",
"items": [
{
"type": "section",
"title": "مبانی",
"sort": 1,
"lessons": [
{
"type": "lesson",
"title": "درس اول",
"sort": 1,
"course_id": 12,
"course_content_id": 145
}
]
}
]
},
"expire_date": "2026-12-30",
"first_login_at": "2026-09-25",
"installment_count": 3,
"assistant_id": [12, 24],
"image": "123/image/png/replacement-cover.png",
"drip": {
"interval_days": 7,
"lessons_per_release": 2
},
"settings": {
"devices_limit": 3,
"has_pwa": true,
"downloadable": true
}
}
- هر section باید حداقل یک lesson داشته باشد؛
sortsectionها و lessonهای هر section مثبت و یکتا است. - هر lesson باید
course_idوcourse_content_idمعتبر داشته باشد، محتوا به همان دوره تعلق داشته باشد و هر محتوا فقط یکبار در مسیر بیاید. دورههای مبدأ نیز باید متعلق به owner پنل باشند. expire_dateوfirst_login_atاختیاری و با فرمتYYYY-MM-DDهستند.installment_countحداقل ۲ و حداکثر تعداد lessonهای مسیر است.assistant_idاختیاری و آرایهٔ شناسههای استادیار متعلق به همان owner است. ارسال استادیارِ نامعتبر یا بدون نقش استادیار با خطای422رد میشود.- در ویرایش، ارسالنکردن
imageتصویر فعلی را حفظ میکند؛ برای جایگزینی ابتدا فایل جدید را با endpoint آپلود تکفایل بفرستید وdata.pathپاسخ را درimageقرار دهید. ارسالnullتصویر را حذف میکند. - در صورت ارسال
drip، هر دو فیلد آن اجباری و حداقل ۱ هستند؛lessons_per_releaseنمیتواند از تعداد lessonها بیشتر باشد. devices_limitبین ۰ تا ۱۰ است. کلیدهای مجاز settings عبارتاند ازdevices_limit،has_pwaوdownloadable.
/api/__panel/learning-paths/{uuid}/courses/{sourceCourseUuid}
حذف درسهای یک دوره از مسیر آموزشی
تمام lessonهای دورهٔ مبدأ با UUID ارسالی را از مسیر حذف میکند. بخشهای بدون درس نیز حذف میشوند.
پس از حذف، وضعیت انتشار شرکتکننده و شمارندهٔ محتوا و مدت مسیر دوباره محاسبه میشوند.
پارامترهای مسیر:
uuid: UUID مسیر آموزشیsourceCourseUuid: UUID دورهٔ مبدأ
بدنهٔ درخواست ندارد و پاسخ موفق، مسیر آموزشی بهروزشده است.
/api/__panel/learning-paths/{uuid}
حذف مسیر آموزشی
uuid شناسهٔ UUID دورهٔ مسیر آموزشی است؛ شناسهٔ عددی پذیرفته نمیشود.
مسیر آموزشی را حذف میکند. ثبتنام مشتری در مسیر، اقساط، ارتباط مشتری با استادیار و دورهٔ ثبتشده در فهرست دورههای استادیار نیز پاکسازی میشوند.
بدنهٔ درخواست ندارد و پاسخ موفق 200 با data: null است.
/api/__panel/learning-paths/with_template
اختصاص مسیر آموزشی به مشتری
با انتخاب یک الگو، یک مسیر مستقل برای مشتری ساخته میشود. الگو و مسیرهای ساختهشده از آن مستقل از یکدیگر هستند.
UUID دورهٔ مسیر ساختهشده در فیلد data.uuid پاسخ برمیگردد و تمام عملیات بعدی با همان UUID انجام میشوند.
ابتدا الگوها را از endpoint دریافت الگوها بگیرید و template_id متعلق به همان owner را انتخاب کنید. نیازی به ارسال customer_id نیست؛ مشتری با mobile پیدا میشود و در صورت نبود ساخته میشود.
بدنهٔ درخواست:
{
"idempotency_key": "9e9a6cd7-5216-4958-b987-29821ae3ceca",
"name": "نام شرکتکننده",
"mobile": "09123456789",
"code": "+98",
"template_id": 42,
"assistant_id": [12, 24],
"expire_date": "2026-12-30",
"first_login_at": "2026-09-25",
"installment_count": 3,
"drip": {
"interval_days": 7,
"lessons_per_release": 2
},
"settings": {
"devices_limit": 3,
"has_pwa": true,
"downloadable": true
}
}
idempotency_key،name،mobile،codeوtemplate_idاجباریاند.mobileشمارهٔ محلی بدون کد کشور است؛ صفر ابتدای شماره پذیرفته و پیش از اعتبارسنجی حذف میشود.codeکد کشور، مانند+98است.assistant_idاختیاری و آرایهٔ شناسههای استادیار متعلق به همان owner است. ارسال استادیارِ نامعتبر یا بدون نقش استادیار با خطای422رد میشود.expire_dateوfirst_login_atاختیاری و با فرمتYYYY-MM-DDهستند.installment_countاختیاری، حداقل ۲ و حداکثر تعداد درسهای الگو است.- در صورت ارسال
drip، هر دو فیلد آن اجباری و حداقل ۱ هستند؛lessons_per_releaseنمیتواند از تعداد درسهای الگو بیشتر باشد. devices_limitبین ۰ تا ۱۰ است. سایر کلیدهای مجاز settings عبارتاند ازdevices_limit،has_pwaوdownloadable.
idempotency_key باید UUID معتبر باشد. برای retry همان درخواست، همان کلید را ارسال کنید؛ استفاده از همان کلید با payload متفاوت خطای 422 میدهد.
/api/__panel/learning-path-templates
دریافت الگوهای مسیر آموزشی
فقط الگوهای متعلق به owner پنل را برمیگرداند. اگر الگویی وجود نداشته باشد، data یک آرایهٔ خالی است.
در ساخت یا ویرایش Template نیز تصویر مستقیماً داخل درخواست آپلود نمیشود: فایل را ابتدا با آپلودر تکفایل ارسال کنید و مقدار data.path پاسخ را در فیلد image بگذارید.
پاسخ موفق:
{
"status": "success",
"data": [
{
"id": 42,
"image": {
"id": 91,
"name": "template-cover.jpg",
"url": "https://...",
"size": "120 KB",
"mime": "image/jpeg"
},
"learning_path": {
"title": "مسیر طراحی محصول",
"description": "توضیحات الگوی مسیر آموزشی",
"items": []
}
}
]
}
/api/__panel/courses/{uuid}/customers
افزودن مشتری به دوره
افزودن مشتری به دوره مورد نظر
پارامترها:
{
"mobile": "09123456789",
"name": "نام مشتری",
"tag_ids": [1,2], // اختیاری
"assistant_id": [1], // اختیاری
"expire_date": "2024-12-31", // اختیاری
"devices_limit_count": 2, // اختیاری
"installment_count": 5 // اختیاری؛ null یعنی دسترسی عادی، حداقل 2 و حداکثر تعداد درسهای دوره
}
در صورت ارسال installment_count، دوره براساس ترتیب فعلی درسها به
تعداد قسمتهای اعلامشده تقسیم میشود. همه اقساط در ابتدا پرداختنشدهاند؛ در صورتی که قسط اول پرداخت نشده باشد عملا کاربر به هیچی درسی نسترسی نخواهد داشت.
پاسخ موفق:
{
"status": true,
"message": "",
"data": {
"id": 42311,
"name": "نام مشتری",
"mobile": "930...",
"installment_count": 5
}
}
/api/__panel/courses/{course:uuid}/customers/{customer:id}
ویرایش مشتری
ویرایش مشتری مورد نظر
پارامترها:
{
"tag_ids": [1,2], // اختیاری
"assistant_id": [1], // اختیاری
"tag_ids": [1,2], // اختیاری
"expire_date": "2024-12-31", // اختیاری
"first_login_at": "2024-12-31", // اختیاری
"devices_limit_count": 2, // اختیاری
"installment_count": 5 // اختیاری؛ در صورت عدم ارسال، مقدار فعلی حفظ میشود
}
فیلد installment_count فقط در صورت ارسال تغییر میکند. تا پیش از ثبت
اولین پرداخت میتوان تعداد اقساط را تغییر داد یا با ارسال null برنامه
را غیرفعال کرد. پس از ثبت اولین پرداخت، تعداد اقساط قابل تغییر یا حذف نیست.
پاسخ موفق:
{
"status": true,
"message": "",
"data": {
"id": 42311,
"name": "نام مشتری",
"mobile": "930...",
"installment_count": 5
}
}
/api/__panel/tags
دریافت لیست برچسبها
دریافت لیست برچسبهای کاربر
پاسخ موفق:
{
"status": "success",
"data": [
{
"id": 1,
"name": "برچسب 1"
},
{...}
]
}
/api/__panel/courses/{uuid}/customers
دریافت لیست مشتریان
دریافت لیست مشتریان دوره مورد نظر
پارامترهای کوئری:
search=نام مشتری | شماره موبایل // optional
tag_ids[]=1 // optional
tag_ids[]=2 // optional
created_after=2025-01-01 // optional
created_before=2025-01-01 // optional
page=1
مثال:
?search=محمد&tag_ids[]=1&tag_ids[]=2&created_after=2025-01-01&created_before=2025-01-01&has_chat=1&page=1
پاسخ موفق:
{
"data": [
{
"id": 42311,
"name": "محمد ",
"email": null,
"code": "+98",
"mobile": "930...",
"devices_count": 0,
"created_at": "2025-01-22T12:45:27.000000Z",
"expired_at": null, // تاریخ انقضای دسترسی مشتری به دوره
"last_login_at": "2025-03-08 12:06:20",
"first_login_at": "2025-01-22 21:24:44",
"drip_started_at": "2025-01-22", // تاریخ شروع انتشار قطرهای محتوا
"drip_stoped_at": null, // تاریخ توقف انتشار قطرهای؛ null یعنی فعال است
"installment_count": 5, // null یعنی دسترسی اقساطی فعال نیست
"options": {
"has_chat": 1,
"has_download": 1,
"devices_limit_count": 10
},
"seconds_of_view": 46110,
"percent_of_view": 87.58,
"contents_viewed_count": 103
},
{...}
],
"meta": {
"current_page": 2,
"from": 101,
"last_page": 9,
"per_page": 100,
"to": 200,
"total": 880
}
}
/api/__panel/courses/{uuid}/customers/{customer}
دریافت جزئیات مشتری
دریافت جزئیات مشتری در دوره مورد نظر
پاسخ موفق:
{
"data": [
{
"id": 42311,
"name": "محمد ",
"email": null,
"code": "+98",
"mobile": "930...",
"devices_count": 0,
"created_at": "2025-01-22T12:45:27.000000Z",
"expired_at": null, // تاریخ انقضای دسترسی مشتری به دوره
"last_login_at": "2025-03-08 12:06:20",
"first_login_at": "2025-01-22 21:24:44",
"drip_started_at": "2025-01-22", // تاریخ شروع انتشار قطرهای محتوا
"drip_stoped_at": "2025-03-01", // تاریخ توقف انتشار قطرهای؛ null یعنی فعال است
"tags": [
{
"id": 1,
"name": "برچسب 1"
},
{...}
],
"assistants": [
{
"id": 1,
"name": "استادیار 1"
},
{...}
],
"options": {
"has_chat": 1,
"has_download": 1,
"devices_limit_count": 10
},
"contents": [
{
"id": 202,
"type": "video",
"title": "شروع دوره",
"duration_seconds": 71,
"seconds_of_view": 250,
"percent_of_view": 100
},
{
"id": 204,
"type": "video",
"title": "تمرین تکمیلی دوم",
"duration_seconds": 864,
"seconds_of_view": 940,
"percent_of_view": 100
},
{...}
]
},
{...}
]
}
/api/__panel/courses/{course:uuid}/customers/{customer:id}/installments/{installmentNumber}/payment
اعلام پرداخت قسط مشتری
پرداخت قسط مشخصشده را با زمان سرور و شناسه کاربر جاری ثبت میکند. پرداختها باید به ترتیب
انجام شوند و ثبت دوباره یک قسط، مقدار اولیه paid_at را تغییر نمیدهد.
پرداخت قسط شماره k قسمت k+1 را تا سقف تعداد
قسمتها باز میکند؛ پرداخت قسط آخر فقط وضعیت تسویه را کامل میکند.
پارامتر course UUID دوره و
installmentNumber شماره قسط است. این درخواست بدنه ندارد.
احراز هویت آن مانند سایر endpointهای /__panel از طریق Basic API Token
انجام میشود.
پاسخ موفق:
{
"status": true,
"message": "",
"data": {
"number": 1,
"paid_at": "2026-09-11T18:30:00.000000Z",
"paid_by": 19
}
}
خطای ترتیب پرداخت (422):
{
"message": "The given data was invalid.",
"errors": {
"installment_number": [
"ابتدا باید اقساط قبلی پرداخت شوند."
]
}
}
/api/__panel/courses/{course:uuid}/customers/{customer:id}/drip_start
شروع مجدد انتشار قطرهای برای مشتری
انتشار تدریجی محتوا را برای مشتری از حالت توقف خارج میکند. تعداد روزهای توقف به
drip_started_at اضافه و drip_stoped_at خالی
میشود.
این درخواست بدنه یا پارامتر ورودی ندارد.
پاسخ موفق:
{
"status": true,
"message": "",
"data": {
"id": 42311,
"name": "نام مشتری",
"mobile": "930...",
"drip_started_at": "2026-08-04",
"drip_stoped_at": null
}
}
/api/__panel/courses/{course:uuid}/customers/{customer:id}/drip_stop
توقف انتشار قطرهای برای مشتری
انتشار تدریجی محتوا را برای مشتری متوقف و تاریخ امروز را در
drip_stoped_at ثبت میکند. اگر انتشار قطرهای قبلاً متوقف شده باشد،
تاریخ توقف اولیه تغییر نمیکند.
این درخواست بدنه یا پارامتر ورودی ندارد.
پاسخ موفق:
{
"status": true,
"message": "",
"data": {
"id": 42311,
"name": "نام مشتری",
"mobile": "930...",
"drip_started_at": "2026-08-01",
"drip_stoped_at": "2026-08-23"
}
}
/api/__panel/media/uploads/single
آپلود تکفایل
یک فایل را با Basic Authentication پنل و بهصورت multipart/form-data در فضای موقت آپلود میکند.
نام فیلد فایل باید file باشد.
قاعدهٔ استفاده از فایل در API:
- فایل را ابتدا با همین endpoint و در فیلد
fileآپلود کنید. - مقدار
data.pathرا از پاسخ بردارید. - در درخواست اصلی، خودِ مقدار
data.pathرا در فیلد مربوط به فایل قرار دهید؛ برای نمونه، مقدار فیلدimageباید همین path باشد، نه URL تصویر و نه خود فایل.
این قاعده برای تمام فایلهای این API برقرار است؛ از جمله image مسیر آموزشی و image الگوی مسیر آموزشی (Template).
نمونه درخواست:
curl -X POST "https://panel-api.videm.ir/api/__panel/media/uploads/single" \
-u "username:password" \
-F "file=@cover.jpg"
پاسخ موفق:
{
"status": true,
"message": "فایل با موفقیت آپلود شد",
"data": {
"path": "123/image/jpeg/hashed-file-name.jpg"
}
}
نمونهٔ استفاده از path در درخواست بعدی:
{
"image": "123/image/jpeg/hashed-file-name.jpg"
}
همین ساختار برای ساخت یا ویرایش مسیر آموزشی و Template استفاده میشود.
در صورت ارسالنشدن فایل یا شکست آپلود پاسخ 400 و در صورت Basic Authentication نامعتبر پاسخ 401 برمیگردد.