> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mailchannels.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom tracking

> Route click tracking, open tracking, and unsubscribe links through your own custom domain to reinforce your brand and improve email deliverability.

## What is custom tracking?

By default, MailChannels uses shared domains for click-tracking links, open-tracking pixels,
and unsubscribe URLs embedded in your emails. A custom tracking domain replaces those shared
domains with one you own (e.g., `click.example.com`), improving brand consistency and deliverability.

Each custom tracking domain is defined by three user-configurable fields:

* **`hostname`** — the subdomain you control, e.g., `click.example.com`.
* **`scope`** — the event type it handles: `click`, `open`, or `unsubscribe`.
* **`name`** — a unique short label used to select this domain at send time (e.g., `clickdemo`).

<Info>
  Custom tracking domains are not available on the free developer plan. Upgrade to a paid plan to enable it.
</Info>

## Registering a custom tracking domain

<Steps>
  <Step title="Submit the registration request">
    Provide the `hostname`, `scope`, and a unique `name` for the domain.

    <CodeGroup>
      ```bash cURL theme={null}
      #!/usr/bin/env bash
      # Register a custom click-tracking domain.
      set -u
      : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"

      curl -X POST "https://api.mailchannels.net/tx/v1/custom-tracking-domains" \
        -H "Content-Type: application/json" \
        -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
        -d @- <<JSON
      {
        "name": "clickdemo",
        "hostname": "click.example.com",
        "scope": "click"
      }
      JSON
      ```
    </CodeGroup>

    If the domain has not been verified yet, the API returns the DNS records you need to add.
    The domain is not active at this stage.

    ```json theme={null}
    {
      "token": "550e8400-e29b-41d4-a716-446655440000",
      "txt_record_name": "_mailchannels-verify.click.example.com",
      "txt_record_value": "550e8400-e29b-41d4-a716-446655440000",
      "instructions": "Add a DNS TXT record: _mailchannels-verify.click.example.com → \"550e8400-e29b-41d4-a716-446655440000\" and a CNAME record: click.example.com → links.mailchannels.net, then retry this request."
    }
    ```
  </Step>

  <Step title="Add the required DNS records">
    Add both records to your domain's DNS before retrying:

    ```plaintext theme={null}
    _mailchannels-verify.click.example.com  TXT    550e8400-e29b-41d4-a716-446655440000
    click.example.com                        CNAME  links.mailchannels.net
    ```

    The TXT record proves you own the hostname. The CNAME record routes tracking traffic to MailChannels infrastructure.
  </Step>

  <Step title="Re-register to confirm">
    Once both records have propagated, call the registration endpoint again with the same request body.
    If verification succeeds, the API returns the domain in the `active` status.

    <Note>
      If either record is not yet visible to MailChannels, the response includes an `instructions` field
      describing which record is still missing. Wait for DNS propagation and retry.
    </Note>
  </Step>
</Steps>

## Sending with custom tracking

Reference the custom tracking domain by its `name` in `tracking_settings` or `unsubscribe_settings`
when sending a message. The domain must have `active` status.

A full send example:

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Send an email with the custom click-tracking, open-tracking, and unsubscribe-handling domains.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${FROM_EMAIL:?Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)}"
  : "${TO_EMAIL:?Set TO_EMAIL}"

  curl -X POST "https://api.mailchannels.net/tx/v1/send" \
    -H "Content-Type: application/json" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
    -d @- <<JSON
  {
    "personalizations": [
      { "to": [{ "email": "$TO_EMAIL", "name": "Recipient" }] }
    ],
    "from": {
      "email": "$FROM_EMAIL",
      "name": "Your Name"
    },
    "subject": "Hello from MailChannels",
    "content": [
      {
        "type": "text/html",
        "value": "<p>Hello! Visit our <a href=\"https://example.net/sale\">sale page</a>.</p>"
      }
    ],
    "tracking_settings": {
      "click_tracking": {
        "enable": true,
        "custom_domain_name": "clickdemo"
      },
      "open_tracking": {
        "enable": true,
        "custom_domain_name": "opendemo"
      },
    },
    "unsubscribe_settings": {
      "custom_domain_name": "unsubscribedemo"
    }
  }
  JSON
  ```
</CodeGroup>

## Managing custom tracking domains

### Listing domains

Retrieve all registered domains for your account. Optional filters include `name`, `status`, and `scope`.

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Retrieve custom tracking domains for the account.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY (parent or sub-account) before running}"

  curl -X GET "https://api.mailchannels.net/tx/v1/custom-tracking-domains" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY"
  ```
</CodeGroup>

### Updating a domain

Rename a domain or toggle its status between `active` and `disabled`.

<Note>
  Reactivating a disabled domain triggers DNS re-verification. Both the TXT ownership record and the
  CNAME record must be in place. If either is missing, the response includes an `instructions` field
  describing what to add.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Update a custom tracking domain.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${TRACKING_DOMAIN_HOSTNAME:?Set TRACKING_DOMAIN_HOSTNAME to the hostname of the custom tracking domain to be updated}"
  : "${SCOPE:?Set SCOPE to the scope of the custom tracking domain to be updated}"

  curl -X PATCH "https://api.mailchannels.net/tx/v1/custom-tracking-domains/$TRACKING_DOMAIN_HOSTNAME/$SCOPE" \
    -H "Content-Type: application/json" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
    -d @- <<JSON
  {
    "status": "disabled",
    "name": "dontuse"
  }
  JSON
  ```
</CodeGroup>

### Deleting a domain

Delete a domain by its hostname and scope. The same hostname and scope can be re-registered if needed.

<Warning>
  Any tracking links or unsubscribe URLs in previously sent emails that used a deleted domain will
  stop working immediately.
</Warning>

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Delete a custom tracking domain permanently.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${TRACKING_DOMAIN_HOSTNAME:?Set TRACKING_DOMAIN_HOSTNAME to the hostname of the custom tracking domain to be removed}"
  : "${SCOPE:?Set SCOPE to the scope of the custom tracking domain to be removed}"

  curl -X DELETE "https://api.mailchannels.net/tx/v1/custom-tracking-domains/$TRACKING_DOMAIN_HOSTNAME/$SCOPE" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
  ```
</CodeGroup>
