Brevo API: Geliştiriciler İçin Pratik Bir Kılavuz
Geliştiriciler için Brevo API kılavuzu: kimlik doğrulama, temel URL, kişiler, işlemsel e-posta, kampanyalar, CRM nesneleri, webhook'lar, hız limitleri ve gerçek dünya kısıtları.
Brevo, işlemsel mesajlaşmayı, pazarlama kampanyalarını, kişi verisini ve CRM kayıtlarını kapsayan tek bir REST API sunar. İlk isteğin 201 döndürmesi yaklaşık iki dakika sürer. Veriyi sessizce kaybetmeyen bir üretim entegrasyonu kurmak ise çok daha uzun sürer, çünkü en çok önem taşıyan kısıtların birkaçı ya belgelenmemiştir ya da API’nin kendisi hakkında bildirdiği şeyle çelişir.
Bu kılavuz her iki tarafı da kapsar: ilk günden ihtiyacınız olan uç noktalar, SDK’lar ve kimlik doğrulama ile yayına almadan önce etrafından dolaşarak tasarlamanız gereken platform limitleri.
Brevo API neleri kapsar
Her şey tek bir sunucu ve tek bir sürüm yolu altında yer alır. Geliştirici dokümantasyonu yüzeyi dört ürün alanına ayırır:
- Mesajlaşma: toplu gönderimler, zamanlama ve mesaj etkinliği dahil olmak üzere işlemsel e-posta, SMS ve WhatsApp.
- Pazarlama platformu: kişiler, listeler, segmentler ve e-posta kampanyaları.
- eTicaret: ürünler, siparişler ve müşteri olayı takibi.
- Conversations: sohbet bileşeni ve programatik konuşma yönetimi.
Bu alanlar tek bir hesabı, tek bir kişi veritabanını ve tek bir API anahtarını paylaşır. Bu hem pratiktir hem de zaman zaman tehlikelidir: verinin hazırlık ortamındaki hâline göre yazılmış bir betik, kampanyalarınızın gönderim yaptığı aynı kişilerle konuşuyordur.
İşlemsel ile pazarlama arasındaki fark
İki aile, birbirine karıştırılması en yaygın tasarım hatası olacak kadar farklı davranır.
| İşlemsel | Pazarlama | |
|---|---|---|
| Birincil uç nokta | POST /v3/smtp/email | POST /v3/emailCampaigns |
| Adresleme | İstekte açıkça belirtilen alıcılar | listIds veya segmentIds |
| Tetikleyici | Uygulamanız, gerçek zamanlı | Zamanlanmış veya talep üzerine gönderilir |
| Tipik hacim biçimi | Sürekli, seferde bir mesaj | Ani yükselen, tek büyük gönderim |
| Hız limiti duruşu | Çok yüksek, standart planlarda saniyede 1.000 istek | Düşük, kampanya uç noktaları genel üst sınıra tabidir |
Brevo’nun sizin için doğru platform olup olmadığına hâlâ karar veriyorsanız, platform genel bakışı o konuyu ele alıyor.
Kimlik doğrulama ve anahtar yönetimi
Brevo, özel bir başlıkta düz bir API anahtarı kullanır. Başlığın adı Authorization değil api-key şeklindedir ve Bearer öneki yoktur. Bu durum, daha önce başka bir mesajlaşma API’si kullanmış olan hemen herkesin ayağını kaydırır.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"Anahtarlar Brevo uygulamasında hesap ayarları altında, SMTP ve API bölümünde, API anahtarları sekmesinde üretilir. Her anahtara, onu kullanan sisteme bağlı açıklayıcı bir ad verin. Anahtar değeri üretildiğinde tam olarak bir kez gösterilir, dolayısıyla kaybederseniz eskisini kurtarmak yerine yenisini üretirsiniz.
Birkaç pratik kural:
- Her dağıtım hedefi ve her servis için ayrı bir anahtar verin. Ele geçirilmiş bir anahtarı iptal etmek asla birbiriyle ilgisiz üç sistemi devre dışı bırakmamalıdır.
- Standart API anahtarları hesap genelindedir. Herhangi bir anahtarı kişilere, gönderime ve CRM verisine tam erişim olarak görün.
- Brevo ayrıca başka Brevo hesapları adına hareket eden uygulamalar için OAuth 2.0 destekler; bu, anahtar akışının yanında kimlik doğrulama şemalarında anlatılır.
- AI asistanlarının kullandığı MCP sunucusu ayrı bir token alır ve bearer başlığı kullanır. Bu token aynı API anahtarları ekranında üretilir ama bir REST anahtarıyla birbirinin yerine geçmez.
Temel URL, sürümleme ve ilk yazma işleminiz
Temel URL https://api.brevo.com/v3/ adresidir. Sürüm bir başlıkta değil yolda yer alır ve güncel nesil v3’tür. Bu kılavuzdaki her yol o temele görecelidir.
İlk yazma işlemi, ilk okumadan daha bilgilendiricidir, çünkü hesabın genellikle yanlış yapılandırılmış kısımlarını (özellikle doğrulanmış göndericileri) çalıştırır:
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sender": { "name": "Ops", "email": "[email protected]" }, "to": [{ "email": "[email protected]", "name": "Dev" }], "subject": "First transactional send", "htmlContent": "<html><body><p>It works.</p></body></html>", "tags": ["smoke-test"] }'Başarılı bir gönderim messageId ile birlikte 201 döndürür. Zamanlanmış bir gönderim 202 döndürür.
Gerçekten kullanacağınız uç noktalar
Kişiler
POST /v3/contacts bir kişi oluşturur. Gövde email, özel alanlar için bir attributes haritası, listIds, kendi harici anahtarınız için ext_id ve pratikte en çok önem taşıyan iki bayrağı alır: çağrıyı bir upsert işlemine dönüştüren updateEnabled ve yanıtın kişi kimliğini döndürmesini sağlayan getId.
Okuma işlemleri GET /v3/contacts üzerinden yapılır; bu uç nokta limit (varsayılan 50, en fazla 1000) ve offset ile sayfalar, ayrıca UTC olarak modifiedSince ve createdSince destekler. Artımlı senkronizasyonlar tüm listeyi taramak yerine modifiedSince üzerine yaslanmalıdır. filter parametresinin yalnızca eşitlik operatörünü desteklediğini unutmayın, dolayısıyla daha ifadeli her şey bir segmentin işidir.
Toplu yükleme için POST /v3/contacts/import uç noktası fileUrl, fileBody veya jsonBody kabul eder, listIds hedefler ve eşzamansız çalışarak bir processId döndürür. Brevo 10 MB’lık bir gövde üst sınırı belgeler ve ayrıştırma yükü şişirdiği için 8 MB civarında kalmayı önerir. Sonucu yoklama yaparak değil öğrenerek almak için notifyUrl sağlayın.
İşlemsel e-posta
POST /v3/smtp/email asıl iş yükünü taşır. sender, to, subject ve htmlContent alanlarının ötesinde bilinmeye değer alanlar şunlardır:
paramsile birliktetemplateId, satır içi içeriği bir Brevo şablonu ve değişken ikameleriyle değiştirir. Tekil sürüm parametreleri 100 KB, kümülatif parametreler 1000 KB ile sınırlıdır.messageVersions, kişiselleştirilmiş varyantları tek çağrıda gönderir, sürüm başına en fazla 99 alıcıyla.tags, her zaman ayarlamanız gereken alan. Etiketler webhook olaylarında geri gelir ve bir teslimat olayını onu üreten kod yoluyla ilişkilendirmenin tek ucuz yoludur.scheduledAtilebatchId, grup olarak iptal etmek isteyebileceğiniz ileri tarihli gönderimler için.headers, özel SMTP başlıkları için Title-Case biçiminde.
Tek bir istek en fazla 2.000 alıcı kabul eder. Bu uç nokta ile kampanya gönderimi arasındaki farka mesajlaşma stratejisi açısından bakmak için işlemsel e-posta kılavuzu uygun kaynaktır.
E-posta kampanyaları
POST /v3/emailCampaigns uç noktası name ve sender alanlarını, ayrıca tam olarak bir içerik kaynağını gerektirir: htmlContent (en az 10 karakter, 1 MB altında), htmlUrl veya templateId. Hedef kitle recipients içinde listIds veya segmentIds olarak verilir ve scheduledAt alanı YYYY-MM-DDTHH:mm:ss.SSSZ UTC biçimini kullanır. Tamamlayıcı rotalar anında gönderim, test gönderimi, durum güncelleme ve kampanya raporunu çekme işlemlerini kapsar.
Şirketler, anlaşmalar ve nesneler
Brevo’nun CRM’inde birbiriyle örtüşen iki yazma yolu vardır ve doğru olanı seçmek önemlidir.
CRM rotaları POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id} ve anlaşmalar için eşdeğer kümedir. Bunlar eşzamanlıdır. Bir PATCH, değişiklik uygulandığında 204 döndürür.
Nesneler API’si toplu yoldur: POST /v3/objects/{object_type}/batch/upsert istek başına en fazla 1000 kayıt ve 1 MB, kayıt başına en fazla 500 öznitelik ve kayıt başına nesne türü başına en fazla 10 ilişki kaydı alır. Uygulandı değil kabul edildi anlamına gelen, processId içeren 202 döndürür.
curl -X POST https://api.brevo.com/v3/objects/company/batch/upsert \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [ { "identifiers": { "id": 12345 }, "attributes": { "domain": "acme.example", "industry": "retail" } } ] }'Brevo CRM kılavuzu nesne modelini operatör tarafından ele alıyor.
Resmi SDK’lar
Brevo, istemcileri getbrevo GitHub organizasyonu altında sürdürür:
| Dil | Depo |
|---|---|
| Node.js | github.com/getbrevo/brevo-node |
| Python | github.com/getbrevo/brevo-python |
| PHP | github.com/getbrevo/brevo-php |
| Java | github.com/getbrevo/brevo-java |
| C# | github.com/getbrevo/brevo-csharp |
| Go | github.com/getbrevo/brevo-go |
| Ruby | github.com/getbrevo/brevo-ruby |
Node istemcisi @getbrevo/brevo olarak kurulur:
npm install @getbrevo/brevoimport { BrevoClient } from "@getbrevo/brevo";
const brevo = new BrevoClient({ apiKey: process.env.BREVO_API_KEY });
const result = await brevo.transactionalEmails.sendTransacEmail({ subject: "Order confirmed", htmlContent: "<html><body><p>Thanks for your order.</p></body></html>", tags: ["order-confirmation"],});
console.log("Message ID:", result.messageId);Python istemcisi pip install brevo-python ile kurulur. İki uç nokta için bir SDK bağımlılığı taşımak istemiyorsanız, ham HTTP yüzeyi doğrudan çağrılabilecek kadar küçüktür ve bu sizi SDK sürüm dalgalanmalarından da korur:
import osimport requests
BASE = "https://api.brevo.com/v3"HEADERS = { "api-key": os.environ["BREVO_API_KEY"], "Content-Type": "application/json",}
def upsert_contact(email, attributes, list_ids): response = requests.post( f"{BASE}/contacts", headers=HEADERS, json={ "email": email, "attributes": attributes, "listIds": list_ids, "updateEnabled": True, }, timeout=30, ) response.raise_for_status() return responseAyrıca AI asistanları için https://mcp.brevo.com/v1/brevo/mcp adresinde, aynı ayarlar ekranında üretilen bir bearer token ile kimlik doğrulayan bir MCP sunucusu vardır. Keşif ve hesap soruları için kullanışlıdır, üretim veri yolları için değil.
Webhook’lar
Webhook’lar, bir gönderimden sonra ne olduğunu öğrenme biçiminizdir. POST /v3/webhooks bir tane oluşturur; url, events, type ve isteğe bağlı olarak channel (email veya sms), batched, özel headers ve bir auth nesnesi alır.
Farklı olay sözlüklerine sahip üç webhook türü vardır:
- İşlemsel:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - Pazarlama:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - Gelen: ek olarak bir
domaingerektireninboundEmailProcessedvereply.
curl -X POST https://api.brevo.com/v3/webhooks \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://yourapp.example/hooks/brevo", "type": "transactional", "events": ["delivered", "hardBounce", "spam", "unsubscribed"], "description": "Deliverability signals" }'Doğru yapılması gereken üç şey var. Birincisi, bir hesap tüm türler genelinde en fazla 40 webhook tutabilir, dolayısıyla olay başına bir uç nokta kaydetmek yerine işleyicinizin içinde olaya göre yönlendirme yapın. İkincisi, hacim beklediğinizde batched bayrağını kullanın, çünkü çok sayıda olay taşıyan tek bir istek, çok sayıda isteğe göre işlenmesi çok daha ucuzdur. Üçüncüsü, alıcıyı koruyun: Brevo gönderim IP aralıklarını yayımlar ve uç noktanızı bu aralıklarla sınırlamak belgelenmiş yaklaşımdır. İkinci bir katman olarak headers alanı üzerinden kendi paylaşılan sırrınızı ekleyin.
İşleyiciler idempotent olmalıdır. Mesaj kimliği artı olay türü artı zaman damgasını yinelenme giderme anahtarı olarak kullanın.
Hız limitleri ve hata yönetimi
Brevo’nun hız limitleri uç nokta ve plan katmanı başınadır ve uç noktalar arasındaki fark devasadır.
| Uç nokta | Standart | Professional ve Enterprise |
|---|---|---|
POST /v3/smtp/email | 1.000 RPS | 2.000 RPS |
POST /v3/transactionalSMS/send | 150 RPS | 200 RPS |
/v3/contacts/... | 10 RPS, 36.000 RPH | 20 RPS, 72.000 RPH |
POST /v3/events | 10 RPS, 36.000 RPH | Enterprise’da daha yüksek |
GET /v3/smtp/emails | 2 RPS, 7.200 RPH | 3 RPS, 10.800 RPH |
| Diğer her şey | 100 RPH | 200 RPH |
Canınızı yakacak satır o son satırdır. Gönderim pratikte ölçülmezken kampanya yönetimi, CRM okumaları ve idari çağrıların çoğu standart planlarda saatte 100 isteklik bir bütçeyi paylaşır. Her yazma işleminden önce bir şirket kaydı okuyan naif bir geri doldurma işlemi, bir saatlik kotayı iki dakikadan kısa sürede tüketir.
Her yanıt x-sib-ratelimit-limit, x-sib-ratelimit-remaining ve x-sib-ratelimit-reset başlıklarını taşır. Bunları yalnızca hatada değil, başarıda da okuyun. Limiti aşmak 429 döndürür ve doğru tepki, sıfırlama başlığındaki aralık kadar beklemek ve ardından titreşimli üstel geri çekilme uygulamaktır.
async function callBrevo(path, init, attempt = 0) { const response = await fetch(`https://api.brevo.com/v3${path}`, { ...init, headers: { "api-key": process.env.BREVO_API_KEY, "Content-Type": "application/json", ...init.headers }, });
if (response.status === 429 && attempt < 5) { const reset = Number(response.headers.get("x-sib-ratelimit-reset") || 1); const backoff = Math.pow(2, attempt) * 250 + Math.random() * 250; await new Promise((r) => setTimeout(r, reset * 1000 + backoff)); return callBrevo(path, init, attempt + 1); }
return response;}429 ve 5xx yanıtlarını yeniden deneyin. 400 veya 409 yanıtlarını asla körü körüne yeniden denemeyin, çünkü ikisi de genelde isteğin erken değil yanlış olduğu anlamına gelir ve özellikle 409, tekrar değil farklı bir eylem gerektirir.
Posta göndermeden test etme
İşlemsel bir gönderime X-Sib-Sandbox başlığını drop değeriyle ekleyin. Brevo isteği doğrular, messageId ile 201 döndürür, hiçbir şey teslim etmez ve e-posta kaydı yazmaz.
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "X-Sib-Sandbox: drop" \ -H "Content-Type: application/json" \ -d '{ "sender": { "email": "[email protected]" }, "to": [{ "email": "[email protected]" }], "subject": "Sandbox", "htmlContent": "<p>hi</p>" }'Bunun neyi kanıtlayıp neyi kanıtlamadığını anlayın. Sandbox modu yalnızca istek biçimini doğrular. Gönderici kimlik doğrulaması, şablon işleme veya teslim edilebilirlik hakkında hiçbir şey söylemez. Kişilere veya CRM verisine dokunan her şeyin entegrasyon testi için ayrı bir Brevo hesabı tutun, çünkü sandbox modu gönderimi kapsar, API’nin geri kalanını değil.
Entegrasyon tasarımınızı şekillendiren limitler
Bunlar yalnızca bir entegrasyon gerçek bir hesap üzerinde hacimli çalıştığında ortaya çıkan kısıtlardır. Birkaçı API’nin kendisi hakkında söylediğiyle çelişir. Hiçbiri pazarlığa açık değildir, dolayısıyla tek makul tepki etraflarından dolaşarak tasarlamaktır.
Şirketler alan adı gerektirir ve alan adı başına yalnızca bir şirket olur
GET /v3/crm/attributes/companies her özniteliği zorunlu değil olarak bildirir ve şirket oluşturma referansı yalnızca name alanını zorunlu listeler. Pratikte, boş olmayan bir domain özniteliği olmadan POST /v3/companies çağrısı, eksik zorunlu varsayılan öznitelikler hakkında bir mesajla 400 döndürür. Boş bir dize de tıpkı hiç vermemek gibi başarısız olur.
Daha kötüsü, alan adı benzersizliği zorunlu tutulur. Zaten kullanımda olan bir alan adındaki ikinci bir şirket 409 döndürür. B2B ticaret için bu yapısaldır: tek bir alıcı e-posta alan adını paylaşan bağlı şirketler Brevo’da ayrı şirketler olarak var olamaz. Bir kişiyi senkronize etmek de o kişinin e-posta alan adında bir şirketin belirmesi için yeterlidir, dolayısıyla bir oluşturma işlemi kimsenin açıkça oluşturmadığı bir şirketle çakışabilir. Doğru işleyici, 409 durumunda başarısız olmak veya yeniden denemek yerine mevcut şirketi sahiplenir.
Tanımlanmamış öznitelikler sessizce atılır
Bu, platformdaki en tehlikeli davranıştır ve Brevo bunu açıkça belgeler: bir öznitelik istekte görünüyor ama nesne şemasında daha önce tanımlanmamışsa hiçbir şey olmaz. Hata yok, öznitelik oluşturma yok, uyarı yok.
Dolayısıyla 2xx yanıtı verinizin ulaştığının kanıtı değildir. Yazmadan önce şemayı okuyun, kendi istemcinizde tanımlanmamış her şeyi eleyin ve öznitelikleri var olmayan bir senkronizasyonu, kimse fark etmeden bir ay boyunca yarım kayıt yazmasındansa çalıştırmayı reddedin.
Öznitelik filtreleri kabul edilir ve yok sayılır
GET /v3/companies?filters[attributes.domain]=... çağrısı 200 döndürür ve filtreyi yok sayar. Tamamen farklı iki filtre aynı kayıtları döndürür. O rota üzerinden bir şirketi özniteliğe göre aramanın çalışan bir yolu yoktur.
Filtresiz listenin büyük hesaplarda her sayfa boyutunda 504 ile zaman aşımına uğramasıyla birleşince, mevcut bir şirket belgelenmiş yol üzerinden gerçekten bulunamaz hâle gelebilir. Geçici çözüm, hızlı, sayfalanmış ve öznitelikleri döndüren GET /v3/objects/company/records rotasını sort=desc ile makul sayıda sayfayla sınırlı olarak taramaktır. Az önce 409 tetikleyen bir şirket neredeyse her zaman birkaç dakika önce oluşturulmuştur, dolayısıyla en yeniden başlayan tarama onu hızla bulur.
Nesne türü başına bir milyon kayıt ve toplu silme yok
Bir nesne türü bir milyon kayıt tuttuğunda POST /v3/objects/{type}/batch/upsert çağrısı 400 döndürür. Oluşturma kadar güncellemeyi de engeller: mevcut bir kaydı kendi sayısal kimliğiyle adreslemek de aynı şekilde başarısız olur. Tüm nesne yazma yolu bir anda kapanır.
Tavanın altına geri inmek yavaştır, çünkü POST /v3/objects/{type}/batch/delete çağrısı company gibi Brevo standart nesne türleri için 403 döndürür. Tek rota, çağrı başına tek kayıt ve yaklaşık 156 ms süren DELETE /v3/companies/{id} rotasıdır. Bu şekilde 124.000 kaydı temizlemek 20 paralel işçiyle saatler aldı. Tavanı başarısız bir senkronizasyonla keşfetmek yerine kayıt sayısını düzenli olarak izleyin ve yüksek hacimli güncellemeleri böyle bir limiti olmayan PATCH /v3/companies/{id} üzerinden yönlendirin.
ext_id sizin değil Brevo’nun kimliğidir
Nesne kayıtlarında identifiers.ext_id, Brevo’nun kendi CRM şirket kimliğini, Mongo tarzı bir dizeyi tutar. Serbest bir harici anahtar değildir. ext_id alanını kendi platformunuzun tanımlayıcısına ayarlayarak bir upsert anahtarlamak eşleştirme yerine kopyalar oluşturur. Sizin harici kimliğiniz kendine ait, tanımlanmış bir özniteliğe aittir.
Nesne upsert işlemleri eşzamansızdır, CRM yazmaları değil
batch/upsert bir 202 ve processId döndürür, ardından daha sonra uygular. Var olmayan bir kimlik eşzamansız olarak başarısız olur ve çağırana yine 202 döner. PATCH /v3/companies/{id} ise 204 döndürür ve eşzamanlı olarak uygulanır. Senkronizasyonunuz başarı bildiriyorsa, takip eden bir okuma olmadan bu kelimeyi yalnızca eşzamanlı yol hak eder.
Kısa bir entegrasyon kontrol listesi
- Servis ve ortam başına ayrı API anahtarları, personel değişikliklerinde döndürülür.
- Tüm yazma işlemleri hız limiti başlıklarını okuyan ve 429’da geri çekilen tek bir istemciden geçer.
- Öznitelik şeması başlangıçta doğrulanır ve öznitelikleri eksikse senkronizasyon çalışmayı reddeder.
- Şirket oluşturmada 409, yeniden dene değil sahiplen demektir.
- Toplu yollar verim için nesne API’sini, doğrulanması gereken her şey için CRM rotalarını kullanır.
- Webhook’lar idempotenttir, toplu çalışır, IP kısıtlıdır ve paylaşılan bir sır başlığı taşır.
- Artımlı kişi senkronizasyonları tam liste taraması değil
modifiedSincekullanır.
Bu katmanı kurmak ve sürdürmek gerçek bir mühendislik işidir: şema doğrulama, geri çekilme, sahiplenme mantığı, mutabakat. Tajo bunu üstlenmek için var; Shopify ve ticaret verisini Brevo kişileri, şirketleri ve olaylarıyla senkronize tutar, üstelik kimse yeniden deneme ve yinelenme giderme mantığını elle yazmadan. Bunu kendiniz kuruyorsanız, Brevo entegrasyon kılavuzu koddan önce gelen veri modeli tercihlerini anlatıyor.
Temel çıkarımlar
- API,
https://api.brevo.com/v3/adresinde tek bir REST yüzeyidir ve bearer token yerine birapi-keybaşlığıyla kimlik doğrular. - Hız limitleri son derece dengesizdir: gönderim pratikte ölçülmezken diğer uç noktaların çoğu standart planlarda saatte 100 isteği paylaşır.
- Yedi dil için resmi SDK’lar mevcuttur ama HTTP yüzeyi, yalnızca birkaç uç noktaya ihtiyacınız olduğunda doğrudan çağrılabilecek kadar basittir.
- Sandbox modu yalnızca istek biçimini doğrular, dolayısıyla gönderim dışındaki her şeyi test etmek için ayrı bir hesap tutun.
- 2xx yanıtı bir yazma işleminin uygulandığını kanıtlamaz. Tanımlanmamış öznitelikler sessizce düşer ve nesne upsert işlemleri eşzamansızdır.
- Sabit limitlerin etrafından dolaşarak tasarlayın: alan adı başına bir şirket, nesne türü başına bir milyon kayıt, standart nesneler için toplu silme yokluğu ve sessizce hiçbir şey yapmayan öznitelik filtreleri.