Rate limit'ler, webhook teslim sınırları, senkron action/hook timeout'ları ve development store kotaları. DEV (test) ve PROD (canlı) değerleri FARKLIDIR — dev kasıtlı olarak sıkıdır (incelenmemiş kod platformu zorlamasın diye).
| Uç | Yön | DEV (test) | PROD (canlı) | Aşılırsa |
|---|---|---|---|---|
| GET /plugin-api/* | eklenti → bize | 5 / dk | 120 / dk | 429 plugin.rateLimited |
| POST /plugin-api/* (write) | eklenti → bize | 20 / dk (ayrı write havuzu — okumadan bağımsız) | 429 plugin.rateLimited | |
| POST /plugin-api/oauth/token | eklenti → bize | 5 / dk | 10 / dk | per client_id (brute-force koruması) |
| /plugins/action | bize → eklenti (senkron) | 5 / dk | 60 / dk | plugin.rateLimited |
| /plugins/hook | bize → eklenti (senkron) | 5 / dk | 60 / dk | plugin.rateLimited |
| /plugin-api/capabilities/* | eklenti → bize (yetenek çağrısı) | 5 / dk | 60 / dk | 429 plugin.rateLimited |
| Günlük cap (yalnız DEV) | Callback/action/hook | 200 / gün | yok | 429 |
messaging.send/notify.staff/invoice.issue) install başına tek cap:<id> kovasını paylaşır — legacy /messaging/* ve jenerik /capabilities/* uçları AYNI kovaya sayılır (çift-yol kota bypass'ı yok). Sağlayıcının durum raporu (/status) da bu kovada.Retry-After (sn) değerine uy; header yoksa üstel backoff + jitter. Dev'de testleri ölçülü tetikle; dev limitin gerçekten yetmiyorsa bize yaz.// 429 → Retry-After'a uy; yoksa üstel backoff + jitter
async function callWithRetry(fn, maxAttempts = 5) {
for (let attempt = 1; ; attempt++) {
const res = await fn();
if (res.status !== 429 || attempt === maxAttempts) return res;
const retryAfter = Number(res.headers.get('Retry-After')); // saniye — sunucunun söylediği süre
const waitMs = Number.isFinite(retryAfter) && retryAfter > 0
? retryAfter * 1000
: Math.min(30_000, 1000 * 2 ** (attempt - 1)) * (1 + Math.random() * 0.3); // fallback
await new Promise((r) => setTimeout(r, waitMs));
}
}
const res = await callWithRetry(() =>
fetch(BASE + '/plugin-api/products/list', { headers: { Authorization: 'Bearer ' + apiKey } }),
);Tüm /plugin-api/* yanıtları kota durumunu başlıklarla bildirir:
| Başlık | Anlamı |
|---|---|
| X-RateLimit-Limit | Pencere limiti — okuma kovasında PROD varsayılanı 120 / dk |
| X-RateLimit-Remaining | Pencerede kalan istek |
| X-RateLimit-Reset | Pencere reset zamanı — epoch saniye = now + 60 (sabit pencere) |
| Retry-After | Yalnız 429'da — bu kadar saniye bekle (backoff hesabı yerine buna uy) |
429 gövdesi: { success:false, message:"plugin.rateLimited" }.
| Sınır | Değer |
|---|---|
| Timeout | 10 sn / deneme (redirect takip edilmez) |
| Retry | max 6 deneme, artan aralıklı (1 sn → 1 saat); sonrasında teslim bırakılır |
| Beklenen yanıt | hızlı 2xx — ağır işi async yap (yoksa timeout → retry) |
| İmza | X-Restomenum-Signature (HMAC) — doğrula, ±5 dk replay penceresi |
| Idempotency | envelope id — retry'da aynı id gelir → dedup et |
| Outbound cap (per-install) | yok (event'ler tenant aktivitesiyle gelir) |
Endpoint'in hızlı + idempotent + imza-doğrulamalı olmalı. Yavaş/hatalı endpoint → retry → en sonunda teslim düşer. Bkz. /webhook alıcısı, imza şeması, lifecycle.
| Tür | Timeout | Geç dönersen |
|---|---|---|
| /plugins/action (UI buton) | 8 sn (max 10) | plugin.action.timeout |
| /plugins/hook (before-action) | 5 sn (max 10) | fail-closed (default) → işlem iptal |
Bu sürede { success, message, level, display } dön. Detay: Action ucu · Hook'lar.
Çoğu liste ucunda sayfalama (cursor/offset) parametresi yoktur — uç, tüm listeyi tek yanıtta, uca özel bir üst sınıra (cap) kadar döner. İstisna: customers/list cursor sayfalaması kullanır (after/nextCursor, sayfa başına max 500):
| Uç | Cap | Aşılırsa |
|---|---|---|
| products/list | 2000 | yanıt truncated işaretlenir + total döner |
| categories/list | 500 | — |
| users/get | 200 | — |
| customers/list | 500 / sayfa | cursor sayfalaması (after/nextCursor) — cap değil, sonraki sayfayı çek |
product.*, category.*, user.* oluşturma/güncelleme/silmede gelir).*/get?id= uçlarını kullan (API Genel Bakış).| Limit | Değer |
|---|---|
| Cap (geliştirici başına) | 3 dev store |
| Lifespan | 30 gün; dev portal'a her login'de 30 gün uzar |
| Süre dolunca | panel girişi kapanır (end < now); login'de geri açılır |
| Sahiplik | own-only — dev store yalnız kendi eklentilerini görür/kurar (developerId eşleşmeli) |
| Ücret | DEV'de billing kapalı → eklenti ücretsiz kurulur (checkout yok) |
| E-posta | otomatik doğrulanır; @restomenum.com (ve alt domain) yasak |
| Kayıt | dev hesabı yalnız portal create-dev-store ile açılır (client signUp reddedilir) |
id ile idempotent.