Brevo API: praktický sprievodca pre vývojárov
Sprievodca Brevo API pre vývojárov: autentifikácia, základná URL, kontakty, transakčné e-maily, kampane, CRM objekty, webhooky, limity požiadaviek a reálne obmedzenia.
Brevo poskytuje jedno REST API, ktoré pokrýva transakčné správy, marketingové kampane, kontaktné dáta aj CRM záznamy. Dostať prvú požiadavku k odpovedi 201 trvá približne dve minúty. Postaviť produkčnú integráciu, ktorá ticho nestráca dáta, trvá podstatne dlhšie, pretože viaceré z najdôležitejších obmedzení sú buď nezdokumentované, alebo si protirečia s tým, čo API o sebe hlási.
Tento sprievodca pokrýva obe polovice: endpointy, SDK a autentifikáciu, ktoré potrebujete hneď v prvý deň, a platformové limity, okolo ktorých musíte navrhnúť riešenie ešte pred nasadením.
Čo Brevo API pokrýva
Všetko sa nachádza pod jedným hostiteľom a jednou cestou s verziou. Dokumentácia pre vývojárov delí rozhranie na štyri produktové oblasti:
- Messaging: transakčné e-maily, SMS a WhatsApp vrátane dávkového odosielania, plánovania a aktivity správ.
- Marketingová platforma: kontakty, zoznamy, segmenty a e-mailové kampane.
- eCommerce: produkty, objednávky a sledovanie zákazníckych udalostí.
- Conversations: chatovací widget a programová správa konverzácií.
Tieto oblasti zdieľajú jeden účet, jednu databázu kontaktov a jeden API kľúč. To je pohodlné a občas nebezpečné: skript napísaný s predstavou testovacích dát komunikuje s tými istými kontaktmi, ktorým odosielate kampane.
Transakčné verzus marketingové
Obe rodiny sa správajú natoľko odlišne, že ich zámena je najčastejšou chybou návrhu.
| Transakčné | Marketingové | |
|---|---|---|
| Hlavný endpoint | POST /v3/smtp/email | POST /v3/emailCampaigns |
| Adresovanie | Explicitní príjemcovia v požiadavke | listIds alebo segmentIds |
| Spúšťač | Vaša aplikácia, v reálnom čase | Naplánované alebo odoslané na požiadanie |
| Typický tvar objemu | Súvislý, po jednej správe | Nárazový, jedno veľké odoslanie |
| Nastavenie limitov | Veľmi vysoké, 1 000 požiadaviek za sekundu na štandardných plánoch | Nízke, endpointy kampaní spadajú pod všeobecný strop |
Ak sa ešte len rozhodujete, či je Brevo vôbec tá správna platforma, prehľad platformy pokrýva túto tému.
Autentifikácia a správa kľúčov
Brevo používa jednoduchý API kľúč vo vlastnej hlavičke. Hlavička sa volá api-key, nie Authorization, a nemá predponu Bearer. Na tomto zakopne takmer každý, kto predtým pracoval s iným API na posielanie správ.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"Kľúče sa vytvárajú v aplikácii Brevo v nastaveniach účtu, v sekcii SMTP and API, na karte API keys. Každému kľúču dajte popisný názov naviazaný na systém, ktorý ho používa. Hodnota kľúča sa zobrazí presne raz pri vytvorení, takže ak ju stratíte, vygenerujete nový kľúč namiesto obnovy starého.
Niekoľko praktických pravidiel:
- Vydajte samostatný kľúč pre každé prostredie a každú službu. Zrušenie kompromitovaného kľúča by nikdy nemalo zhodiť tri nesúvisiace systémy.
- Štandardné API kľúče platia pre celý účet. Ku každému kľúču pristupujte ako k plnému prístupu ku kontaktom, odosielaniu a CRM dátam.
- Brevo podporuje aj OAuth 2.0 pre aplikácie, ktoré konajú v mene iných účtov Brevo. Popísané je to spolu s tokom kľúčov v schémach autentifikácie.
- MCP server, ktorý používajú AI asistenti, má vlastný token a ten skutočne používa bearer hlavičku. Vytvára sa na tej istej obrazovke API keys, ale nie je zameniteľný s REST kľúčom.
Základná URL, verzovanie a Váš prvý zápis
Základná URL je https://api.brevo.com/v3/. Verzia je v ceste, nie v hlavičke, a v3 je aktuálna generácia. Každá cesta v tomto sprievodcovi je relatívna voči tejto základnej adrese.
Prvý zápis povie viac než prvé čítanie, pretože preverí tie časti účtu, ktoré bývajú zle nastavené (predovšetkým overených odosielateľov):
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"] }'Úspešné odoslanie vráti 201 s messageId. Naplánované odoslanie vráti 202.
Endpointy, ktoré budete naozaj používať
Kontakty
POST /v3/contacts vytvorí kontakt. Telo prijíma email, mapu attributes pre vlastné polia, listIds, ext_id pre Váš vlastný externý kľúč a dva príznaky, na ktorých v praxi záleží najviac: updateEnabled, ktorý zmení volanie na upsert, a getId, vďaka ktorému odpoveď vráti id kontaktu.
Čítanie ide cez GET /v3/contacts, ktorý stránkuje pomocou limit (predvolene 50, maximum 1000) a offset a podporuje modifiedSince a createdSince v UTC. Inkrementálne synchronizácie by sa mali opierať o modifiedSince namiesto prechádzania celého zoznamu. Všimnite si, že parameter filter podporuje iba operátor rovnosti, takže čokoľvek výraznejšie patrí do segmentu.
Na hromadné načítanie POST /v3/contacts/import prijíma fileUrl, fileBody alebo jsonBody, cieli na listIds a beží asynchrónne, pričom vracia processId. Brevo dokumentuje maximum 10 MB pre telo požiadavky a odporúča držať sa okolo 8 MB, pretože parsovanie payload nafúkne. Nastavte notifyUrl, aby ste sa o výsledku dozvedeli namiesto opakovaného dopytovania.
Transakčné e-maily
POST /v3/smtp/email je hlavný ťahúň. Okrem sender, to, subject a htmlContent stoja za pozornosť tieto polia:
templateIdsparams, ktoré nahradia vložený obsah šablónou Brevo a jej dosadenými premennými. Parametre jednotlivej verzie majú strop 100 KB, kumulatívne parametre 1000 KB.messageVersions, ktoré pošlú personalizované varianty v jednom volaní, s najviac 99 príjemcami na verziu.tags, ktoré by ste mali nastavovať vždy. Značky sa vracajú vo webhookových udalostiach a sú jediným lacným spôsobom, ako priradiť udalosť doručenia k tej časti kódu, ktorá ju vyvolala.scheduledAtspolu sbatchIdpre budúce odoslania, ktoré možno budete chcieť zrušiť ako skupinu.headers, v tvare Title-Case, pre vlastné SMTP hlavičky.
Jedna požiadavka prijme najviac 2 000 príjemcov. Rozdielu medzi týmto endpointom a odosielaním kampaní sa venuje sprievodca transakčnými e-mailami z pohľadu stratégie správ.
E-mailové kampane
POST /v3/emailCampaigns vyžaduje name a sender plus presne jeden zdroj obsahu: htmlContent (minimálne 10 znakov, do 1 MB), htmlUrl alebo templateId. Publikum sa uvádza v recipients ako listIds alebo segmentIds a scheduledAt používa UTC formát YYYY-MM-DDTHH:mm:ss.SSSZ. Sprievodné trasy pokrývajú okamžité odoslanie, testovacie odoslanie, aktualizáciu stavu a stiahnutie reportu kampane.
Firmy, obchody a objekty
CRM v Brevo má dve prekrývajúce sa cesty zápisu a správna voľba je dôležitá.
CRM trasy sú POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id} a rovnaká sada pre obchody. Tieto sú synchrónne. PATCH vráti 204, keď je zmena aplikovaná.
Objektové API je hromadná cesta: POST /v3/objects/{object_type}/batch/upsert prijme až 1000 záznamov a 1 MB na požiadavku, až 500 atribútov na záznam a až 10 asociačných záznamov na typ objektu a záznam. Vracia 202 s processId, čo znamená prijaté, nie aplikované.
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" } } ] }'Sprievodca Brevo CRM pokrýva objektový model z pohľadu operátora.
Oficiálne SDK
Brevo udržiava klientov pod organizáciou getbrevo na GitHube:
| Jazyk | Repozitár |
|---|---|
| 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 |
Klient pre Node sa inštaluje ako @getbrevo/brevo:
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);Klient pre Python sa inštaluje príkazom pip install brevo-python. Ak nechcete kvôli dvom endpointom ťahať závislosť na SDK, holé HTTP rozhranie je dosť malé na priame volanie, čo Vás zároveň izoluje od zmien verzií SDK:
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 responseExistuje aj MCP server na adrese https://mcp.brevo.com/v1/brevo/mcp pre AI asistentov, autentifikovaný bearer tokenom vygenerovaným na tej istej obrazovke nastavení. Je užitočný na prieskum a otázky o účte, nie pre produkčné dátové cesty.
Webhooky
Webhooky sú spôsob, ako sa dozviete, čo sa po odoslaní stalo. POST /v3/webhooks vytvorí jeden, s url, events, type a voliteľne channel (email alebo sms), batched, vlastnými headers a objektom auth.
Existujú tri typy webhookov s odlišnými slovníkmi udalostí:
- Transakčné:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - Marketingové:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - Prichádzajúce:
inboundEmailProcessedareply, ktoré navyše vyžadujúdomain.
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" }'Tri veci treba urobiť správne. Po prvé, účet môže mať naraz najviac 40 webhookov naprieč všetkými typmi, takže smerujte podľa udalosti vo vnútri svojho handlera namiesto registrácie jedného endpointu na každú udalosť. Po druhé, pri očakávanom objeme použite príznak batched, keďže jedna požiadavka s mnohými udalosťami sa spracúva oveľa lacnejšie než mnoho požiadaviek. Po tretie, chráňte prijímač: Brevo zverejňuje rozsahy svojich odosielacích IP adries a obmedzenie Vášho endpointu na tieto rozsahy je dokumentovaný postup. Ako druhú vrstvu pridajte vlastné zdieľané tajomstvo cez pole headers.
Handlery musia byť idempotentné. Ako deduplikačný kľúč berte id správy plus typ udalosti plus časovú značku.
Limity požiadaviek a spracovanie chýb
Limity požiadaviek v Brevo sú nastavené pre každý endpoint a každú úroveň plánu a rozptyl medzi endpointmi je obrovský.
| Endpoint | Standard | Professional a 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 | vyššie na Enterprise |
GET /v3/smtp/emails | 2 RPS, 7 200 RPH | 3 RPS, 10 800 RPH |
| Všetko ostatné | 100 RPH | 200 RPH |
Posledný riadok je ten, ktorý bolí. Odosielanie je prakticky nemerané, zatiaľ čo správa kampaní, čítanie CRM a väčšina administratívnych volaní zdieľajú rozpočet 100 požiadaviek za hodinu na štandardných plánoch. Naivné doplnenie dát, ktoré pred každým zápisom prečíta záznam firmy, vyčerpá hodinovú kvótu za menej než dve minúty.
Každá odpoveď nesie x-sib-ratelimit-limit, x-sib-ratelimit-remaining a x-sib-ratelimit-reset. Čítajte ich pri úspechu, nielen pri zlyhaní. Prekročenie limitu vráti 429 a správnou reakciou je počkať interval z hlavičky reset a potom uplatniť exponenciálny odklad s náhodným rozptylom.
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;}Opakujte 429 a 5xx. Nikdy neopakujte 400 alebo 409 naslepo, pretože oboje zvyčajne znamená, že požiadavka je nesprávna, nie predčasná, a 409 si obzvlášť vyžaduje iný postup namiesto opakovania.
Testovanie bez odoslania pošty
Do transakčného odoslania pridajte hlavičku X-Sib-Sandbox s hodnotou drop. Brevo požiadavku overí, vráti 201 s messageId, nič nedoručí a nezapíše žiadny e-mailový záznam.
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>" }'Pochopte, čo to dokazuje a čo nie. Režim sandbox overuje iba formát požiadavky. Nehovorí nič o autentifikácii odosielateľa, vykreslení šablóny ani o doručiteľnosti. Pre integračné testovanie čohokoľvek, čo sa dotýka kontaktov alebo CRM dát, si držte samostatný účet Brevo, pretože režim sandbox pokrýva odosielanie a nie zvyšok API.
Limity, ktoré formujú návrh Vašej integrácie
Toto sú obmedzenia, ktoré sa objavia až vtedy, keď integrácia beží voči skutočnému účtu pri objeme. Viaceré si protirečia s tým, čo API o sebe tvrdí. Ani jedno z nich nie je vyjednateľné, takže jedinou rozumnou reakciou je navrhnúť riešenie okolo nich.
Firmy vyžadujú doménu a na doménu pripadá iba jedna firma
GET /v3/crm/attributes/companies hlási každý atribút ako nepovinný a referencia na vytvorenie firmy uvádza ako povinný iba name. V praxi POST /v3/companies bez neprázdneho atribútu domain vráti 400 so správou o chýbajúcich povinných predvolených atribútoch. Prázdny reťazec zlyhá rovnako ako jeho vynechanie.
Horšie je, že jedinečnosť domény sa vynucuje. Druhá firma na doméne, ktorá sa už používa, vráti 409. Pre B2B obchod je to štrukturálne: dcérske spoločnosti zdieľajúce jednu e-mailovú doménu kupujúceho nemôžu v Brevo existovať ako samostatné firmy. Aj samotná synchronizácia kontaktu stačí na to, aby sa firma objavila na e-mailovej doméne toho kontaktu, takže vytvorenie môže kolidovať s firmou, ktorú nikto výslovne nevytvoril. Správny handler pri 409 prevezme existujúcu firmu namiesto zlyhania alebo opakovania.
Nedeklarované atribúty sa ticho zahadzujú
Toto je najnebezpečnejšie správanie platformy a Brevo ho dokumentuje otvorene: ak sa atribút objaví v požiadavke, ale nebol predtým definovaný v schéme objektu, nestane sa nič. Žiadna chyba, žiadne vytvorenie atribútu, žiadne varovanie.
Odpoveď 2xx teda nie je dôkazom, že Vaše dáta dorazili. Pred zápisom si prečítajte schému, vo vlastnom klientovi zahoďte čokoľvek nedeklarované a radšej odmietnite spustiť synchronizáciu, ktorej atribúty neexistujú, než aby ste mesiac zapisovali polovičný záznam, kým si to niekto všimne.
Filtre podľa atribútov sa prijmú a ignorujú
GET /v3/companies?filters[attributes.domain]=... vráti 200 a filter ignoruje. Dva úplne odlišné filtre vrátia rovnaké záznamy. Cez túto trasu neexistuje funkčný spôsob, ako vyhľadať firmu podľa atribútu.
V kombinácii s tým, že nefiltrovaný zoznam na veľkých účtoch vyprší s 504 pri akejkoľvek veľkosti stránky, môže byť existujúca firma cez dokumentovanú cestu skutočne nenájditeľná. Obchádzkou je prehľadávať GET /v3/objects/company/records so sort=desc, čo je rýchle, stránkované a vracia atribúty, ohraničené na rozumný počet stránok. Firma, ktorá práve vyvolala 409, bola takmer vždy vytvorená pred chvíľou, takže prehľadávanie od najnovších ju nájde rýchlo.
Milión záznamov na typ objektu a žiadne hromadné mazanie
POST /v3/objects/{type}/batch/upsert vráti 400, hneď ako typ objektu obsahuje milión záznamov. Blokuje aktualizácie rovnako ako vytváranie: adresovanie existujúceho záznamu jeho vlastným číselným id zlyhá identicky. Celá cesta zápisu objektov sa uzavrie naraz.
Dostať sa späť pod strop je pomalé, pretože POST /v3/objects/{type}/batch/delete vracia 403 pre štandardné typy objektov Brevo, ako je company. Jedinou trasou je DELETE /v3/companies/{id}, jeden záznam na volanie pri približne 156 ms. Vyčistenie 124 000 záznamov týmto spôsobom trvalo hodiny s 20 paralelnými pracovníkmi. Sledujte počet záznamov pravidelne namiesto toho, aby ste strop objavili cez zlyhanú synchronizáciu, a aktualizácie s vysokým objemom smerujte cez PATCH /v3/companies/{id}, ktorý takýto limit nemá.
ext_id je id Brevo, nie Vaše
Pri objektových záznamoch identifiers.ext_id obsahuje vlastné CRM id firmy v Brevo, reťazec v štýle Mongo. Nie je to voľný externý kľúč. Upsert kľúčovaný na ext_id nastavené na identifikátor Vašej platformy vytvorí duplikáty namiesto párovania. Vaše externé id patrí do vlastného deklarovaného atribútu.
Upserty objektov sú asynchrónne, CRM zápisy nie
batch/upsert vráti 202 a processId, potom sa aplikuje neskôr. Neexistujúce id zlyhá asynchrónne a Vášmu volajúcemu aj tak vráti 202. PATCH /v3/companies/{id} vráti 204 a aplikuje sa synchrónne. Ak Vaša synchronizácia hlási úspech, bez následného čítania si to slovo zaslúži iba synchrónna cesta.
Krátky kontrolný zoznam pre integráciu
- Samostatné API kľúče pre každú službu a každé prostredie, rotované pri personálnych zmenách.
- Všetky zápisy idú cez jedného klienta, ktorý číta hlavičky limitov a pri 429 sa odkladá.
- Schéma atribútov sa overuje pri štarte a synchronizácia odmietne bežať, ak jej atribúty chýbajú.
- 409 pri vytvorení firmy znamená prevziať, nie opakovať.
- Hromadné cesty používajú objektové API pre priepustnosť a CRM trasy pre čokoľvek, čo musí byť potvrdené.
- Webhooky sú idempotentné, dávkované, obmedzené na IP a nesú hlavičku so zdieľaným tajomstvom.
- Inkrementálne synchronizácie kontaktov používajú
modifiedSince, nie prechádzanie celého zoznamu.
Postaviť a udržiavať túto vrstvu je skutočná inžinierska práca: overovanie schémy, odklady, logika prevzatia, rekonciliácia. Tajo existuje na to, aby ju absorbovalo a udržalo dáta zo Shopify a obchodu synchronizované s kontaktmi, firmami a udalosťami v Brevo bez toho, aby niekto ručne písal logiku opakovaní a deduplikácie. Ak si to zapájate sami, sprievodca integráciou Brevo prechádza rozhodnutiami o dátovom modeli, ktoré prichádzajú pred kódom.
Kľúčové poznatky
- API je jedno REST rozhranie na
https://api.brevo.com/v3/, autentifikované hlavičkouapi-key, nie bearer tokenom. - Limity požiadaviek sú extrémne nerovnomerné: odosielanie je prakticky nemerané, zatiaľ čo väčšina ostatných endpointov zdieľa 100 požiadaviek za hodinu na štandardných plánoch.
- Oficiálne SDK existujú pre sedem jazykov, ale HTTP rozhranie je dosť jednoduché na priame volanie, keď potrebujete len pár endpointov.
- Režim sandbox overuje iba formát požiadavky, takže si na testovanie čohokoľvek nad rámec odosielania držte samostatný účet.
- Odpoveď 2xx nedokazuje, že sa zápis aplikoval. Nedeklarované atribúty sa ticho zahadzujú a upserty objektov sú asynchrónne.
- Navrhujte s ohľadom na pevné limity: jedna firma na doménu, milión záznamov na typ objektu, žiadne hromadné mazanie pre štandardné objekty a filtre atribútov, ktoré potichu nerobia nič.