نوبت انبار و پایش آن
مخاطب: برنامهنویس نرمافزار انبارداری یا ربات اطلاعرسانی که میخواهد بداند انبارهای دیجیکالا در چه روز و ساعتی نوبت خالی برای تحویل محموله دارند و همان لحظهای که نوبتی باز یا آزاد میشود، خبردار شود.
📖 مقدمه
Section titled “📖 مقدمه”برای تحویل محموله به انبار دیجیکالا باید یک نوبت (یک ساعت مشخص در یک روز) رزرو شود. نوبتها کماند، معمولا چند روز جلوتر منتشر میشوند و در چند دقیقه پر میشوند؛ گاهی هم فروشندهی دیگری محمولهاش را حذف میکند و نوبتی دوباره آزاد میشود. سلر ۳۶۰ نوبتهای همهی انبارها را هر ۳۰ ثانیه میخواند و برای انبارهایی که شما پایش میکنید، باز شدن، آزاد شدن و کم شدن ظرفیت را اعلام میکند.
با مسیرهای این صفحه میتوانید:
| کار | مسیر | در دسترس |
|---|---|---|
| انبارهای قابل ارسال برای این پنل | GET /v1/warehouses |
فعال |
| نوبتهای انبارهای پایششده | GET /v1/warehouse-slots |
فعال |
| فهرست پایشها | GET /v1/slot-watches |
فعال |
| افزودن پایش یک انبار | POST /v1/slot-watches |
فعال |
| خواندن یک پایش | GET /v1/slot-watches/{slot_watch_id} |
فعال |
| تغییر پایش | PATCH /v1/slot-watches/{slot_watch_id} |
فعال |
| حذف پایش | DELETE /v1/slot-watches/{slot_watch_id} |
فعال |
| خواندن تنظیم اعلان پایش | GET /v1/slot-watch-notifications |
فعال |
| تغییر تنظیم اعلان پایش | PATCH /v1/slot-watch-notifications |
فعال |
و با رویدادهای وبهوک slot.opened، slot.freed و slot.low خبردار شوید. پایش و اعلان فقط در سلر ۳۶۰ ثبت میشوند و چیزی در دیجیکالا نمینویسند؛ به همین دلیل همه در فاز ۱ هستند.
⚙️ پیشنیازها
Section titled “⚙️ پیشنیازها”دسترسی (Scope)
Section titled “دسترسی (Scope)”| دسترسی | برای |
|---|---|
shipping:read |
خواندن انبارها، نوبتها، پایشها و تنظیم اعلان، و دریافت رویدادهای slot.* |
shipping:write |
افزودن، تغییر و حذف پایش و تغییر تنظیم اعلان |
فعال بودن ماژول
Section titled “فعال بودن ماژول”ماژول «API و وبهوک» باید برای پنل فعال باشد؛ در غیر این صورت پاسخ 403 با خطای module_inactive (ماژول API) یا module_required (ماژول این بخش، با نام آن در detail) برمیگردد.
آدرس پایه
Section titled “آدرس پایه”https://api.seller360.ir🏭 انبار، نوبت و پایش
Section titled “🏭 انبار، نوبت و پایش”اندازهی محموله (shipping_nature_id)
Section titled “اندازهی محموله (shipping_nature_id)”| مقدار | برچسب در پنل |
|---|---|
1 |
«کوچک» |
2 |
«متوسط» |
3 |
«سنگین» |
فهرست انبارها برای هر اندازه جداست: یک انبار ممکن است محمولهی کوچک بپذیرد و محمولهی سنگین نپذیرد.
نوع محموله (package_type)
Section titled “نوع محموله (package_type)”| مقدار | برچسب در پنل |
|---|---|
order_fulfilment |
«محمولهی سفارش» |
consignment |
«محمولهی انبارش» |
فیلدهای روز نوبت (WarehouseSlotDay)
Section titled “فیلدهای روز نوبت (WarehouseSlotDay)”یک ردیف برای هر انبار، روز، نوع و اندازهی محموله.
| فیلد | برچسب در پنل | معنی |
|---|---|---|
warehouse_id، warehouse_title |
«کدام انبار؟» | انبار. |
date |
— | روز (به وقت تهران)، از امروز تا سه روز بعد. |
package_type |
«کدام محمولهها؟» | نوع محموله. |
shipping_nature_id |
«اندازهی محموله» | اندازهی محموله. |
published |
«هنوز منتشر نشده» وقتی false است |
دیجیکالا نوبتهای این روز را منتشر کرده است. |
slots |
«شبکهی نوبتها» | نوبتهای آن روز. |
synced_at |
«آخرین بررسی موفق» | آخرین پاسخ موفق دیجیکالا. |
stale |
«آخرین بررسی موفق قدیمی است» | آخرین پاسخ موفق قدیمیتر از ۵ دقیقه است. |
فیلدهای هر نوبت (WarehouseSlot)
Section titled “فیلدهای هر نوبت (WarehouseSlot)”| فیلد | برچسب در پنل | معنی |
|---|---|---|
capacity_id |
— | شناسهی نوبت؛ برای ساخت محمولهی انبارش لازم است. |
starts_at، ends_at |
«نوبت تحویل» | ساعت شروع و پایان، به شکل عدد (مثلا 10 و 11). |
open |
«باز» یا «پر» | نوبت باز است. |
remained |
عدد روی خانهی کهربایی | ظرفیت باقیمانده؛ خالی یعنی بیش از ۱۰ (هشدار ۲). |
فیلدهای پایش (SlotWatch)
Section titled “فیلدهای پایش (SlotWatch)”| فیلد | برچسب در پنل | معنی |
|---|---|---|
enabled |
— | پایش روشن است. |
warehouse_id، shipping_nature_id |
«کدام انبار؟»، «اندازهی محموله» | هر انبار با هر اندازه فقط یک پایش دارد. |
watch_order |
«محمولهی سفارش» | پایش نوبتهای محمولهی سفارش. |
watch_consignment |
«محمولهی انبارش» | پایش نوبتهای محمولهی انبارش. دستکم یکی از دو نوع لازم است. |
alert_opened |
«نوبت تازه باز شد» | اعلان باز شدن نوبت تازه. |
alert_freed |
«نوبت آزاد شد» | اعلان آزاد شدن نوبت پرشده. |
alert_low |
«ظرفیت در حال تکمیل است» | اعلان کم شدن ظرفیت. |
low_threshold |
— | حد هشدار ظرفیت. |
last_checked_at |
«آخرین بررسی موفق» | آخرین پاسخ موفق برای نوعهای پایششده. |
pending |
«در حال اولین بررسی» | پایش روشن است و هنوز یک بار هم بررسی نشده است. |
stale |
«آخرین بررسی موفق قدیمی است» | آخرین پاسخ موفق قدیمیتر از ۵ دقیقه است. |
تنظیم اعلان پایش (SlotWatchNotifications)
Section titled “تنظیم اعلان پایش (SlotWatchNotifications)”یک تنظیم برای همهی پایشهای پنل.
| فیلد | برچسب در پنل | معنی |
|---|---|---|
telegram |
«پیامرسان» | ارسال اعلان در تلگرام یا بله. |
bell |
«صندوق پیام پنل» | اعلان داخل پنل. |
summary |
«خلاصهی صبح» | خلاصهی نوبتهای باز، هر روز ساعت ۸ صبح. |
quiet_enabled، quiet_start، quiet_end |
«ساعت سکوت پیامرسان» | در این بازه پیام تلگرام فرستاده نمیشود. |
این تنظیم فقط اعلانهای پنل را تعیین میکند و بر ارسال وبهوک اثری ندارد.
🔢 تازگی
Section titled “🔢 تازگی”- هر ۳۰ ثانیه: نوبتهای امروز تا سه روز بعد هر ۳۰ ثانیه از دیجیکالا خوانده میشوند.
- یک خواندن مشترک: نوبتها اطلاعات ظرفیت انبار دیجیکالا هستند، نه اطلاعات یک فروشنده. سلر ۳۶۰ هر روز و هر نوع محموله را یک بار برای همهی انبارها و همهی پنلها میخواند و همان پاسخ را به همه نشان میدهد. خواندن این مسیرها هیچ درخواستی به دیجیکالا نمیفرستد و از سقف دیجیکالای شما چیزی کم نمیکند.
- نشان قدیمی بودن (
stale): اگر آخرین پاسخ موفق دیجیکالا قدیمیتر از ۵ دقیقه باشد،stale: trueاست و رویدادی ساخته نمیشود. - فقط انبارهای پایششده:
GET /v1/warehouse-slotsفقط نوبت انبارهایی را دارد که این پنل پایش میکند. برای دیدن نوبت یک انبار، ابتدا پایش آن را بسازید.
⚠️ هشدارها
Section titled “⚠️ هشدارها”📡 مسیرها
Section titled “📡 مسیرها”GET /v1/warehouses — انبارهای قابل ارسال فعال
Section titled “GET /v1/warehouses — انبارهای قابل ارسال ”انبارهای دیجیکالا که این پنل میتواند به آنها محموله بفرستد، به ترتیب نام.
GET /v1/warehouses?shipping_nature_id=1 HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
shipping_nature_id |
1، 2، 3 |
خیر | فقط انبارهای این اندازهی محموله. |
page، size |
عدد | خیر | صفحهبندی. |
{ "status": "ok", "data": [ { "warehouse_id": 1, "title": "انبار کرج", "address": "کرج، جادهی ملارد، انبار مرکزی دیجیکالا", "shipping_nature_id": 1, "synced_at": "2026-11-13T03:10:04+03:30" }, { "warehouse_id": 7, "title": "انبار تهران شرق", "address": "تهران، جادهی خاوران", "shipping_nature_id": 1, "synced_at": "2026-11-13T03:10:04+03:30" } ], "pager": { "page": 1, "item_per_page": 50, "total_pages": 1, "total_rows": 2 }}GET /v1/warehouse-slots — نوبتها فعال
Section titled “GET /v1/warehouse-slots — نوبتها ”نوبتهای امروز تا سه روز بعد، برای انبارهایی که این پنل پایش میکند.
GET /v1/warehouse-slots?package_type=consignment&open=1 HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
warehouse_id |
عدد | خیر | فقط نوبتهای این انبار. |
shipping_nature_id |
1، 2، 3 |
خیر | فقط این اندازهی محموله. |
package_type |
order_fulfilment، consignment |
خیر | فقط این نوع محموله. |
date |
تاریخ | خیر | فقط این روز (به وقت تهران). |
open |
0 یا 1 |
خیر | فقط روزهایی که دستکم یک نوبت باز دارند (1). |
page، size |
عدد | خیر | صفحهبندی. |
پاسخ نمونه
{ "status": "ok", "data": [ { "warehouse_id": 1, "warehouse_title": "انبار کرج", "date": "2026-11-14", "package_type": "consignment", "shipping_nature_id": 1, "published": true, "slots": [ { "capacity_id": 9081733, "starts_at": 10, "ends_at": 11, "open": true, "remained": 3 }, { "capacity_id": 9081734, "starts_at": 11, "ends_at": 12, "open": true, "remained": null }, { "capacity_id": 9081735, "starts_at": 12, "ends_at": 13, "open": false, "remained": 0 } ], "synced_at": "2026-11-13T10:14:31+03:30", "stale": false } ], "pager": { "page": 1, "item_per_page": 50, "total_pages": 1, "total_rows": 1 }}GET /v1/slot-watches — فهرست پایشها فعال
Section titled “GET /v1/slot-watches — فهرست پایشها ”پایشهای پنل، به ترتیب ساخت. GET /v1/slot-watches/{slot_watch_id} همان ساختار را برای یک پایش برمیگرداند.
POST /v1/slot-watches — افزودن پایش فعال
Section titled “POST /v1/slot-watches — افزودن پایش ”پایش تازه روشن ساخته میشود. انبار باید با همان اندازه در GET /v1/warehouses آمده باشد.
POST /v1/slot-watches HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...Idempotency-Key: watch-karaj-smallContent-Type: application/json
{ "warehouse_id": 1, "shipping_nature_id": 1, "watch_order": false, "watch_consignment": true, "alert_opened": true, "alert_freed": true, "alert_low": true, "low_threshold": 10}| فیلد بدنه | نوع | اجباری | توضیح |
|---|---|---|---|
warehouse_id |
عدد | بله | انبار، از GET /v1/warehouses. |
shipping_nature_id |
1، 2، 3 |
بله | اندازهی محموله. |
watch_order، watch_consignment |
بولی | خیر | نوعهای پایششده؛ دستکم یکی لازم است. |
alert_opened، alert_freed، alert_low |
بولی | خیر | اعلانهای پنل برای هر نوع تغییر. |
low_threshold |
عدد | خیر | حد هشدار ظرفیت. |
enabled |
بولی | خیر | روشن یا خاموش. |
پاسخ نمونه (کد 201)
{ "status": "ok", "data": { "id": 12, "enabled": true, "warehouse_id": 1, "warehouse_title": "انبار کرج", "shipping_nature_id": 1, "watch_order": false, "watch_consignment": true, "alert_opened": true, "alert_freed": true, "alert_low": true, "low_threshold": 10, "last_checked_at": null, "pending": true, "stale": false, "created_at": "2026-11-13T10:20:11+03:30", "updated_at": "2026-11-13T10:20:11+03:30" }}خطاهای این مسیر
| کد HTTP | خطا | معنی | تکرار بیخطر است؟ |
|---|---|---|---|
400 |
invalid_parameter |
بدنه نامعتبر است؛ مثلا هیچکدام از دو نوع محموله انتخاب نشده است. | خیر؛ بدنه را اصلاح کنید. |
409 |
slot_watch_exists |
پایش این انبار با همین اندازه پیشتر ثبت شده است. | خیر؛ پایش موجود را با PATCH تغییر دهید. |
409 |
idempotency_mismatch |
این کلید قبلا با بدنهی دیگری استفاده شده است. | خیر؛ کلید تازه بسازید. |
409 |
idempotency_in_progress |
درخواستی با همین کلید در حال انجام است. | بله، چند ثانیه بعد. |
422 |
warehouse_not_listed |
این انبار با این اندازه در فهرست انبارهای پنل نیست. | خیر؛ فهرست انبارها را بخوانید. |
PATCH /v1/slot-watches/{slot_watch_id} — تغییر پایش فعال
Section titled “PATCH /v1/slot-watches/{slot_watch_id} — تغییر پایش ”فقط فیلدهای ارسالشده تغییر میکنند. برای خاموش کردن موقت پایش، {"enabled": false} بفرستید. خطاها مانند افزودن پایش است، بهعلاوهی 404 و not_found برای پایشی که در این پنل نیست.
DELETE /v1/slot-watches/{slot_watch_id} — حذف پایش فعال
Section titled “DELETE /v1/slot-watches/{slot_watch_id} — حذف پایش ”{ "status": "ok", "data": { "id": 12, "deleted": true } }GET /v1/slot-watch-notifications و PATCH /v1/slot-watch-notifications — تنظیم اعلان فعال
Section titled “GET /v1/slot-watch-notifications و PATCH /v1/slot-watch-notifications — تنظیم اعلان ”کانالهای اعلان پنل برای همهی پایشها. در PATCH فقط فیلدهای ارسالشده تغییر میکنند.
{ "status": "ok", "data": { "telegram": true, "bell": true, "summary": true, "quiet_enabled": true, "quiet_start": "23:00", "quiet_end": "08:00" }}🔔 رویدادهای وبهوک
Section titled “🔔 رویدادهای وبهوک”| رویداد | چه وقت |
|---|---|
slot.opened |
برای انبار، نوع و اندازهای که این پنل پایش میکند، نوبتی برای اولین بار باز شد. |
slot.freed |
نوبتی که پر شده بود دوباره آزاد شد؛ معمولا وقتی فروشندهی دیگری محمولهی خود را حذف میکند. |
slot.low |
جمع ظرفیت باقیماندهی نوبتهای باز یک روز تغییر کرد (total_remained و prev_total). |
رویداد slot.low حد هشدار پایش را اعمال نمیکند: هر تغییر جمع ظرفیت فرستاده میشود و low_threshold را خودتان روی total_remained اعمال کنید. اگر ظرفیت بیش از ۱۰ باشد، دیجیکالا عدد نمیدهد و این رویداد ساخته نمیشود. هیچکدام از این رویدادها وقتی پایش «قدیمی» است ساخته نمیشوند (هشدار ۵).
نمونهی پیام slot.opened
{ "id": "evt_01HZYF2D", "type": "slot.opened", "created_at": "2026-11-13T10:21:02+03:30", "panel_id": 1, "livemode": true, "data": { "warehouse_id": 1, "warehouse_title": "انبار کرج", "date": "2026-11-14", "package_type": "consignment", "shipping_nature_id": 1, "slots": [ { "capacity_id": 9081736, "starts_at": 13, "ends_at": 14, "open": true, "remained": 6 } ], "total_remained": null, "prev_total": null }}پیش از استفاده از هر پیام، امضای آن را بررسی کنید.
💻 نمونهکد: افزودن پایش یک انبار
Section titled “💻 نمونهکد: افزودن پایش یک انبار”curl -X POST https://api.seller360.ir/v1/slot-watches \ -H "Authorization: Bearer $S360_API_KEY" \ -H "Idempotency-Key: watch-karaj-small" \ -H "Content-Type: application/json" \ -d '{"warehouse_id": 1, "shipping_nature_id": 1, "watch_consignment": true, "alert_opened": true, "alert_freed": true}'$ch = curl_init("https://api.seller360.ir/v1/slot-watches");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("S360_API_KEY"), "Idempotency-Key: watch-karaj-small", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "warehouse_id" => 1, "shipping_nature_id" => 1, "watch_consignment" => true, "alert_opened" => true, "alert_freed" => true, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20,]);$res = json_decode(curl_exec($ch), true);if (($res["error"]["code"] ?? null) === "slot_watch_exists") { // پایش این انبار پیشتر ساخته شده است}import os, requests
res = requests.post( "https://api.seller360.ir/v1/slot-watches", headers={ "Authorization": f"Bearer {os.environ['S360_API_KEY']}", "Idempotency-Key": "watch-karaj-small", }, json={ "warehouse_id": 1, "shipping_nature_id": 1, "watch_consignment": True, "alert_opened": True, "alert_freed": True, }, timeout=20,).json()if res["status"] == "error" and res["error"]["code"] == "slot_watch_exists": ... # پایش این انبار پیشتر ساخته شده استconst res = await fetch('https://api.seller360.ir/v1/slot-watches', { method: 'POST', headers: { Authorization: `Bearer ${process.env.S360_API_KEY}`, 'Idempotency-Key': 'watch-karaj-small', 'Content-Type': 'application/json', }, body: JSON.stringify({ warehouse_id: 1, shipping_nature_id: 1, watch_consignment: true, alert_opened: true, alert_freed: true, }),})const body = await res.json()if (body.error?.code === 'slot_watch_exists') { // پایش این انبار پیشتر ساخته شده است}using var http = new HttpClient();var req = new HttpRequestMessage(HttpMethod.Post, "https://api.seller360.ir/v1/slot-watches");req.Headers.Add("Authorization", $"Bearer {Environment.GetEnvironmentVariable("S360_API_KEY")}");req.Headers.Add("Idempotency-Key", "watch-karaj-small");req.Content = JsonContent.Create(new { warehouse_id = 1, shipping_nature_id = 1, watch_consignment = true, alert_opened = true, alert_freed = true,});var res = await http.SendAsync(req);var body = await res.Content.ReadFromJsonAsync<JsonElement>();