Brevo API: πρακτικός οδηγός για προγραμματιστές
Οδηγός Brevo API για προγραμματιστές: ταυτοποίηση, base URL, επαφές, transactional email, καμπάνιες, αντικείμενα CRM, webhooks, όρια ρυθμού και πραγματικοί περιορισμοί.
Το Brevo εκθέτει ένα REST API που καλύπτει transactional μηνύματα, καμπάνιες μάρκετινγκ, δεδομένα επαφών και εγγραφές CRM. Για να επιστρέψει το πρώτο αίτημα 201 χρειάζονται περίπου δύο λεπτά. Για μια ενσωμάτωση παραγωγής που δεν χάνει σιωπηλά δεδομένα χρειάζεται σημαντικά περισσότερος χρόνος, επειδή αρκετοί από τους περιορισμούς που μετρούν περισσότερο είτε δεν τεκμηριώνονται είτε αντιφάσκουν με όσα δηλώνει το ίδιο το API για τον εαυτό του.
Αυτός ο οδηγός καλύπτει και τα δύο σκέλη: τα endpoints, τα SDK και την ταυτοποίηση που χρειάζεστε από την πρώτη μέρα, καθώς και τα όρια της πλατφόρμας γύρω από τα οποία πρέπει να σχεδιάσετε πριν βγείτε σε παραγωγή.
Τι καλύπτει το Brevo API
Τα πάντα βρίσκονται κάτω από έναν ενιαίο host και μία ενιαία διαδρομή έκδοσης. Η τεκμηρίωση για προγραμματιστές ομαδοποιεί την επιφάνεια σε τέσσερις περιοχές προϊόντος:
- Messaging: transactional email, SMS και WhatsApp, συμπεριλαμβανομένων μαζικών αποστολών, χρονοπρογραμματισμού και δραστηριότητας μηνυμάτων.
- Marketing platform: επαφές, λίστες, τμήματα και καμπάνιες email.
- eCommerce: προϊόντα, παραγγελίες και παρακολούθηση συμβάντων πελατών.
- Conversations: το widget συνομιλίας και η προγραμματιστική διαχείριση συνομιλιών.
Αυτές οι περιοχές μοιράζονται έναν λογαριασμό, μία βάση δεδομένων επαφών και ένα κλειδί API. Αυτό είναι βολικό και περιστασιακά επικίνδυνο: ένα script γραμμένο με βάση μια ιδέα δεδομένων staging μιλά στις ίδιες επαφές στις οποίες στέλνουν οι καμπάνιες σας.
Transactional έναντι marketing
Οι δύο οικογένειες συμπεριφέρονται αρκετά διαφορετικά ώστε η σύγχυσή τους να είναι το πιο συνηθισμένο σφάλμα σχεδιασμού.
| Transactional | Marketing | |
|---|---|---|
| Κύριο endpoint | POST /v3/smtp/email | POST /v3/emailCampaigns |
| Διευθυνσιοδότηση | Ρητοί παραλήπτες μέσα στο αίτημα | listIds ή segmentIds |
| Έναυσμα | Η εφαρμογή σας, σε πραγματικό χρόνο | Χρονοπρογραμματισμένο ή κατ’ απαίτηση |
| Τυπικό σχήμα όγκου | Συνεχές, ένα μήνυμα κάθε φορά | Απότομο, μία μεγάλη αποστολή |
| Στάση ορίων ρυθμού | Πολύ υψηλή, 1.000 αιτήματα ανά δευτερόλεπτο στα τυπικά πακέτα | Χαμηλή, τα endpoints καμπανιών εμπίπτουν στο γενικό όριο |
Αν ακόμη αποφασίζετε αν το Brevo είναι καν η σωστή πλατφόρμα, η επισκόπηση της πλατφόρμας καλύπτει αυτό το έδαφος.
Ταυτοποίηση και διαχείριση κλειδιών
Το Brevo χρησιμοποιεί ένα απλό κλειδί API σε προσαρμοσμένη κεφαλίδα. Η κεφαλίδα ονομάζεται api-key, όχι Authorization, και δεν υπάρχει πρόθεμα Bearer. Αυτό μπερδεύει σχεδόν όλους όσους έχουν χρησιμοποιήσει πρώτα κάποιο άλλο API μηνυμάτων.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"Τα κλειδιά δημιουργούνται στην εφαρμογή Brevo, στις ρυθμίσεις λογαριασμού, στην ενότητα SMTP and API, στην καρτέλα API keys. Δώστε σε κάθε κλειδί ένα περιγραφικό όνομα συνδεδεμένο με το σύστημα που το χρησιμοποιεί. Η τιμή του κλειδιού εμφανίζεται ακριβώς μία φορά κατά τη δημιουργία του, οπότε αν τη χάσετε δημιουργείτε νέο κλειδί αντί να ανακτήσετε το παλιό.
Μερικοί πρακτικοί κανόνες:
- Εκδώστε ξεχωριστό κλειδί ανά περιβάλλον ανάπτυξης και ανά υπηρεσία. Η ανάκληση ενός παραβιασμένου κλειδιού δεν πρέπει ποτέ να ρίχνει τρία άσχετα συστήματα.
- Τα τυπικά κλειδιά API ισχύουν για ολόκληρο τον λογαριασμό. Θεωρήστε κάθε κλειδί πλήρη πρόσβαση σε επαφές, αποστολές και δεδομένα CRM.
- Το Brevo υποστηρίζει επίσης OAuth 2.0 για εφαρμογές που ενεργούν εκ μέρους άλλων λογαριασμών Brevo, όπως περιγράφεται παράλληλα με τη ροή κλειδιών στα σχήματα ταυτοποίησης.
- Ο διακομιστής MCP που χρησιμοποιείται από βοηθούς AI δέχεται ξεχωριστό token και όντως χρησιμοποιεί κεφαλίδα bearer. Αυτό το token δημιουργείται στην ίδια οθόνη API keys αλλά δεν είναι εναλλάξιμο με ένα κλειδί REST.
Base URL, εκδόσεις και η πρώτη σας εγγραφή
Το base URL είναι το https://api.brevo.com/v3/. Η έκδοση βρίσκεται στη διαδρομή και όχι σε κεφαλίδα, και η v3 είναι η τρέχουσα γενιά. Κάθε διαδρομή σε αυτόν τον οδηγό είναι σχετική ως προς αυτή τη βάση.
Μια πρώτη εγγραφή είναι πιο κατατοπιστική από μια πρώτη ανάγνωση, επειδή δοκιμάζει τα σημεία του λογαριασμού που συνήθως είναι λάθος ρυθμισμένα (ιδίως τους επαληθευμένους αποστολείς):
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"] }'Μια επιτυχημένη αποστολή επιστρέφει 201 με ένα messageId. Μια χρονοπρογραμματισμένη αποστολή επιστρέφει 202.
Τα endpoints που θα χρησιμοποιήσετε στην πράξη
Επαφές
Το POST /v3/contacts δημιουργεί μια επαφή. Το σώμα δέχεται email, έναν χάρτη attributes για προσαρμοσμένα πεδία, listIds, ext_id για το δικό σας εξωτερικό κλειδί, και τις δύο σημαίες που μετρούν περισσότερο στην πράξη: το updateEnabled, που μετατρέπει την κλήση σε upsert, και το getId, που κάνει την απόκριση να επιστρέφει το id της επαφής.
Οι αναγνώσεις γίνονται μέσω GET /v3/contacts, που σελιδοποιεί με limit (προεπιλογή 50, μέγιστο 1000) και offset, και υποστηρίζει modifiedSince και createdSince σε UTC. Οι σταδιακοί συγχρονισμοί πρέπει να στηρίζονται στο modifiedSince αντί να διατρέχουν ολόκληρη τη λίστα. Σημειώστε ότι η παράμετρος filter υποστηρίζει μόνο τελεστή ισότητας, οπότε οτιδήποτε πιο εκφραστικό ανήκει σε ένα τμήμα.
Για μαζική φόρτωση, το POST /v3/contacts/import δέχεται fileUrl, fileBody ή jsonBody, στοχεύει listIds και εκτελείται ασύγχρονα, επιστρέφοντας ένα processId. Το Brevo τεκμηριώνει μέγιστο σώμα 10 MB και συνιστά να μένετε κοντά στα 8 MB, επειδή η ανάλυση διογκώνει το ωφέλιμο φορτίο. Δώστε notifyUrl ώστε να μαθαίνετε το αποτέλεσμα αντί να κάνετε polling.
Transactional email
Το POST /v3/smtp/email είναι το άλογο εργασίας. Πέρα από τα sender, to, subject και htmlContent, τα πεδία που αξίζει να γνωρίζετε είναι:
templateIdμεparams, που αντικαθιστά το ενσωματωμένο περιεχόμενο με ένα πρότυπο Brevo και τις αντικαταστάσεις μεταβλητών του. Οι παράμετροι ανά έκδοση περιορίζονται στα 100 KB και αθροιστικά στα 1000 KB.messageVersions, που στέλνει εξατομικευμένες παραλλαγές σε μία κλήση, με έως 99 παραλήπτες ανά έκδοση.tags, που πρέπει πάντα να ορίζετε. Οι ετικέτες επιστρέφουν στα συμβάντα webhook και είναι ο μοναδικός φθηνός τρόπος να συσχετίσετε ένα συμβάν παράδοσης με τη διαδρομή κώδικα που το παρήγαγε.scheduledAtμαζί μεbatchId, για μελλοντικές αποστολές που ίσως θελήσετε να ακυρώσετε ως ομάδα.headers, σε Title-Case, για προσαρμοσμένες κεφαλίδες SMTP.
Ένα μεμονωμένο αίτημα δέχεται το πολύ 2.000 παραλήπτες. Για τη διαφορά ανάμεσα σε αυτό το endpoint και την αποστολή καμπανιών, ο οδηγός για το transactional email δίνει την οπτική της στρατηγικής μηνυμάτων.
Καμπάνιες email
Το POST /v3/emailCampaigns απαιτεί name και sender, καθώς και ακριβώς μία πηγή περιεχομένου: htmlContent (τουλάχιστον 10 χαρακτήρες, κάτω από 1 MB), htmlUrl ή templateId. Το κοινό μπαίνει στο recipients ως listIds ή segmentIds, και το scheduledAt χρησιμοποιεί τη μορφή UTC YYYY-MM-DDTHH:mm:ss.SSSZ. Συνοδευτικές διαδρομές καλύπτουν την άμεση αποστολή, την αποστολή δοκιμής, την ενημέρωση κατάστασης και την άντληση της αναφοράς καμπάνιας.
Εταιρείες, συμφωνίες και αντικείμενα
Το CRM του Brevo έχει δύο επικαλυπτόμενες διαδρομές εγγραφής, και η σωστή επιλογή έχει σημασία.
Οι διαδρομές CRM είναι POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id} και το αντίστοιχο σύνολο για τις συμφωνίες. Αυτές είναι σύγχρονες. Ένα PATCH επιστρέφει 204 μόλις εφαρμοστεί η αλλαγή.
Το objects API είναι η μαζική διαδρομή: το POST /v3/objects/{object_type}/batch/upsert δέχεται έως 1000 εγγραφές και 1 MB ανά αίτημα, έως 500 χαρακτηριστικά ανά εγγραφή και έως 10 εγγραφές συσχέτισης ανά τύπο αντικειμένου ανά εγγραφή. Επιστρέφει 202 με ένα processId, που σημαίνει αποδεκτό και όχι εφαρμοσμένο.
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 καλύπτει το μοντέλο αντικειμένων από την πλευρά του χειριστή.
Επίσημα SDK
Το Brevo συντηρεί clients στον οργανισμό getbrevo του GitHub:
| Γλώσσα | Αποθετήριο |
|---|---|
| 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 |
Ο client Node εγκαθίσταται ως @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);Ο client Python εγκαθίσταται με pip install brevo-python. Αν προτιμάτε να μην κουβαλάτε εξάρτηση SDK για δύο endpoints, η καθαρή επιφάνεια HTTP είναι αρκετά μικρή ώστε να την καλέσετε απευθείας, κάτι που σας προστατεύει και από τις συνεχείς αλλαγές εκδόσεων του 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 responseΥπάρχει επίσης ένας διακομιστής MCP στο https://mcp.brevo.com/v1/brevo/mcp για βοηθούς AI, με ταυτοποίηση μέσω bearer token που δημιουργείται στην ίδια οθόνη ρυθμίσεων. Είναι χρήσιμος για εξερεύνηση και ερωτήσεις λογαριασμού, όχι για διαδρομές δεδομένων παραγωγής.
Webhooks
Τα webhooks είναι ο τρόπος με τον οποίο μαθαίνετε τι συνέβη μετά από μια αποστολή. Το POST /v3/webhooks δημιουργεί ένα, με url, events, type και προαιρετικά channel (email ή sms), batched, προσαρμοσμένες headers και ένα αντικείμενο auth.
Υπάρχουν τρεις τύποι webhook με ξεχωριστά λεξιλόγια συμβάντων:
- Transactional:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - Marketing:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - Inbound:
inboundEmailProcessedκαιreply, που απαιτούν επιπλέον ένα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" }'Τρία πράγματα πρέπει να τα κάνετε σωστά. Πρώτον, ένας λογαριασμός μπορεί να έχει το πολύ 40 webhooks σε όλους τους τύπους, οπότε δρομολογήστε ανά συμβάν μέσα στον handler σας αντί να καταχωρείτε ένα endpoint ανά συμβάν. Δεύτερον, χρησιμοποιήστε τη σημαία batched όταν περιμένετε όγκο, αφού ένα αίτημα που μεταφέρει πολλά συμβάντα είναι πολύ φθηνότερο στην επεξεργασία από πολλά αιτήματα. Τρίτον, προστατέψτε τον δέκτη: το Brevo δημοσιεύει τα εύρη IP αποστολής του και ο περιορισμός του endpoint σας σε αυτά τα εύρη είναι η τεκμηριωμένη προσέγγιση. Προσθέστε το δικό σας κοινό μυστικό μέσω του πεδίου headers ως δεύτερο επίπεδο.
Οι handlers πρέπει να είναι idempotent. Θεωρήστε το id μηνύματος συν τον τύπο συμβάντος συν τη χρονοσήμανση ως κλειδί απαλοιφής διπλότυπων.
Όρια ρυθμού και χειρισμός σφαλμάτων
Τα όρια ρυθμού του Brevo ορίζονται ανά endpoint και ανά επίπεδο πακέτου, και η διαφορά μεταξύ των endpoints είναι τεράστια.
| Endpoint | Standard | Professional και 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 |
GET /v3/smtp/emails | 2 RPS, 7.200 RPH | 3 RPS, 10.800 RPH |
| Όλα τα υπόλοιπα | 100 RPH | 200 RPH |
Αυτή η τελευταία γραμμή είναι που πονάει. Η αποστολή είναι ουσιαστικά αμέτρητη, ενώ η διαχείριση καμπανιών, οι αναγνώσεις CRM και οι περισσότερες διαχειριστικές κλήσεις μοιράζονται έναν προϋπολογισμό 100 αιτημάτων ανά ώρα στα τυπικά πακέτα. Μια αφελής επαναφόρτωση που διαβάζει μια εγγραφή εταιρείας πριν από κάθε εγγραφή εξαντλεί το όριο μιας ώρας σε λιγότερο από δύο λεπτά.
Κάθε απόκριση μεταφέρει τα x-sib-ratelimit-limit, x-sib-ratelimit-remaining και x-sib-ratelimit-reset. Διαβάστε τα στην επιτυχία, όχι μόνο στην αποτυχία. Η υπέρβαση ενός ορίου επιστρέφει 429, και η σωστή αντίδραση είναι να περιμένετε το διάστημα της κεφαλίδας reset και μετά να εφαρμόσετε εκθετική υποχώρηση με τυχαιότητα.
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 και 5xx. Ποτέ μην επαναλαμβάνετε τυφλά σε 400 ή 409, επειδή και τα δύο συνήθως σημαίνουν ότι το αίτημα είναι λάθος και όχι πρόωρο, ενώ ένα 409 ειδικότερα χρειάζεται διαφορετική ενέργεια αντί για επανάληψη.
Δοκιμές χωρίς αποστολή αλληλογραφίας
Προσθέστε την κεφαλίδα X-Sib-Sandbox με τιμή drop σε μια transactional αποστολή. Το Brevo επικυρώνει το αίτημα, επιστρέφει 201 με ένα messageId, δεν παραδίδει τίποτα και δεν γράφει καταγραφή email.
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>" }'Κατανοήστε τι αποδεικνύει και τι δεν αποδεικνύει αυτό. Η λειτουργία sandbox επικυρώνει μόνο τη μορφή του αιτήματος. Δεν λέει τίποτα για την ταυτοποίηση αποστολέα, την απόδοση προτύπων ή την παραδοσιμότητα. Κρατήστε ξεχωριστό λογαριασμό Brevo για δοκιμές ενσωμάτωσης σε οτιδήποτε αγγίζει επαφές ή δεδομένα CRM, επειδή η λειτουργία sandbox καλύπτει την αποστολή και όχι το υπόλοιπο API.
Όρια που διαμορφώνουν τον σχεδιασμό της ενσωμάτωσής σας
Αυτοί είναι οι περιορισμοί που εμφανίζονται μόνο όταν μια ενσωμάτωση τρέχει σε πραγματικό λογαριασμό με όγκο. Αρκετοί αντιφάσκουν με όσα λέει το API για τον εαυτό του. Κανένας δεν είναι διαπραγματεύσιμος, οπότε η μόνη λογική απάντηση είναι να σχεδιάσετε γύρω τους.
Οι εταιρείες απαιτούν domain, και μόνο μία εταιρεία ανά domain
Το GET /v3/crm/attributes/companies αναφέρει κάθε χαρακτηριστικό ως μη υποχρεωτικό, και η αναφορά δημιουργίας εταιρείας παραθέτει μόνο το name ως υποχρεωτικό. Στην πράξη, το POST /v3/companies χωρίς μη κενό χαρακτηριστικό domain επιστρέφει 400 με μήνυμα για ελλείποντα υποχρεωτικά προεπιλεγμένα χαρακτηριστικά. Μια κενή συμβολοσειρά αποτυγχάνει το ίδιο με την παράλειψή του.
Ακόμη χειρότερα, επιβάλλεται μοναδικότητα domain. Μια δεύτερη εταιρεία σε domain που ήδη χρησιμοποιείται επιστρέφει 409. Για το B2B εμπόριο αυτό είναι δομικό: θυγατρικές που μοιράζονται ένα domain email αγοραστή δεν μπορούν να υπάρχουν όλες ως ξεχωριστές εταιρείες στο Brevo. Ο συγχρονισμός μιας επαφής αρκεί επίσης για να εμφανιστεί μια εταιρεία στο domain email αυτής της επαφής, οπότε μια δημιουργία μπορεί να συγκρουστεί με εταιρεία που κανείς δεν δημιούργησε ρητά. Ο σωστός handler υιοθετεί την υπάρχουσα εταιρεία σε 409 αντί να αποτυγχάνει ή να επαναλαμβάνει.
Τα μη δηλωμένα χαρακτηριστικά απορρίπτονται σιωπηλά
Αυτή είναι η πιο επικίνδυνη συμπεριφορά της πλατφόρμας, και το Brevo την τεκμηριώνει ξεκάθαρα: αν ένα χαρακτηριστικό εμφανιστεί σε ένα αίτημα αλλά δεν είχε οριστεί προηγουμένως στο σχήμα του αντικειμένου, δεν συμβαίνει τίποτα. Κανένα σφάλμα, καμία δημιουργία χαρακτηριστικού, καμία προειδοποίηση.
Μια απόκριση 2xx δεν αποτελεί επομένως απόδειξη ότι τα δεδομένα σας προσγειώθηκαν. Διαβάστε το σχήμα πριν γράψετε, αφαιρέστε ό,τι δεν είναι δηλωμένο μέσα στον δικό σας client και αρνηθείτε να τρέξετε έναν συγχρονισμό του οποίου τα χαρακτηριστικά δεν υπάρχουν, αντί να γράφετε μισή εγγραφή για έναν μήνα πριν το προσέξει κανείς.
Τα φίλτρα χαρακτηριστικών γίνονται δεκτά και αγνοούνται
Το GET /v3/companies?filters[attributes.domain]=... επιστρέφει 200 και αγνοεί το φίλτρο. Δύο εντελώς διαφορετικά φίλτρα επιστρέφουν τις ίδιες εγγραφές. Δεν υπάρχει λειτουργικός τρόπος να αναζητήσετε μια εταιρεία με βάση χαρακτηριστικό μέσω αυτής της διαδρομής.
Σε συνδυασμό με το γεγονός ότι η αφιλτράριστη λίστα κάνει timeout με 504 σε μεγάλους λογαριασμούς σε οποιοδήποτε μέγεθος σελίδας, μια υπάρχουσα εταιρεία μπορεί να είναι πραγματικά μη ανευρέσιμη μέσω της τεκμηριωμένης διαδρομής. Η λύση είναι να σαρώσετε το GET /v3/objects/company/records με sort=desc, που είναι γρήγορο, σελιδοποιημένο και επιστρέφει χαρακτηριστικά, περιορισμένο σε λογικό αριθμό σελίδων. Μια εταιρεία που μόλις προκάλεσε 409 είχε σχεδόν πάντα δημιουργηθεί λίγο νωρίτερα, οπότε η σάρωση με τα νεότερα πρώτα τη βρίσκει γρήγορα.
Ένα εκατομμύριο εγγραφές ανά τύπο αντικειμένου, και καμία μαζική διαγραφή
Το POST /v3/objects/{type}/batch/upsert επιστρέφει 400 μόλις ένας τύπος αντικειμένου φτάσει το ένα εκατομμύριο εγγραφές. Μπλοκάρει τόσο τις ενημερώσεις όσο και τις δημιουργίες: η αναφορά σε υπάρχουσα εγγραφή με το δικό της αριθμητικό id αποτυγχάνει με τον ίδιο τρόπο. Ολόκληρη η διαδρομή εγγραφής αντικειμένων κλείνει μεμιάς.
Η επιστροφή κάτω από το όριο είναι αργή, επειδή το POST /v3/objects/{type}/batch/delete επιστρέφει 403 για τυπικούς τύπους αντικειμένων του Brevo όπως το company. Η μόνη διαδρομή είναι το DELETE /v3/companies/{id}, μία εγγραφή ανά κλήση σε περίπου 156 ms. Ο καθαρισμός 124.000 εγγραφών με αυτόν τον τρόπο πήρε ώρες με 20 παράλληλους εργάτες. Παρακολουθείτε τον αριθμό εγγραφών προγραμματισμένα αντί να ανακαλύψετε το όριο μέσα από έναν αποτυχημένο συγχρονισμό, και δρομολογήστε τις ενημερώσεις υψηλού όγκου μέσω PATCH /v3/companies/{id}, που δεν έχει τέτοιο όριο.
Το ext_id είναι το id του Brevo, όχι το δικό σας
Στις εγγραφές αντικειμένων, το identifiers.ext_id κρατά το δικό του id εταιρείας CRM του Brevo, μια συμβολοσειρά τύπου Mongo. Δεν είναι ελεύθερο εξωτερικό κλειδί. Το να βασίσετε ένα upsert στο ext_id ορισμένο στο αναγνωριστικό της πλατφόρμας σας δημιουργεί διπλότυπα αντί να κάνει αντιστοίχιση. Το εξωτερικό σας id ανήκει σε ένα δικό του δηλωμένο χαρακτηριστικό.
Τα upserts αντικειμένων είναι ασύγχρονα, οι εγγραφές CRM όχι
Το batch/upsert επιστρέφει 202 και ένα processId, και εφαρμόζεται αργότερα. Ένα ανύπαρκτο id αποτυγχάνει ασύγχρονα και εξακολουθεί να επιστρέφει 202 στον καλούντα σας. Το PATCH /v3/companies/{id} επιστρέφει 204 και εφαρμόζεται σύγχρονα. Αν ο συγχρονισμός σας αναφέρει επιτυχία, μόνο η σύγχρονη διαδρομή δικαιούται τη λέξη χωρίς επακόλουθη ανάγνωση.
Μια σύντομη λίστα ελέγχου ενσωμάτωσης
- Ξεχωριστά κλειδιά API ανά υπηρεσία και ανά περιβάλλον, με εναλλαγή σε αλλαγές προσωπικού.
- Όλες οι εγγραφές περνούν από έναν client που διαβάζει τις κεφαλίδες ορίων ρυθμού και υποχωρεί σε 429.
- Το σχήμα χαρακτηριστικών επαληθεύεται κατά την εκκίνηση, και ο συγχρονισμός αρνείται να τρέξει αν λείπουν τα χαρακτηριστικά του.
- Το 409 στη δημιουργία εταιρείας σημαίνει υιοθέτηση, όχι επανάληψη.
- Οι μαζικές διαδρομές χρησιμοποιούν το objects API για ρυθμό και τις διαδρομές CRM για ό,τι πρέπει να επιβεβαιωθεί.
- Τα webhooks είναι idempotent, ομαδοποιημένα, περιορισμένα σε IP και φέρουν κεφαλίδα κοινού μυστικού.
- Οι σταδιακοί συγχρονισμοί επαφών χρησιμοποιούν
modifiedSince, όχι διατρέξεις ολόκληρης της λίστας.
Η κατασκευή και η συντήρηση αυτού του επιπέδου είναι πραγματική δουλειά μηχανικής: επαλήθευση σχήματος, υποχώρηση, λογική υιοθέτησης, συμφωνία δεδομένων. Το Tajo υπάρχει για να την απορροφήσει, κρατώντας τα δεδομένα Shopify και εμπορίου συγχρονισμένα με επαφές, εταιρείες και συμβάντα του Brevo χωρίς να γράφει κανείς με το χέρι τη λογική επανάληψης και απαλοιφής διπλότυπων. Αν αντ’ αυτού το καλωδιώνετε μόνοι σας, ο οδηγός ενσωμάτωσης Brevo περνά μέσα από τις επιλογές μοντέλου δεδομένων που προηγούνται του κώδικα.
Βασικά συμπεράσματα
- Το API είναι μία επιφάνεια REST στο
https://api.brevo.com/v3/, με ταυτοποίηση μέσω κεφαλίδαςapi-keyκαι όχι bearer token. - Τα όρια ρυθμού είναι εξαιρετικά άνισα: η αποστολή είναι ουσιαστικά αμέτρητη, ενώ τα περισσότερα άλλα endpoints μοιράζονται 100 αιτήματα ανά ώρα στα τυπικά πακέτα.
- Υπάρχουν επίσημα SDK για επτά γλώσσες, αλλά η επιφάνεια HTTP είναι αρκετά απλή ώστε να την καλέσετε απευθείας όταν χρειάζεστε μόνο λίγα endpoints.
- Η λειτουργία sandbox επικυρώνει μόνο τη μορφή του αιτήματος, οπότε κρατήστε ξεχωριστό λογαριασμό για δοκιμές οτιδήποτε πέρα από τις αποστολές.
- Μια απόκριση 2xx δεν αποδεικνύει ότι μια εγγραφή εφαρμόστηκε. Τα μη δηλωμένα χαρακτηριστικά απορρίπτονται σιωπηλά και τα upserts αντικειμένων είναι ασύγχρονα.
- Σχεδιάστε γύρω από τα σταθερά όρια: μία εταιρεία ανά domain, ένα εκατομμύριο εγγραφές ανά τύπο αντικειμένου, καμία μαζική διαγραφή για τυπικά αντικείμενα και φίλτρα χαρακτηριστικών που σιωπηλά δεν κάνουν τίποτα.