400 bad request when calling /marketing/v3/transactional/single-email/send

Hi,

I am trying to send an email using the single-email send api, but I keep getting a 400 Bad Request response. The response body is no help, as it only contains this text: “Invalid request”. I guessed as much from the 400 response…

I find the documentation quite confusing but I gather that I should use the SMTP API token in the Authorization header.

My request looks like this:

https://api.hubapi.com/marketing/v3/transactional/single-email/send

```plaintext

Authorization: Bearer [TOKEN]`

Content-Type: application/json

Accept: application/json

```

And my body looks like this:

```json

{

“emailId”: 123456789012,

“message”: {

"to": "\[REDACTED]"

},

“contactProperties”: {

"firstname": "test",

"lastname": "test"

},

“customProperties”: {

"firstName": "test",

"lastName": "test",

"senderFirstName": "\[REDACTED]",

"senderLastName": "\[REDACTED]",

"clinicName": "\[REDACTED]",

"invitationUrl": "\[REDACTED]",

"invitationToken": "\[REDACTED]"

}

}

```

Happens when a few prerequisites/auth bits are off. Use a Private App token with the transactional-email scope (not the SMTP token) and make sure your account has the Transactional Email add-on, and that the emailId points to a published Transactional email (created in Marketing Email - turn on Transactional). Also, pass every required template token in customProperties with the exact internal names used in the email.

If you still get 400, common causes:
Email is not marked Transactional
Email ID is from a draft or non-published version
A required token in the email isn’t provided (typo in property name) You’re sending to a malformed email
The private app lacks the transactional email scope.

Quick sanity check: open the email’s View details to confirm it’s Published (Transactional) and list the required tokens, then match those names 1:1 in your payload.

Hi,

This is where the documentation is a bit confusing… Some parts tells me to use the SMTP token, others tell me to use the private app token. And since I don’t get a 401 Unauthorized or a 403 Forbidden, when I use the SMTP token, I thought everything is OK.
I will try the Private App token and get back to you.

Why can’t the API tell me these things instead of me having to ask a question about it here? If I make a bad request, as the server tells me, it should tell me exactly why it’s a bad request.

Creating a legacy app and use the token from there seems to have worked.