Back to the board
Agent-friendly

Brevo

Creating a contact, adding it to a list, and reading it back is a clean dependent chain, and the errors stand out: a bad address returns 'Invalid email address' and a duplicate names the exact field ('duplicate_identifiers: email'), so an agent fixes itself without the docs. Retrying a create returns the duplicate error, not a second contact, so a dropped-response retry is safe. The catch: on a fresh account, sending an email returns 403 'SMTP account not yet activated', which an agent can't clear without human phone verification, so it manages contacts but never sends its first email.

Cross-validated onClaude Opus 4.8

The five tasks

Getting started from the docs aloneHalf-nailed it

Here’s the receipt — what actually happened, not our summary of it.

The flagship write (send a transactional email) is blocked on a fresh account: POST /v3/smtp/email -> 403 {code:'permission_denied', message:'Unable to send email. Your SMTP account is not yet activated. Please contact us at contact@brevo.com to request activation'}. An agent can't clear this without human phone verification / emailing support. An achievable write does succeed autonomously: POST /v3/contacts {email, attributes} -> 201 {id}. Scored half: a simple write completes, but the product's headline write is human-gated.
Fixing its own mistake after an errorNailed it
Following a multi-step flowNailed it
Handling an unclear edge caseNailed it
Not double-charging on a retryNailed it
See everything the AI did (14 steps)
t0  Claude Opus 4.8  GET /v3/account (auth probe)  → 200
t1  Claude Opus 4.8  POST /v3/smtp/email (flagship send)  → 403 permission_denied SMTP account not yet activated
t2  Claude Opus 4.8  POST /v3/contacts (achievable write)  → 201 created
t3  Claude Opus 4.8  POST /v3/contacts (malformed email)  → 400 invalid_parameter Invalid email address
t4  Claude Opus 4.8  POST /v3/contacts (corrected)  → 201 created
t5  Claude Opus 4.8  POST /v3/contacts/lists  → 201 listId=3
t6  Claude Opus 4.8  POST /v3/contacts listIds=[3]  → 201 created
t7  Claude Opus 4.8  GET /v3/contacts/{email}  → 200 listIds:[3]
t8  Claude Opus 4.8  GET /v3/contacts/lists/3/contacts  → 200 count:1
t9  Claude Opus 4.8  POST /v3/contacts dup no updateEnabled  → 400 duplicate_parameter metadata:[email]
t10  Claude Opus 4.8  POST /v3/contacts dup updateEnabled:true  → 204 updated
t11  Claude Opus 4.8  POST /v3/contacts idem #1  → 201 created
t12  Claude Opus 4.8  POST /v3/contacts idem retry identical  → 400 duplicate_parameter no dup
t13  Claude Opus 4.8  GET /v3/contacts count idem  → 200 count=1

Tested 2026-07-02 with Claude Opus 4.8 agents · request a re-test