شكل الخطأ
{
"error": {
"code": "VERSION_CONFLICT",
"message": "The menu is at version 16.",
"request_id": "req_01JA9Z",
"details": { "current_version": 16 }
}
}- اعتمد على
codeفي شيفرتك، لا علىmessage. الرسالة قد تتغير. - كل رد يحمل
X-Request-Id. أرسله لنا عند طلب الدعم.
الرموز
| HTTP | الرمز | المعنى |
|---|---|---|
| 400 | VALIDATION_FAILED |
حقل ناقص أو غير صحيح، أو معرف فيه :. التفاصيل في details[] مع path |
| 400 | URL_NOT_ALLOWED |
عنوان webhook أو تسعير ليس https عاما |
| 400 | IDEMPOTENCY_KEY_MISSING |
أمر تعديل بلا Idempotency-Key |
| 401 | KEY_UNKNOWN |
معرف المفتاح غير موجود |
| 401 | KEY_REVOKED |
المفتاح ملغى |
| 401 | KEY_MODE_MISMATCH |
مفتاح تجربة على عنوان التشغيل، أو العكس |
| 401 | TIMESTAMP_SKEW |
الوقت بعيد عن وقتنا أكثر من 300 ثانية |
| 401 | NONCE_INVALID |
الرقم العشوائي غير صالح |
| 401 | NONCE_REUSED |
الرقم العشوائي استعمل من قبل |
| 401 | SIGNATURE_INVALID |
التوقيع لا يطابق |
| 403 | SCOPE_MISSING |
الربط لا يحمل الصلاحية. اسمها في details.scope |
| 403 | LINK_REQUIRED |
لا ربط بينك وبين هذا المكان |
| 403 | PARTNER_NOT_CERTIFIED |
طلب تشغيل قبل الاعتماد |
| 403 | PARTNER_SUSPENDED |
حساب الشريك موقوف |
| 404 | NOT_FOUND |
المعرف غير موجود، أو لا يخصك |
| 404 | MENU_NOT_FOUND |
لا توجد قائمة منك لهذا المكان |
| 404 | MENU_VERSION_GONE |
النسخة المطلوبة لم تعد محفوظة. الحالية في details.current_version |
| 409 | VERSION_CONFLICT |
تغيرت القائمة بعد النسخة التي أرسلتها |
| 409 | IDEMPOTENCY_KEY_REUSED |
المفتاح نفسه مع جسم مختلف |
| 409 | IDEMPOTENCY_IN_PROGRESS |
الطلب الأول بالمفتاح نفسه لم ينته بعد |
| 409 | INVALID_TRANSITION |
لا يمكن نقل الطلب إلى هذه الحالة |
| 409 | ALREADY_ACCEPTED |
الطلب قبل من قبل، مثل محاولة رفضه |
| 409 | ORDER_CLOSED |
الطلب انتهى. الحالة في details.status |
| 409 | LOCATION_ALREADY_LINKED |
فرعك هذا مربوط بمكان آخر |
| 409 | LINK_CODE_EXPIRED |
انتهت صلاحية رمز الربط |
| 409 | LINK_CODE_USED |
رمز الربط استعمل |
| 410 | LINK_REMOVED |
ألغى التاجر الربط |
| 413 | PAYLOAD_TOO_LARGE |
الجسم أكبر من 2 ميغابايت |
| 422 | MENU_INVALID |
القائمة تخالف قواعد CM v1 |
| 422 | PRODUCT_INVALID |
المنتج يخالف قواعد CP v1 قريبا |
| 429 | RATE_LIMITED |
تجاوزت الحد. انتظر Retry-After |
| 500 | INTERNAL |
خطأ عندنا |
| 503 | UNAVAILABLE |
صيانة أو ضغط مؤقت |
متى تعيد المحاولة
| الرد | ماذا تفعل |
|---|---|
| 5xx، 429، انقطاع الشبكة | أعد المحاولة بتأخير متزايد، وبنفس Idempotency-Key |
409 IDEMPOTENCY_IN_PROGRESS |
انتظر ثانية ثم أعد |
409 VERSION_CONFLICT |
اقرأ القائمة أو انشرها كاملة، ثم أعد |
| 4xx أخرى | لا تعد. أصلح الطلب |
منع التكرار (Idempotency-Key)
كل POST وPUT وPATCH وDELETE يحتاج ترويسة Idempotency-Key: من 8 إلى 128 حرفا من [A-Za-z0-9_.:-].
- نحفظ المفتاح 24 ساعة مع بصمة الجسم، لكل حساب وبيئة، لا لكل مفتاح API. لذلك تبقى إعادة المحاولة معروفة لنا حتى بعد تدوير المفاتيح.
- المفتاح نفسه مع الجسم نفسه: نرد الرد المحفوظ، ومعه
Idempotent-Replayed: true. لا ينفذ الأمر مرة ثانية. - المفتاح نفسه مع جسم مختلف:
409 IDEMPOTENCY_KEY_REUSED.
المفتاح ليس الرقم العشوائي. إعادة المحاولة تأخذ رقما عشوائيا وتوقيعا جديدين، وتحتفظ بالمفتاح نفسه.
اختر مفتاحا يصف الأمر، مثل accept-ord_7m1x9c، أو menu-plc_9q3w7e-<رقم النسخة عندك>.
async function withRetry(fn, tries = 5) {
for (let i = 0; ; i++) {
try { return await fn(); }
catch (e) {
const retryable = !e.status || e.status >= 500 || e.status === 429 || e.error?.code === 'IDEMPOTENCY_IN_PROGRESS';
if (!retryable || i >= tries - 1) throw e;
await new Promise((r) => setTimeout(r, Math.min(30000, 500 * 2 ** i)));
}
}
}
// المفتاح ثابت في كل المحاولات، والتوقيع جديد في كل محاولة
await withRetry(() => aurmap('POST', `/v1/orders/${id}/accept`, { prep_minutes: 15 }, `accept-${id}`));function with_retry(callable $fn, int $tries = 5) {
for ($i = 0; ; $i++) {
try {
return $fn();
} catch (RuntimeException $e) {
$status = $e->getCode();
$retryable = $status === 0 || $status >= 500 || $status === 429 || $e->getMessage() === 'IDEMPOTENCY_IN_PROGRESS';
if (!$retryable || $i >= $tries - 1) {
throw $e;
}
usleep(min(30000, 500 * (2 ** $i)) * 1000);
}
}
}
with_retry(fn () => aurmap('POST', "/v1/orders/{$id}/accept", ['prep_minutes' => 15], "accept-{$id}"));حدود المعدل
| النوع | الحد |
|---|---|
| كل الطلبات | 600 في الدقيقة لكل حساب وبيئة |
| نشر القائمة كاملة | 12 في الساعة لكل مكان |
| تعديل القائمة والحالة والمخزون | 120 في الدقيقة لكل مكان |
| رموز الربط | 60 في الساعة |
| أوامر الطلبات | 300 في الدقيقة |
| الأحداث | حد يومي لكل حساب وبيئة |
كل رد يحمل X-RateLimit-Limit وX-RateLimit-Remaining وX-RateLimit-Reset. ومع 429 نرسل Retry-After بالثواني.
الحدود مفعلة من أول يوم، وفي الفترة التجريبية المجانية أيضا. وهي لكل حساب وبيئة، لا لكل مفتاح، فلا يغيرها إنشاء مفتاح جديد. إذا احتجت حدا أعلى، اطلبه من الدعم.
الصفحات
القوائم تستعمل مؤشرا (cursor):
aurmap GET '/v1/orders?status=open&limit=100'
aurmap GET '/v1/orders?status=open&limit=100&cursor=c_8Jk2'{ "data": [ { "order_id": "ord_7m1x9c", "…": "…" } ], "next_cursor": "c_8Jk2" }limitمن 1 إلى 100، والافتراضي 50.- المؤشر صالح 24 ساعة. لا تحاول قراءته أو بناءه.
next_cursorفارغ يعني النهاية.