BluetickedDeveloper docs

Email

Sending identity, HTML bodies, and the compliance footer every marketing send carries.

Email: getting live

  1. 1
    Verify a sending domainAdd the DKIM and SPF records for your own domain. Until it verifies, transactional email uses the shared sender and lands less reliably, and marketing email is refused (400 validation_failed, details.reason custom_identity_required). A test key does not check this, so the first live marketing send is where it shows.Set up your domain
  2. 2
    Decide transactional or marketingmessage_type drives consent and the compliance footer. Marketing requires explicit opt-in and always carries an unsubscribe link.Read the concepts
  3. 3
    Send it with a test keyA blu_test_ key validates the whole request — contact, consent, rendering — without a message leaving or a cent being charged.Send from the console
  4. 4
    Watch what happens nextOpens, clicks, bounces and complaints arrive as webhooks, and a complaint suppresses the address automatically.Open analytics

Essentials

Sending identity & domain
Email sends go through your business's connected sender identity. Verify a sending domain (SPF, DKIM, DMARC) in Blueticked; reply_to is accepted only when it matches the active sender address for that business. A send the sender cannot make answers 400 validation_failed with details.reason naming the case (custom_identity_required, dmarc_required, business_identity_required, physical_address_required, freemail_reply_to or reply_to_not_aligned).
Transactional vs marketing
message_type defaults to transactional (bypasses marketing opt-outs, never an 'all' block). Set marketing to honour marketing opt-outs and double opt-in. Marketing email cannot use cc or bcc — send one message per recipient.
Unsubscribe & suppression
A one-click unsubscribe header is added automatically. Hard bounces and spam complaints auto-suppress the recipient, and suppressed addresses are skipped on future sends.
Delivery events
Subscribe a webhook to email.opened / clicked / bounced / complained. Authorize email sends with messages:send or the least-privilege email:send scope.

Email API endpoints

POST/api/v1/messagesmessages:sendTry in console

Send an email

Send a transactional email to a contact (or create it with to.create: true), with an optional subject line and reply-to.

Body parameters
business_idstring
channelrequiredstring
torequiredobject
subjectstring
bodyrequiredstring
message_typestring
reply_tostring
ccstring[]
bccstring[]
  • Email uses to.email and a free-form body; pass subject to set the subject line (free-text emails without one default to "Notification").
  • Authorize email sends with either messages:send or the least-privilege email:send scope.
  • message_type defaults to transactional (bypasses marketing opt-outs, never an 'all' block); set marketing to honour marketing opt-outs, double opt-in and the contact's recorded email consent.
  • reply_to is accepted only when it matches the active sender address for that business; configure sender/reply identity in Blueticked before sending.
  • cc / bcc (arrays of addresses, max 50 each) are accepted on transactional email only: any cc/bcc address on the suppression list (opted-out / bounced / complained) is silently dropped, and the primary recipient must pass or the whole send is rejected. Marketing email rejects cc/bcc outright (see the marketing-email example).
  • Emails send through the selected business's connected sender identity. If multiple email channels exist, pass business_id.
  • A one-click unsubscribe header is added automatically; bounces and complaints auto-suppress the recipient.
curl -X POST "https://app.blueticked.com/api/v1/messages" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: change-me-per-request-0001" \
  -d '{
  "business_id": "22222222-2222-4222-9222-222222222222",
  "channel": "email",
  "to": {
    "email": "sam@example.com"
  },
  "subject": "Your statement is ready",
  "body": "Hi Sam, your May statement is attached in your account.",
  "message_type": "transactional",
  "reply_to": "accounts@yourbusiness.co.za",
  "cc": [
    "colleague@yourbusiness.co.za"
  ],
  "bcc": [
    "archive@yourbusiness.co.za"
  ]
}'
Response
{
  "message_id": "763c4dc3-d46b-4c10-8bd4-3f233a933ea0",
  "conversation_message_id": "5592edf6-d7ae-4198-962e-3e8ebe83bb49",
  "conversation_id": "fa3efd47-67b2-428c-b75f-17d1dd2e9790",
  "status": "queued",
  "contact_id": "ff506e53-e2f0-4d92-884a-dab77d628bad",
  "contact_created": false,
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
POST/api/v1/messagesmessages:sendTry in console

Send a marketing email (HTML body)

Send a marketing email with your own HTML body, rendered inside the branded shell with the required compliance footer.

Body parameters
business_idstring
channelrequiredstring
torequiredobject
subjectstring
message_typestring
bodyrequiredstring
htmlstring
reply_tostring
  • Send both: body is the plain-text alternative every email needs, and html is the rendered part. html is your content only. Blueticked wraps it in the sender's branded shell and always appends the compliance footer (unsubscribe + physical address), so the unsubscribe link can never be dropped.
  • message_type: "marketing" is required for promotional mail: recipients with a marketing opt-out, an unconfirmed double opt-in, or no recorded email consent are rejected up front (details.reason: "consent_required" for the last).
  • reply_to, when supplied, must match the active sender address for the selected business. This protects sender alignment and deliverability.
  • Marketing email is strictly one recipient per send: passing cc or bcc is rejected with a 400 (validation_failed, "Marketing email cannot use cc or bcc") so consent, unsubscribe and tracking stay recipient-specific. Use the transactional send example if you need cc/bcc.
curl -X POST "https://app.blueticked.com/api/v1/messages" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: change-me-per-request-0001" \
  -d '{
  "business_id": "22222222-2222-4222-9222-222222222222",
  "channel": "email",
  "to": {
    "email": "sam@example.com"
  },
  "subject": "20% off this month",
  "message_type": "marketing",
  "body": "Winter sale: 20% off all services this month.",
  "html": "<h1>Winter sale</h1><p>20% off all services this month.</p>",
  "reply_to": "hello@yourbusiness.co.za"
}'
Response
{
  "message_id": "763c4dc3-d46b-4c10-8bd4-3f233a933ea0",
  "conversation_message_id": "5592edf6-d7ae-4198-962e-3e8ebe83bb49",
  "conversation_id": "fa3efd47-67b2-428c-b75f-17d1dd2e9790",
  "status": "queued",
  "contact_id": "ff506e53-e2f0-4d92-884a-dab77d628bad",
  "contact_created": false,
  "request_id": "req_1d287d7abad27e32267ed53db44059f0"
}
GET/api/v1/email/sending-domainchannels:readTry in console

Get email sending identity

Read a business email sending identity and its DNS verification status.

Query parameters
business_idstring
  • Returns sending_domain: null when no identity is configured.
  • If the workspace has more than one email channel, pass business_id to choose the business.
  • Possible statuses: not_started, pending, verified, partially_verified, partially_failed, failed, temporary_failure.
  • While status is not 'verified', this refreshes the live status so polling reflects DNS propagation.
curl -X GET "https://app.blueticked.com/api/v1/email/sending-domain" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "sending_domain": {
    "id": "fb1c7505-7053-44da-bf3a-5b0e8949e81d",
    "domain": "mail.yourbusiness.co.za",
    "from_local_part": "accounts",
    "status": "pending",
    "records": [
      {
        "record": "DKIM",
        "name": "resend._domainkey",
        "type": "TXT",
        "value": "p=MIGf...",
        "status": "pending"
      }
    ]
  },
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
POST/api/v1/email/sending-domainchannels:writeTry in console

Add an email sending identity

Register a Blueticked-managed sending identity and get back the DNS records to add. Emails use that sender once it verifies.

Query parameters
business_idstring
Body parameters
domainrequiredstring
from_local_partrequiredstring
  • Add the returned DNS records at your domain registrar, then call the verify endpoint.
  • If the workspace has more than one email channel, pass business_id to choose the business.
  • One sending identity per business - remove the current one (DELETE) before adding another.
  • A domain the email provider already has is never taken over. Another workspace's or business's domain answers 409 conflict with details.reason domain_in_use_elsewhere or domain_in_use_by_business. One no workspace holds answers 409 conflict with domain_registered_unclaimed: support releases it, and a retry gets the same answer. If the holder could not be read, it answers 503 service_unavailable with domain_holder_unchecked.
  • A timeout or a provider 5xx is answered as could not confirm. A retried add of a domain the provider did take answers domain_registered_unclaimed: contact support with request_id.
  • Until verified, emails keep sending from the shared Blueticked address; once verified they send from from_local_part@domain.
curl -X POST "https://app.blueticked.com/api/v1/email/sending-domain" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "mail.yourbusiness.co.za",
  "from_local_part": "accounts"
}'
Response
{
  "sending_domain": {
    "id": "fb1c7505-7053-44da-bf3a-5b0e8949e81d",
    "domain": "mail.yourbusiness.co.za",
    "from_local_part": "accounts",
    "status": "pending",
    "records": [
      {
        "record": "DKIM",
        "name": "resend._domainkey",
        "type": "TXT",
        "value": "p=MIGf...",
        "status": "pending"
      },
      {
        "record": "SPF",
        "name": "send",
        "type": "MX",
        "value": "feedback-smtp.eu-west-1.amazonses.com",
        "priority": 10,
        "status": "pending"
      }
    ]
  },
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
POST/api/v1/email/sending-domain/verifychannels:writeTry in console

Verify the email sending identity

Trigger a DNS re-check now. When it returns verified, every send uses the verified sender address.

Query parameters
business_idstring
  • Call this after adding the DNS records; DNS can take minutes to hours to propagate.
  • If the workspace has more than one email channel, pass business_id to choose the business.
curl -X POST "https://app.blueticked.com/api/v1/email/sending-domain/verify" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "sending_domain": {
    "id": "fb1c7505-7053-44da-bf3a-5b0e8949e81d",
    "domain": "mail.yourbusiness.co.za",
    "from_local_part": "accounts",
    "status": "verified",
    "records": [
      {
        "record": "DKIM",
        "name": "resend._domainkey",
        "type": "TXT",
        "value": "p=MIGf...",
        "status": "verified"
      }
    ]
  },
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
DELETE/api/v1/email/sending-domainchannels:writeTry in console

Remove the email sending identity

Remove the custom sending identity and revert the workspace to the shared Blueticked sender.

Query parameters
business_idstring
  • If the workspace has more than one email channel, pass business_id to choose the business.
  • Idempotent on the provider side: a failed remote delete still reverts the channel locally.
curl -X DELETE "https://app.blueticked.com/api/v1/email/sending-domain" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "removed": "mail.yourbusiness.co.za",
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}