# Hatalar ve Limitler

Hata kodları, origin doğrulama, hız sınırı
Kaynak: https://selwise.com/docs/api-reference/errors-and-limits

Public API'nin hata gövdesi, durum kodları, hız sınırları ve boyut sınırları. Hangi isteğin neden reddedildiğini anlamak için önce [Kimlik Doğrulama ve Erişim](/docs/api-reference/authentication) sayfasındaki sıraya, sonra buradaki tablolara bakın.

## Hata gövdesi

Hata yanıtları bir JSON nesnesidir:

```json
{
  "statusCode": 400,
  "timestamp": "2026-10-09T09:12:00.000Z",
  "path": "/api/v1/public/sites/SITE_KEY/events/batch",
  "method": "POST",
  "message": "Validation failed",
  "errors": ["events.0.name: name must be a string"]
}
```

| Alan | Anlamı |
| --- | --- |
| `statusCode`, `timestamp`, `path`, `method` | Her hatada vardır |
| `message` | İnsan için İngilizce cümle. Programınız bunun metnine bakmamalı |
| `code` | Yalnızca kodlu hatalarda: kararlı, `SCREAMING_SNAKE` bir ad (`MODULE_NOT_ENTITLED`, `SITE_NOT_VERIFIED`, `VALUE_TOO_LONG`). Programınız bu alana bakmalı |
| `params` | Kodlu hatada cümlenin değerleri (`{ "siteKey": "..." }`) |
| `errors[]` | Yalnızca doğrulama hatasında: `alan.yolu: neden` biçiminde satırlar |

Sunucu hatası (`5xx`) hiçbir iç ayrıntı taşımaz.

## Durum kodları

| Kod | Ne zaman | Yeniden dene |
| --- | --- | --- |
| `200`, `201` | Başarı; `POST` uçları `201` döner. **Ama** analitik uçlar `success: false` ile de başarı kodu dönebilir; gövdeye bakın | Hayır |
| `304` | Yalnızca [SSR ucu](/docs/api-reference/ssr-api): `If-None-Match` eşleşti | Hayır |
| `400` | İstek geçersiz: gövde doğrulaması, zorunlu alan eksik, bilinmeyen alan, sınırı aşan değer | Hayır; düzeltin |
| `401` | `x-selwise-api-key` başlığı hiç gönderilmedi (SSR ve izin uçları) | Hayır |
| `402` | Hesabın sözleşmesinde bu modül yok (`MODULE_NOT_ENTITLED`). Panelde ilgili ekran da görünmez | Hayır; hesap yöneticinizle konuşun |
| `403` | Kanal doğrulanmamış, alan adı yetkisiz, API anahtarı geçersiz ya da kapsamı yetersiz (`BUSINESS_EVENTS_SCOPE_REQUIRED`: iş olayı mobil anahtarla geldi ve geçiş süresi bitti), hesap teslimatı kapalı, ya da kanal imzalı kimliği zorunlu kılmışken `traits` imzasız bir tarayıcıdan geldi (`IDENTITY_NOT_VERIFIED`) | Hayır |
| `404` | Site anahtarı bilinmiyor, ya da bir kayıt yok (örneğin `SITE_USER_NOT_IDENTIFIED`, `FEED_TOKEN_INVALID`) | Hayır |
| `409` | Durum çakışması (`FEED_SYNC_IN_PROGRESS`: aynı besleme için bir senkronizasyon sürüyor) | Evet, bir süre sonra |
| `413` | Gövde sınırı aşıldı (aşağıda) | Hayır; küçültün |
| `429` | Hız sınırı. `IDENTIFY_LIMIT` ise bir tarayıcı bir günde çok sayıda farklı müşteri numarasıyla tanıtıldı; ertesi gün açılır | Evet, `Retry-After` kadar sonra (`IDENTIFY_LIMIT` hariç) |
| `503` | Veritabanı bağlantı havuzu dolu (`DB_POOL_EXHAUSTED`) ya da bakım penceresi | Evet |
| `504` | İstek 30 saniyede tamamlanamadı | Evet, küçülterek |

`5xx` ve `429` geçici sayılır; bir istemci bunları üstel geri çekilmeyle (ör. 1, 2, 4 saniye, en çok birkaç deneme) yeniden denemelidir. `4xx` yeniden denemekle düzelmez.

## Bilinmeyen alan 400 verir

Sunucu, gövdesini sınıfla doğruladığı uçlarda tanımadığı alanı **reddeder**; sessizce yok saymaz.

> **Alan adını yanlış yazmak tüm isteği düşürür**
>
> `productItemCode` yerine `product_code` yazmak, `events/batch` içindeki tek bir olayda bile tüm batch'i `400` yapar. Hata mesajı hangi alanın sorunlu olduğunu söyler (`events.2.product_code: property product_code should not exist`).

| Uç | Gövde doğrulaması |
| --- | --- |
| `events/batch`, `users/identify`, `users/traits`, `newsletter`, `contacts/consent`, `business-events`, `scenarios/inbox` ve `inbox/ack`, `product-metrics/batch`, `push/subscribe`, `experiments/track`, `segments/evaluate` | Sınıfla doğrulanır; bilinmeyen alan `400`. Sorgu parametreleri sınıfla doğrulanan uçlar da (`product-metrics`, `scenarios/inbox`) bilinmeyen parametreyi reddeder |
| `orders` | Doğrulanmaz; bilinmeyen alan yok sayılır (yalnızca `id` alanı `400`) |
| `consent` | Sınıfla doğrulanır: `categories` zorunlu, bilinmeyen üst alan `400` |
| `search/log`, `search/click`, `search/zero-results`, `recommendations/*` | Doğrulanmaz; eksik zorunlu alan `400` ya da `500` olabilir, bilinmeyen alan yok sayılır |

## Yazmadan denemek: dry-run

Yazma uçlarının çoğu `x-selwise-dry-run: 1` başlığını tanır: istek gerçek çağrıyla **aynı** kimlik doğrulamasından ve gövde doğrulamasından geçer, ama işlem **çalıştırılmaz**. Hiçbir kayıt yazılmaz, olay kaydedilmez, senaryo kuyruğuna bir şey girmez. Yanıt, ucun kendi başarı koduyla ve şu gövdeyle döner:

```json
{ "dryRun": true, "valid": true, "message": "…", "request": { "orderId": "ORDER_12345" } }
```

Geçersiz bir istek ise gerçek çağrıdaki hatayı alır (`400` ve `errors[]`, `403`, `404` ...). Entegrasyonunuzu canlı veriye dokunmadan denemek, CI'da sözleşmeyi doğrulamak ya da dokümandaki **Dene** paneli için kullanılır. Bir ucun dry-run destekleyip desteklemediği o ucun kutusunda yazar; desteklemeyen bir uca bu başlıkla istek atarsanız `400` (kod `DRY_RUN_UNSUPPORTED`) alırsınız ve istek çalıştırılmaz.

## Hız sınırları

Sınırlar **dakika başına, IP başına ve uç başına** sayılır: bir ucun kovası, aynı IP'nin başka bir uca yaptığı isteklerle paylaşılmaz. Aşağıdakiler varsayılan değerlerdir.

| Uç | Sınır |
| --- | --- |
| `config`, `events/batch`, `product-facts` | 1000 istek |
| `events/batch` (ek) | Ziyaretçi (ya da oturum) başına 120, aynı kanalda bir IP için 1200 |
| `ssr/enrichments` | **API anahtarı** başına 6000 (IP değil) |
| `business-events` | 300 |
| `experiments/track`, `segments/evaluate` | 120 |
| `experiments/assign`, `scenarios/inbox`, `scenarios/inbox/ack`, `push/subscribe`, `push/unsubscribe`, `unsubscribe` | 60 |
| `newsletter` | 20 |
| `messaging/.../events` (sağlayıcı webhook'u), `orders`, `orders/:orderId/status` | 600 |
| `identify`, `traits`, `consent`, `search/log`, `search/click`, `search/zero-results`, `recommendations/track/*` | **Sınırsız**: veri kaybı olmasın diye. Tek istisna: `identify` aynı tarayıcıdan (`visitorId`) günde en fazla 5 **farklı** müşteri numarası kabul eder, fazlası `429` ve `IDENTIFY_LIMIT` alır. İmzalı çağrı ([İmzalı Kimlik](/docs/integration/identity-verification)) bu sınıra takılmaz |
| Diğer her uç (`tracking-config`, `integrations`, `campaigns`, `scripts`, `search`, `search-config`, `search/suggestions`, `recommendations`, `recommendations/:id/products`, `product-metrics/*`, `enrichments`, `app/enrichments`, `metrics`, `contacts/consent`, `feeds/:token`) | 100 |

Yanıtlar `X-RateLimit-Limit` ve `X-RateLimit-Remaining` başlıklarını taşır. Aşıldığında `429` ve saniye cinsinden `Retry-After` döner. Gövde ucun sınırlayıcısına göre biraz farklıdır (`ThrottlerException: Too Many Requests` ya da `{ "error": "Too Many Requests", "retryAfter": 12 }`); `Retry-After` başlığına güvenin.

SSR ucu bilerek anahtar başına sayılır: sizin sunucularınız bütün mağaza trafiğini birkaç adresten taşır, IP başına sayılsaydı paylaşılan kovayı saniyeler içinde tüketir ve widget'ınızı, olay akışınızı ve aramanızı da durdururdu.

### 429 alırsanız

| Sebep | Çözüm |
| --- | --- |
| Olayları tek tek gönderiyorsunuz | `events/batch` ucunda 50-200 olayı tek istekte toplayın |
| Sunucudan arama, öneri ya da ürün sayısı çağrısı | Yanıtı kendi önbelleğinizde 1-5 dakika tutun; tek IP'den çıkan trafik tek kovaya yazılır |
| Döngü içinde sipariş | Siparişleri `orderId` ile tekilleştirip yayın |
| Hâlâ sınırda | Hesap yöneticiniz ortamın sınırlarını yükseltebilir; kendi tarafınızda `Retry-After` kadar bekleyin |

Widget bu sınırlara zaten uyar; sorun genellikle kendi yazdığınız sunucu tarafı entegrasyonlarda çıkar.

## Boyut sınırları

| Sınır | Değer | Aşılırsa |
| --- | --- | --- |
| JSON istek gövdesi (besleme hariç) | Genel varsayılan **100 KB** | `413` ve kod `ENTITY_TOO_LARGE`; mesaj sınırı söyler |
| Besleme gönderimi (her biçim, JSON dahil) | 50 MB | `413` ve kod `FEED_BODY_TOO_LARGE` |
| `events/batch` | 200 olay, olay başına 2 KB `metadata` | `400` |
| `contacts/consent` | 500 kayıt | `400` |
| `product-metrics/batch` | 50 ürün | `400` |
| SSR yanıtı | 256 KB markup | Kural sınırında kesilir |
| Müşteri kimliği (`siteUserId`, `externalId`) | 64 karakter | `400` (kimliklendirmede), siparişte bağlantı düşer |
| Ürün kodu | 100 karakter | Zenginleştirmede boş yanıt, olaylarda kabul edilir ama eşleşmez |

## Zaman aşımı

İstekler 30 saniyede tamamlanmazsa `504` döner. Veri aktarımı gibi büyük işlemler kendi uçlarında daha uzun süre alır; satır içi gönderimde istek başına 1000 kayıt sınırı vardır, bkz. [Veriyi Hazırlama](/docs/data-import/preparing-data).

Sunucu taraflı çağrılarda (özellikle SSR) kendi zaman aşımınızı kısa tutun: [Sunucu Taraflı Render API](/docs/api-reference/ssr-api#zaman-aşımı-ve-yedek-davranışı).

## localhost

Yerel geliştirme adresinden gelen `Origin`/`Referer` **üretimde kabul edilmez**. Bu kapatılamaz: kabul edilseydi herkes kendi makinesinden sizin sitenizin adına veri gönderebilirdi. Yerel geliştirme için ayrı bir test kanalı tanımlayın.

## Sırada ne var

- [Kimlik Doğrulama ve Erişim](/docs/api-reference/authentication)
- [Takip Sorunları](/docs/troubleshooting/tracking-issues) — Ağ sekmesinde bir hatayı teşhis etme
