Skip to content

Create Custom Tracking Domain method 🌐 Domains

Register a custom branded domain for click tracking, open tracking, or unsubscribe handling. By default, MailChannels uses shared domains for these links. Using a custom domain improves brand consistency by replacing shared domains with your own (e.g., click.example.com). Once registered, select the domain at send time using its name.

Before registration completes, two DNS records must be in place:

  1. A TXT record at _mailchannels-verify.<hostname> containing the verification token (returned when DNS setup is required).
  2. A CNAME record at <hostname> pointing to links.mailchannels.net.

Usage

ts
import { MailChannelsClient, Domains } from 'mailchannels-sdk'

const mailchannels = new MailChannelsClient('your-api-key')
const domains = new Domains(mailchannels)

const { data, error } = await domains.customTracking.create(
  'clickdemo',
  'click.example.com',
  'click'
)

if (error) {
  throw new Error(error.message)
}

if (data.dnsSetupRequired) {
  // DNS setup required fields available here
}
else {
  // Domain fields available here
}
ts
import { MailChannels } from 'mailchannels-sdk'

const mailchannels = new MailChannels('your-api-key')

const { data, error } = await mailchannels.domains.customTracking.create(
  'clickdemo',
  'click.example.com',
  'click'
)

if (error) {
  throw new Error(error.message)
}

if (data.dnsSetupRequired) {
  // DNS setup required fields available here
}
else {
  // Domain fields available here
}

Params

  • name string required: A unique label used to select this domain at message send time.

    IMPORTANT

    Maximum length is 64 characters. Must match the pattern ^[a-z0-9-]+$.

  • hostname string required: The hostname to register as a custom tracking domain. The hostname must have a CNAME record pointing to links.mailchannels.net.
  • scope DomainsCustomTrackingScope required: The event type this domain handles (click, open, unsubscribe).

Response

  • data DomainsCustomTrackingWithDnsSetupRequired | null nullable: The created domain or DNS verification info when pending.
    • When DNS setup is complete:
      • dnsSetupRequired false guaranteed: Whether DNS setup is required for this domain.
      • name string guaranteed: The label for this custom tracking domain.
      • hostname string guaranteed: The registered domain hostname.
      • scope DomainsCustomTrackingScope guaranteed: The event type this domain handles (click, open, unsubscribe).
      • status "active" | "disabled" guaranteed: Current status of the custom tracking domain.
      • createdAt string guaranteed: ISO 8601 timestamp when the domain was registered.
    • When DNS setup is required:
      • dnsSetupRequired true guaranteed: Whether DNS setup is required for this domain.
      • token string optional: UUID v4 nonce; also the TXT record value to set. Present only when TXT ownership verification is pending.
      • txtRecordName string optional: Fully-qualified DNS TXT record name to add. Present only when TXT ownership verification is pending.
      • txtRecordValue string optional: Value for the DNS TXT record. Present only when TXT ownership verification is pending.
      • instructions string optional: Human-readable guidance for the DNS records that must be in place before retrying.
  • error ErrorResponse | null nullable: Error information if the operation failed.
    • message string guaranteed: A human-readable description of the error.
    • statusCode number | null nullable: The HTTP status code from the API, or null if the error is not related to an HTTP request. This field is intended for diagnostic use only and should not be relied upon.
    • type string guaranteed: A string identifier for the type of error. This field is intended for diagnostic use only and should not be relied upon.
    • response Record<string, unknown> | null nullable: An object containing the response, if available. This field may be null if no response is available or if the error is not related to an HTTP request or if the response is not a JSON object.

Type declarations

Signature

ts
async function create (name: string, hostname: string, scope: DomainsCustomTrackingScope): Promise<DomainsCustomTrackingCreateResponse>

Response type declarations

ts
interface ErrorResponse {
  message: string;
  statusCode: number | null;
  type: ErrorType;
  response: Record<string, unknown> | null;
}
ts
type DataResponse<T> = {
  data: T;
  error: null;
} | {
  data: null;
  error: ErrorResponse;
};

Custom Tracking Domain type declarations

ts
type DomainsCustomTrackingScope = "click" | "open" | "unsubscribe";
ts
interface DomainsCustomTrackingDomain {
  name: string;
  hostname: string;
  scope: DomainsCustomTrackingScope;
  status: "active" | "disabled";
  createdAt: string;
}

Create Custom Tracking Domain type declarations

ts
interface DomainsCustomTrackingDnsSetupRequired {
  token?: string;
  txtRecordName?: string;
  txtRecordValue?: string;
  instructions?: string;
}
ts
type DomainsCustomTrackingWithDnsSetupRequired<T extends 202 | 201 | 200 | undefined = undefined> =
  T extends undefined
    ? | DomainsCustomTrackingDomain & { dnsSetupRequired: false }
      | DomainsCustomTrackingDnsSetupRequired & { dnsSetupRequired: true }
    : T extends 202
      ? DomainsCustomTrackingDnsSetupRequired & { dnsSetupRequired: true }
      : DomainsCustomTrackingDomain & { dnsSetupRequired: false };
ts
type DomainsCustomTrackingCreateResponse = DataResponse<DomainsCustomTrackingWithDnsSetupRequired>;

Source

SourcePlaygroundDocsTests

Released under the MIT License.