Brevo API: praktični vodnik za razvijalce
Vodnik po Brevo API za razvijalce: avtentikacija, osnovni URL, stiki, transakcijska e-pošta, kampanje, objekti CRM, webhooki, omejitve zahtev in resnične meje.
Brevo ponuja en sam REST API, ki zajema transakcijsko sporočanje, marketinške kampanje, podatke o stikih in zapise CRM. Da prva zahteva vrne 201, traja približno dve minuti. Da dobite produkcijsko integracijo, ki podatkov ne izgublja po tiho, traja precej dlje, saj so nekatere najpomembnejše omejitve bodisi nedokumentirane bodisi v nasprotju s tem, kar API poroča o samem sebi.
Ta vodnik pokriva obe polovici: končne točke, SDK in avtentikacijo, ki jih potrebujete prvi dan, ter omejitve platforme, ki jih morate upoštevati pri načrtovanju, preden greste v produkcijo.
Kaj pokriva Brevo API
Vse živi pod enim gostiteljem in eno potjo z različico. Razvijalska dokumentacija površino razdeli na štiri produktna področja:
- Sporočanje: transakcijska e-pošta, SMS in WhatsApp, vključno s paketnimi pošiljanji, načrtovanjem in aktivnostjo sporočil.
- Marketinška platforma: stiki, seznami, segmenti in e-poštne kampanje.
- E-trgovina: izdelki, naročila in sledenje dogodkom strank.
- Pogovori: klepetalni pripomoček in programsko upravljanje pogovorov.
Ta področja si delijo en račun, eno zbirko stikov in en ključ API. To je priročno in občasno nevarno: skripta, napisana za neko testno predstavo o podatkih, se pogovarja z istimi stiki, ki jim pošiljate kampanje.
Transakcijsko proti marketinškemu
Družini se vedeta dovolj različno, da je njuno mešanje najpogostejša napaka v zasnovi.
| Transakcijsko | Marketinško | |
|---|---|---|
| Glavna končna točka | POST /v3/smtp/email | POST /v3/emailCampaigns |
| Naslavljanje | Izrecni prejemniki v zahtevi | listIds ali segmentIds |
| Sprožilec | Vaša aplikacija, v realnem času | Načrtovano ali poslano na zahtevo |
| Značilna oblika obsega | Zvezno, po eno sporočilo naenkrat | Sunkovito, eno veliko pošiljanje |
| Drža glede omejitev | Zelo visoka, 1.000 zahtev na sekundo na standardnih paketih | Nizka, končne točke kampanj spadajo pod splošno omejitev |
Če se šele odločate, ali je Brevo sploh prava platforma, ta teren pokriva pregled platforme.
Avtentikacija in upravljanje ključev
Brevo uporablja navaden ključ API v glavi po meri. Glava se imenuje api-key, ne Authorization, in nima predpone Bearer. To zmede skoraj vsakogar, ki je pred tem uporabljal kakšen drug API za sporočanje.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"Ključe ustvarite v aplikaciji Brevo v nastavitvah računa, v razdelku SMTP and API, na zavihku API keys. Vsakemu ključu dajte opisno ime, vezano na sistem, ki ga uporablja. Vrednost ključa je prikazana natanko enkrat ob ustvarjanju, zato ob izgubi ustvarite novega, starega pa ne morete obnoviti.
Nekaj praktičnih pravil:
- Izdajte ločen ključ za vsako ciljno okolje in vsako storitev. Preklic razkritega ključa ne sme nikoli podreti treh nepovezanih sistemov.
- Standardni ključi API veljajo za celoten račun. Vsak ključ obravnavajte kot poln dostop do stikov, pošiljanja in podatkov CRM.
- Brevo podpira tudi OAuth 2.0 za aplikacije, ki delujejo v imenu drugih računov Brevo, kar je skupaj s potekom za ključe opisano v shemah avtentikacije.
- Strežnik MCP, ki ga uporabljajo pomočniki AI, uporablja ločen žeton in res uporablja glavo bearer. Ta žeton nastane na istem zaslonu z API keys, vendar ni zamenljiv s ključem REST.
Osnovni URL, različice in vaš prvi zapis
Osnovni URL je https://api.brevo.com/v3/. Različica je v poti in ne v glavi, v3 pa je trenutna generacija. Vsaka pot v tem vodniku je relativna glede na to osnovo.
Prvi zapis pove več kot prvo branje, saj preveri tiste dele računa, ki so običajno napačno nastavljeni (predvsem potrjene pošiljatelje):
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"] }'Uspešno pošiljanje vrne 201 z vrednostjo messageId. Načrtovano pošiljanje vrne 202.
Končne točke, ki jih boste dejansko uporabljali
Stiki
POST /v3/contacts ustvari stik. Telo sprejme email, preslikavo attributes za polja po meri, listIds, ext_id za vaš lastni zunanji ključ in dve zastavici, ki v praksi štejeta največ: updateEnabled, ki klic spremeni v upsert, in getId, ki poskrbi, da odgovor vrne id stika.
Branja gredo prek GET /v3/contacts, ki straniči s parametroma limit (privzeto 50, največ 1000) in offset ter podpira modifiedSince in createdSince v UTC. Inkrementalne sinhronizacije naj se opirajo na modifiedSince in ne na sprehod čez celoten seznam. Upoštevajte, da parameter filter podpira samo operator enakosti, zato karkoli izraznejšega sodi v segment.
Za množično nalaganje POST /v3/contacts/import sprejme fileUrl, fileBody ali jsonBody, cilja na listIds in teče asinhrono ter vrne processId. Brevo dokumentira največ 10 MB telesa in priporoča, da ostanete blizu 8 MB, ker razčlenjevanje poveča vsebino. Nastavite notifyUrl, da izid izveste, namesto da poizvedujete.
Transakcijska e-pošta
POST /v3/smtp/email je delovni konj. Poleg sender, to, subject in htmlContent so vredna poznavanja tudi ta polja:
templateIdskupaj sparams, ki vgrajeno vsebino zamenja s predlogo Brevo in njenimi zamenjavami spremenljivk. Parametri posamezne različice so omejeni na 100 KB, skupni parametri na 1000 KB.messageVersions, ki v enem klicu pošlje prilagojene različice, z največ 99 prejemniki na različico.tags, ki jih vedno nastavite. Oznake se vrnejo v dogodkih webhooka in so edini poceni način, da dogodek dostave povežete s kodo, ki ga je povzročila.scheduledAtskupaj zbatchIdza prihodnja pošiljanja, ki jih boste morda želeli preklicati kot skupino.headers, zapisano v obliki Title-Case, za glave SMTP po meri.
Ena zahteva sprejme največ 2.000 prejemnikov. Za razliko med to končno točko in pošiljanjem kampanj ima vodnik po transakcijski e-pošti pogled s strani strategije sporočanja.
E-poštne kampanje
POST /v3/emailCampaigns zahteva name in sender ter natanko en vir vsebine: htmlContent (najmanj 10 znakov, pod 1 MB), htmlUrl ali templateId. Občinstvo gre v recipients kot listIds ali segmentIds, scheduledAt pa uporablja obliko UTC YYYY-MM-DDTHH:mm:ss.SSSZ. Spremljajoče poti pokrivajo takojšnje pošiljanje, pošiljanje preizkusa, posodabljanje stanja in pridobivanje poročila o kampanji.
Podjetja, posli in objekti
CRM v Brevu ima dve prekrivajoči se poti za zapisovanje in pravilna izbira šteje.
Poti CRM so POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id} in enakovreden nabor za posle. Te so sinhrone. PATCH vrne 204, ko je sprememba uveljavljena.
API za objekte je pot za množične zapise: POST /v3/objects/{object_type}/batch/upsert sprejme do 1000 zapisov in 1 MB na zahtevo, do 500 atributov na zapis in do 10 povezanih zapisov na tip objekta na zapis. Vrne 202 z vrednostjo processId, kar pomeni sprejeto in ne uveljavljeno.
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" } } ] }'Vodnik po Brevo CRM pokriva objektni model z operativne strani.
Uradni SDK
Brevo vzdržuje odjemalce v organizaciji getbrevo na GitHubu:
| Jezik | Repozitorij |
|---|---|
| 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 |
Odjemalec za Node se namesti kot @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);Odjemalec za Python se namesti z pip install brevo-python. Če za dve končni točki raje ne bi nosili odvisnosti od SDK, je surova površina HTTP dovolj majhna, da jo pokličete neposredno, kar vas hkrati zavaruje pred menjavami različic 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 responseNa voljo je tudi strežnik MCP na naslovu https://mcp.brevo.com/v1/brevo/mcp za pomočnike AI, ki se avtenticira z žetonom bearer, ustvarjenim na istem zaslonu z nastavitvami. Uporaben je za raziskovanje in vprašanja o računu, ne za produkcijske podatkovne poti.
Webhooki
Webhooki so način, kako izveste, kaj se je zgodilo po pošiljanju. POST /v3/webhooks ustvari webhook s parametri url, events, type in po želji channel (email ali sms), batched, glavami po meri v headers in objektom auth.
Obstajajo tri vrste webhookov z različnimi besedišči dogodkov:
- Transakcijski:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - Marketinški:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - Vhodni:
inboundEmailProcessedinreply, ki dodatno zahtevatadomain.
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 stvari morate narediti pravilno. Prvič, en račun lahko hrani največ 40 webhookov čez vse vrste, zato usmerjajte po dogodkih znotraj svojega upravljalnika, namesto da za vsak dogodek registrirate svojo končno točko. Drugič, ob večjih količinah uporabite zastavico batched, saj je ena zahteva z veliko dogodki mnogo cenejša za obdelavo kot veliko zahtev. Tretjič, zaščitite prejemnik: Brevo objavlja svoje razpone pošiljajočih naslovov IP, omejitev vaše končne točke na te razpone pa je dokumentiran pristop. Kot drugo plast dodajte še lastno deljeno skrivnost prek polja headers.
Upravljalniki morajo biti idempotentni. Kot ključ za odstranjevanje podvojitev uporabite id sporočila skupaj z vrsto dogodka in časovnim žigom.
Omejitve zahtev in obravnava napak
Omejitve zahtev v Brevu veljajo za posamezno končno točko in raven paketa, razpon med končnimi točkami pa je ogromen.
| Končna točka | Standard | Professional in 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 | več na Enterprise |
GET /v3/smtp/emails | 2 RPS, 7.200 RPH | 3 RPS, 10.800 RPH |
| Vse ostalo | 100 RPH | 200 RPH |
Zadnja vrstica je tista, ki boli. Pošiljanje je praktično neomejeno, medtem ko si upravljanje kampanj, branja CRM in večina skrbniških klicev na standardnih paketih delijo proračun 100 zahtev na uro. Naivno polnjenje podatkov, ki pred vsakim zapisom prebere zapis podjetja, bo izčrpalo urno kvoto v manj kot dveh minutah.
Vsak odgovor nosi glave x-sib-ratelimit-limit, x-sib-ratelimit-remaining in x-sib-ratelimit-reset. Berite jih ob uspehu, ne samo ob napaki. Preseganje omejitve vrne 429, pravilen odziv pa je počakati interval iz glave za ponastavitev in nato uporabiti eksponentno podaljševanje zamika z naključnim odstopanjem.
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;}Ponavljajte pri 429 in 5xx. Nikoli ne ponavljajte 400 ali 409 na slepo, saj oba običajno pomenita, da je zahteva napačna in ne prezgodnja, 409 pa še posebej zahteva drugačno dejanje in ne ponovitve.
Preizkušanje brez pošiljanja pošte
Transakcijskemu pošiljanju dodajte glavo X-Sib-Sandbox z vrednostjo drop. Brevo preveri zahtevo, vrne 201 z vrednostjo messageId, ne dostavi ničesar in ne zapiše nobenega dnevnika e-pošte.
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>" }'Razumite, kaj to dokaže in česa ne. Peskovnik preveri samo obliko zahteve. O avtentikaciji pošiljatelja, izrisu predloge ali dostavljivosti ne pove nič. Za integracijsko preizkušanje česarkoli, kar se dotika stikov ali podatkov CRM, imejte ločen račun Brevo, saj peskovnik pokriva pošiljanje in ne preostanka vmesnika API.
Omejitve, ki oblikujejo zasnovo vaše integracije
To so omejitve, ki se pokažejo šele, ko integracija teče proti resničnemu računu pri večjih količinah. Več jih je v nasprotju s tem, kar API pove o sebi. Nobena ni pogajalska, zato je edini smiseln odziv, da jih upoštevate pri načrtovanju.
Podjetja zahtevajo domeno, in samo eno podjetje na domeno
GET /v3/crm/attributes/companies poroča, da noben atribut ni obvezen, referenca za ustvarjanje podjetja pa kot obvezno navaja samo name. V praksi POST /v3/companies brez nepraznega atributa domain vrne 400 s sporočilom o manjkajočih obveznih privzetih atributih. Prazen niz pade enako kot izpuščen atribut.
Še huje, edinstvenost domene se uveljavlja. Drugo podjetje na že uporabljeni domeni vrne 409. Za trgovino B2B je to strukturno: hčerinske družbe, ki si delijo eno domeno kupčeve e-pošte, ne morejo vse obstajati kot ločena podjetja v Brevu. Že sinhronizacija stika zadošča, da se na domeni e-pošte tega stika pojavi podjetje, zato lahko ustvarjanje trči ob podjetje, ki ga ni nihče izrecno ustvaril. Pravi upravljalnik ob 409 prevzame obstoječe podjetje, namesto da odpove ali ponovi klic.
Neprijavljeni atributi se tiho zavržejo
To je najbolj nevarno vedenje na platformi in Brevo ga dokumentira povsem odkrito: če se atribut pojavi v zahtevi, prej pa ni bil določen v shemi objekta, se ne zgodi nič. Brez napake, brez ustvarjanja atributa, brez opozorila.
Odgovor 2xx torej ni dokaz, da so vaši podatki pristali. Pred zapisovanjem preberite shemo, karkoli neprijavljenega opustite že v svojem odjemalcu in raje zavrnite zagon sinhronizacije, katere atributi ne obstajajo, kot da mesec dni zapisujete pol zapisa, preden kdo to opazi.
Filtri po atributih so sprejeti in prezrti
GET /v3/companies?filters[attributes.domain]=... vrne 200 in filter prezre. Dva popolnoma različna filtra vrneta iste zapise. Prek te poti ni delujočega načina, da bi podjetje poiskali po atributu.
V kombinaciji z dejstvom, da nefiltriran seznam pri velikih računih pri kateri koli velikosti strani odpove s 504, obstoječega podjetja po dokumentirani poti resnično ni mogoče najti. Rešitev je pregledovanje GET /v3/objects/company/records s sort=desc, ki je hitro, stranično in vrača atribute, omejeno na smiselno število strani. Podjetje, ki je pravkar sprožilo 409, je bilo skoraj vedno ustvarjeno pred trenutki, zato ga pregled od najnovejšega naprej hitro najde.
Milijon zapisov na tip objekta in brez množičnega brisanja
POST /v3/objects/{type}/batch/upsert vrne 400, ko tip objekta doseže milijon zapisov. Blokira tako posodobitve kot ustvarjanja: naslavljanje obstoječega zapisa po njegovem lastnem številskem id enako odpove. Celotna pot za zapisovanje objektov se zapre naenkrat.
Vrnitev pod zgornjo mejo je počasna, ker POST /v3/objects/{type}/batch/delete za standardne tipe objektov Brevo, kot je company, vrne 403. Edina pot je DELETE /v3/companies/{id}, en zapis na klic pri približno 156 ms. Čiščenje 124.000 zapisov na ta način je z 20 vzporednimi delavci trajalo ure. Število zapisov spremljajte po urniku, namesto da zgornjo mejo odkrijete prek neuspele sinhronizacije, posodobitve pri velikih količinah pa usmerite prek PATCH /v3/companies/{id}, ki te omejitve nima.
ext_id je id od Brevo, ne vaš
Pri zapisih objektov identifiers.ext_id hrani lasten id podjetja v CRM od Brevo, niz v slogu Mongo. To ni prost zunanji ključ. Če upsert vežete na ext_id, nastavljen na identifikator vaše platforme, boste namesto ujemanja ustvarjali podvojitve. Vaš zunanji id sodi v lasten prijavljen atribut.
Upserti objektov so asinhroni, zapisi CRM niso
batch/upsert vrne 202 in processId, nato pa uveljavi pozneje. Neobstoječ id odpove asinhrono in klicatelju vseeno vrne 202. PATCH /v3/companies/{id} vrne 204 in je uveljavljen sinhrono. Če vaša sinhronizacija poroča o uspehu, si to besedo brez naknadnega branja zasluži samo sinhrona pot.
Kratek kontrolni seznam za integracijo
- Ločeni ključi API za vsako storitev in vsako okolje, zamenjani ob kadrovskih spremembah.
- Vsi zapisi gredo prek enega odjemalca, ki bere glave z omejitvami zahtev in ob 429 zmanjša tempo.
- Shema atributov se preveri ob zagonu, sinhronizacija pa se noče izvesti, če njeni atributi manjkajo.
- 409 pri ustvarjanju podjetja pomeni prevzemi, ne ponovi.
- Množične poti uporabljajo API za objekte za pretočnost, poti CRM pa za vse, kar mora biti potrjeno.
- Webhooki so idempotentni, paketni, omejeni po IP in nosijo glavo z deljeno skrivnostjo.
- Inkrementalne sinhronizacije stikov uporabljajo
modifiedSincein ne sprehodov čez celoten seznam.
Gradnja in vzdrževanje te plasti je pravo inženirsko delo: preverjanje sheme, upočasnjevanje, logika prevzemanja, usklajevanje. Tajo obstaja prav zato, da to prevzame nase in ohranja podatke iz Shopify in trgovine usklajene s stiki, podjetji in dogodki v Brevu, ne da bi kdo ročno pisal logiko za ponovne poskuse in odstranjevanje podvojitev. Če vse povezujete sami, vas vodnik po integraciji Brevo popelje skozi odločitve o podatkovnem modelu, ki pridejo pred kodo.
Ključne ugotovitve
- API je ena sama površina REST na naslovu
https://api.brevo.com/v3/, avtenticirana z glavoapi-keyin ne z žetonom bearer. - Omejitve zahtev so izjemno neenakomerne: pošiljanje je praktično neomejeno, medtem ko si večina drugih končnih točk na standardnih paketih deli 100 zahtev na uro.
- Uradni SDK obstajajo za sedem jezikov, a je površina HTTP dovolj preprosta za neposredne klice, kadar potrebujete le nekaj končnih točk.
- Peskovnik preveri samo obliko zahteve, zato imejte za preizkušanje česarkoli onkraj pošiljanja ločen račun.
- Odgovor 2xx ne dokazuje, da je bil zapis uveljavljen. Neprijavljeni atributi se tiho zavržejo, upserti objektov pa so asinhroni.
- Načrtujte okoli fiksnih omejitev: eno podjetje na domeno, milijon zapisov na tip objekta, brez množičnega brisanja za standardne objekte in filtri po atributih, ki po tiho ne naredijo ničesar.