message.comDevelopers

Email domains Live

Register a domain you own (such as acme.com) and verify the DNS records that let message.com send outbound replies as you and receive inbound tickets at your custom local-parts. Required for any custom_domain inbound address.

List domains

GET/api/v1/email-domainsAuth: Bearer

Code samples

cURL
curl 'https://app.message.com/api/v1/email-domains' \
  -H 'Authorization: Bearer YOUR_WORKSPACE_JWT'
JavaScript
const res = await fetch('https://app.message.com/api/v1/email-domains', {
  headers: { Authorization: 'Bearer ' + token }
});
const { domains } = await res.json();
Python
import requests
r = requests.get(
    "https://app.message.com/api/v1/email-domains",
    headers={"Authorization": f"Bearer {token}"},
)
domains = r.json()["domains"]
Ruby
require "net/http"
require "json"
uri = URI("https://app.message.com/api/v1/email-domains")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  req = Net::HTTP::Get.new(uri)
  req["Authorization"] = "Bearer #{token}"
  http.request(req)
end
domains = JSON.parse(res.body)["domains"]
PHP
<?php
$ctx = stream_context_create([
  "http" => ["method" => "GET", "header" => "Authorization: Bearer $token"]
]);
$domains = json_decode(file_get_contents("https://app.message.com/api/v1/email-domains", false, $ctx), true)["domains"];

Add a domain

POST/api/v1/email-domainsAuth: Bearer

Registers a new domain and returns the DNS records you must add at your registrar. Domain status begins as pending and flips to verified when all records are reachable.

FieldTypeDescription
domainrequiredstringThe apex domain. We register the apex; subdomains inherit.
Body
{ "domain": "acme.com" }
200 OK
{
  "id": "uuid",
  "domain": "acme.com",
  "status": "verified",
  "dnsRecords": [
    { "type": "MX", "host": "@", "value": "10 mx.message.com", "verified": true },
    { "type": "TXT", "host": "@", "value": "v=spf1 include:_spf.message.com ~all", "verified": true },
    { "type": "CNAME", "host": "msg._domainkey", "value": "msg.dkim.message.com", "verified": true }
  ],
  "createdAt": "2026-05-13T15:00:00Z"
}

Get one domain

GET/api/v1/email-domains/:idAuth: Bearer

Returns the domain record with the live DNS verification state for each record.

Re-check DNS

POST/api/v1/email-domains/:id/verifyAuth: Bearer

Forces a re-check against your authoritative DNS. We poll every five minutes automatically; use this endpoint when you have just changed DNS and want immediate feedback.

Remove a domain

DELETE/api/v1/email-domains/:idAuth: Bearer

Removes the domain registration and unbinds any inbound addresses that depended on it. Outbound replies revert to the workspace default [email protected].

DNS records

Three records, all on the apex:

  • MX. Points inbound mail to mx.message.com. Required for ticket creation.
  • SPF (TXT). Authorises our outbound IPs to send as your domain.
  • DKIM (CNAME). Signs outbound mail with our key. Improves deliverability significantly.
  • DMARC (optional). Strongly recommended at p=quarantine or higher. See the DMARC RFC.

Most failures here are propagation delays. Allow up to 24 hours after editing DNS before assuming a record is wrong.

Errors

CodeWhen
400 invalid_bodyDomain string is not a valid DNS apex.
403 forbiddenAgent role is not admin.
409 conflictDomain already registered to another workspace.
422 dns_unverifiedAction requires verified DNS; one or more records still pending.

Common pitfalls

  • Adding an MX record without removing the old one. Multiple MX records of equal priority cause unpredictable routing. Either remove the old MX or set ours to lower preference.
  • Forgetting DKIM. Without DKIM, expect Gmail and Microsoft 365 to spam-foldering your outbound replies.
  • Verifying a subdomain instead of the apex. We require the apex. If you want inbound only on support.acme.com, register acme.com and use a subdomain inbound address.