API reference

Send an email

Send a single email, transactional or one-off, through the API. The message is accepted and queued for delivery.

POST https://app.blacklistguard.com/api/v1/emails/send

Authenticate with your X-API-Key header and send a JSON body. The key needs the emails:send permission.

Request body

FieldTypeRequiredDescription
from_emailstringYesSender address. Must be on a verified sending domain, or be a verified sender.
tostringYesRecipient email address. One plain address, with no display name and no list of addresses. One message per request.
subjectstringYesSubject line.
bodystringNoMessage content. A message without one is sent empty. It is sent as HTML when it contains both a < and a >, and as plain text otherwise.
from_namestringNoDisplay name shown next to the sender address.
bounce_emailstringNoBounce address. Leave it out and BlacklistGuard handles bounces for you. An address on one of your incoming domains works the same way: bounces still come back to us and are processed. An address on any other domain is used exactly as you give it, so bounces go straight to that address.
virtual_mta_ipstringNoWhich IP the message is sent from. Leave it out to use your default (your dedicated IP if you have one, otherwise the shared pool). See Choosing the sending IP.
attachmentsarrayNoFile attachments. See below.

A request without from_email, to or subject is rejected with a 400 and nothing is queued. Fields the endpoint does not know are ignored.

Choosing the sending IP

Leave virtual_mta_ip out and the message uses your default: your own dedicated IP if you have one, otherwise BlacklistGuard's shared pool. Set it to choose where the message is sent from instead. It takes the same values as the campaign field of the same name:

  • An empty string, or no field at all, for your default.
  • "shared_pool" to always use the shared pool, even if you have a dedicated IP.
  • An IP address, such as "203.0.113.10". It must be one of your own verified dedicated IPs, including any you've bought from us. You'll find them under Virtual MTAs in the console.
  • "routing_rule:<id>" to send through one of your active routing rules.

Your choice is kept with the message, so it still applies if the message has to wait in the queue. If the IP stops being yours before the message goes out, for example because you released a dedicated IP, it uses your default instead.

Attachment fields

FieldRequiredDescription
filenameYesFile name shown to the recipient.
contentYesFile contents, Base64-encoded.
content_typeNoMIME type, e.g. application/pdf. Defaults to application/octet-stream.
dispositionNoattachment (default) or inline for embedded images.
content_idNoFor inline images. Reference it in your HTML as cid:<content_id>.
⚠An attachment with no filename, no content, or content that is not valid Base64 is left out. The request still succeeds and the message goes out without it, so check your encoding.
ℹScope of this endpoint. It sends one message to one recipient. It does not support cc, bcc, reply-to, custom headers, scheduling, multiple recipients in one call, separate HTML/text parts, or templates. For audience sends, use campaigns.

Example request

curl -X POST https://app.blacklistguard.com/api/v1/emails/send \
  -H "X-API-Key: efk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "from_email": "you@yourdomain.com",
    "from_name": "Acme",
    "to": "customer@example.com",
    "subject": "Your receipt",
    "body": "<h1>Thanks!</h1><p>Your order is confirmed.</p>",
    "attachments": [
      { "filename": "receipt.pdf", "content_type": "application/pdf", "content": "JVBERi0xLjQK..." }
    ]
  }'

Response

A successful request returns 201 with the queued message's ID:

{
  "success": true,
  "data": { "status": "queued", "id": "1a3a56c6-4393-465e-86aa-d2c0d1200958" },
  "message": "Resource created successfully"
}

Use data.id to find the message in the console under Messages, or through the reporting API.

A message to an address your workspace has suppressed is accepted like any other, but it isn't delivered. Its status becomes skipped, with the reason address is suppressed.

A 201 means the message is queued, not delivered. The platform makes one delivery attempt. A message that fails is not sent again automatically, so check its status and send it again from your side if you need to.

Errors

StatusCodeWhen
400BAD_REQUESTfrom_email is missing or blank. The message is from_email is required.
400BAD_REQUESTfrom_email is not a valid address. The message is Invalid from_email.
400BAD_REQUESTfrom_email is not on a verified sending domain and is not a verified sender. The message tells you to verify the domain or the address.
400BAD_REQUESTto is missing or blank. The message is to is required.
400BAD_REQUESTto is not one plain email address. The message is Invalid to: send one email address.
400BAD_REQUESTsubject is missing or blank. The message is subject is required.
400BAD_REQUESTvirtual_mta_ip is an IP that isn't one of your own verified dedicated IPs. The message is Sending IP must be one of your own verified dedicated IPs; shared-pool IPs cannot be selected directly (use "shared_pool" for the shared pool).
400BAD_REQUESTvirtual_mta_ip names a routing rule with a malformed ID. The message is Invalid routing rule ID.
400BAD_REQUESTvirtual_mta_ip names a routing rule that doesn't exist or isn't yours. The message is Routing rule not found or not owned by this tenant.
400BAD_REQUESTThe body is not valid JSON, or a field has the wrong type. The message starts with Invalid JSON:.
402INSUFFICIENT_BALANCEYour account balance has run out. Nothing is queued, and the message explains why.
402PLAN_LIMIT_REACHEDYour plan's sending allowance is used up. Nothing is queued.
402SERVICE_SUSPENDEDSending is suspended because a payment is overdue. Nothing is queued.
429RATE_LIMIT_EXCEEDEDYour workspace has reached its hourly, daily or monthly sending limit. Nothing is queued, and the message says which. The daily limit resets at 00:00 UTC.
403SENDING_PAUSEDSending is paused for your account. Nothing is queued. The message is Sending is paused for this account. Contact support to have it reviewed.
403INSUFFICIENT_SCOPEThe API key does not have the emails:send permission.
403FEATURE_NOT_AVAILABLEYour plan does not include API access.

See the error codes for the full list, including plan-limit and balance errors.