Summary
POST https://in-automate.brevo.com/api/v2/trackEvent returns 204 No Content when the ma-key header contains a value that is not a valid key. It validates the request body synchronously but not the credential, so a caller with a wrong, rotated or malformed key gets an unbroken stream of success responses while nothing is recorded.
Reproduction
# garbage key — accepted
$ curl -o /dev/null -w "%{http_code}\n" -X POST https://in-automate.brevo.com/api/v2/trackEvent \
-H "ma-key: not-a-real-key-at-all" -H "content-type: application/json" \
-d '{"email":"someone@example.com","event":"probe"}'
204
# missing header — correctly rejected
$ curl -X POST https://in-automate.brevo.com/api/v2/trackEvent \
-H "ma-key: " -H "content-type: application/json" \
-d '{"email":"someone@example.com","event":"probe"}'
401 {"code":"unauthorized","message":"'ma-key' is missing in headers"}
# body IS validated synchronously
$ ... -d '{"event":"probe"}'
400 {"code":"request","message":"email is empty or invalid"}
$ ... -d '{"email":"someone@example.com"}'
400 {"code":"request","message":"event is empty"}
So the endpoint checks that the header is present, and checks the body, but does not check that the key is valid before returning 204.
Why this is worse than a normal auth bug
A 401 is self-announcing — you find out immediately. A 204 is indistinguishable from success, so the failure mode is:
- an integration ships with a bad or stale key,
- every call returns 204 and every log line looks healthy,
- automations never fire, and
- nobody notices until a customer asks why their birthday or win-back emails stopped.
It also makes the endpoint untestable from the outside. There is no way for an integrator to verify their key works short of building an automation in the UI and watching whether a contact enters it — the HTTP response carries no signal at all.
What would resolve it
Return 401 when ma-key is present but invalid, matching the existing behaviour for a missing header. If asynchronous processing means validity genuinely cannot be determined at request time, then a 202 Accepted would at least be honest about not being a confirmation — but a synchronous key check would be far more useful, since the key is a static credential and does not require the event pipeline to resolve.
Context
Found while evaluating whether an OAuth access token can stand in for an ma-key, since /v3/events rejects OAuth tokens outright (filed separately as #46). The 204 initially looked like a positive result; it was only the control test with a deliberately invalid key that showed the response means nothing either way.
Summary
POST https://in-automate.brevo.com/api/v2/trackEventreturns204 No Contentwhen thema-keyheader contains a value that is not a valid key. It validates the request body synchronously but not the credential, so a caller with a wrong, rotated or malformed key gets an unbroken stream of success responses while nothing is recorded.Reproduction
So the endpoint checks that the header is present, and checks the body, but does not check that the key is valid before returning 204.
Why this is worse than a normal auth bug
A 401 is self-announcing — you find out immediately. A 204 is indistinguishable from success, so the failure mode is:
It also makes the endpoint untestable from the outside. There is no way for an integrator to verify their key works short of building an automation in the UI and watching whether a contact enters it — the HTTP response carries no signal at all.
What would resolve it
Return
401whenma-keyis present but invalid, matching the existing behaviour for a missing header. If asynchronous processing means validity genuinely cannot be determined at request time, then a202 Acceptedwould at least be honest about not being a confirmation — but a synchronous key check would be far more useful, since the key is a static credential and does not require the event pipeline to resolve.Context
Found while evaluating whether an OAuth access token can stand in for an
ma-key, since/v3/eventsrejects OAuth tokens outright (filed separately as #46). The 204 initially looked like a positive result; it was only the control test with a deliberately invalid key that showed the response means nothing either way.