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

# Set up a custom tracking domain

> Publish one CNAME so open and click links use your own domain instead of a shared one.

export const UiPath = ({children}) => {
  const parts = String(children).split(/\s*(?:→|>)\s*/).filter(Boolean);
  return <span className="pl-path">
      {parts.map((part, index) => <span key={`${index}-${part}`}>
          {index > 0 && <span className="pl-path__sep">→</span>}
          {part}
        </span>)}
    </span>;
};

export const Screenshot = ({id, alt, caption, frame = 'browser', url, marks = [], lang = 'en', workspace = 'northwind-outbound'}) => {
  const src = `/images/screenshots/${lang}/${id}.png`;
  const chrome = url ? `app.pipelime.ai/${workspace}${url}` : 'app.pipelime.ai';
  return <figure className={`pl-shot pl-shot--${frame} not-prose`}>
      <div className="pl-shot__frame">
        {frame !== 'bare' && <div className="pl-shot__bar">
            <span className="pl-shot__dots">
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
            </span>
            <span className="pl-shot__url">{chrome}</span>
          </div>}
        <div className="pl-shot__media">
          <img src={src} alt={alt} loading="lazy" />
          {marks.map(mark => <span key={mark.n} className="pl-shot__mark" style={{
    left: `${mark.x}%`,
    top: `${mark.y}%`
  }} aria-hidden="true">
              {mark.n}
            </span>)}
        </div>
      </div>
      {caption && <figcaption className="pl-shot__caption">{caption}</figcaption>}
    </figure>;
};

Publish one CNAME record, and this account's open and click links carry your own domain
instead of the default tracking domain every workspace otherwise shares.

<div className="pl-availability">
  <div className="pl-availability__row">
    <div className="pl-availability__label">Where</div>
    <div className="pl-availability__value"><span className="pl-path">Integrations<span className="pl-path__sep">→</span>Integrations<span className="pl-path__sep">→</span>Email Accounts</span></div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">Your role needs</div>
    <div className="pl-availability__value">Read access to Email Accounts <code>read-senders</code>. Admin, Member and Viewer have it by default.</div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">To create or change</div>
    <div className="pl-availability__value"><code>create-senders</code> to add one, <code>update-senders</code> to change one, on top of the permission above.</div>
  </div>

  <div className="pl-availability__note">If you cannot find this in your sidebar, your workspace may have a custom menu configuration. Contact support and we will check it for you.</div>
</div>

<Note>
  This is a CNAME and nothing else. The check reads a single record's target: SPF, DKIM and
  DMARC are not part of it, and no other record is asked for.
</Note>

## Before you begin

* An email account you can already open. The tracking domain lives among that account's
  optional settings, so [add the account](/en/email-accounts/add-senders) first if you have
  not yet.
* Access to DNS for the domain you want to use: your own provider, or whoever manages it
  for you.

## Add the record

<Steps>
  <Step title="Open the account">
    Go to <UiPath>Integrations → Integrations → Email Accounts</UiPath> and press **Edit** on
    the account whose links you want to carry your domain. Scroll past the connection
    settings to "Optional Settings" and open the "Custom Domain" panel.
  </Step>

  <Step title="Type your domain">
    Enter it without http\:// or https\://. The field already shows http\:// in front of it,
    and a scheme you paste in is stripped for you. A subdomain,
    tracking.yourcompany.com, and a root domain, yourcompany.com, both work.

    <Screenshot id="email-accounts/custom-tracking-domain--record-table" alt="A DNS record table with one row: Type CNAME, Host/Name tracking, Value/Target tracking.pipelime.ai, TTL 3600" caption="One CNAME is the only DNS instruction the product gives you. There is nothing else to add." frame="bare" />

    The table underneath reacts to what you typed. Host/Name becomes the subdomain's first
    label ("tracking", in this example) or @ for a root domain, which is how most DNS
    providers write "the domain itself". Type and Value/Target never change: a CNAME pointing
    at tracking.pipelime.ai. Every cell has a copy control next to it; use it instead of
    retyping, and copy the value from your own screen rather than from this page.
  </Step>

  <Step title="Create the record at your DNS provider">
    Create the CNAME using the host and value from the table, and leave the TTL at 3600
    unless your provider requires something else. The check compares the record's target
    against the expected value exactly, so anything appended to it fails.
  </Step>

  <Step title="Check it">
    Back on this page, press the "Verify Domain" button under the field. It runs a DNS lookup
    right then, so you are not guessing whether the record has propagated. A green alert
    reading "Domain verified successfully!" means the lookup found a CNAME pointing at the
    expected target.

    <Screenshot id="email-accounts/custom-tracking-domain--verified" alt="A green alert reading Domain verified successfully, with the date and time of the check" caption="A representative example: a live pass needs a record that has actually propagated, so this is captured against a simulated response." frame="bare" />
  </Step>

  <Step title="Save">
    Press **Save**. The green alert in the panel is only a preview: the check that is stored
    against the account is the one the server runs again while it saves.
  </Step>
</Steps>

<Warning>
  Save only once the check is green. On a mailbox you connected yourself, changing the
  tracking domain makes the form resend the account's connection settings as well, so saving
  re-tests the mailbox and the CNAME together, and a record that still fails does not merely
  leave tracking alone. The account's status becomes **Error**, and an account in Error sends
  nothing at all until it reconnects.
</Warning>

## What happens next

<Check>
  Reopen the account, open the "Custom Domain" panel again, and the green alert is already
  there. From the next send, this account's open pixel and its click links both carry your
  domain.
</Check>

The registration behind that domain also joins the expiry watch we already keep for your
sending domains (the whole registration, so tracking.yourcompany.com is watched as
yourcompany.com), and you get a notice in the app before it lapses.

## Troubleshooting

<AccordionGroup>
  <Accordion title="DNS verification failed. Please check your CNAME record and try again.">
    <Screenshot id="email-accounts/custom-tracking-domain--failed" alt="A red alert reading DNS verification failed, please check your CNAME record and try again" caption="A representative example: a live failure needs a record that genuinely does not resolve, so this is captured against a simulated response." frame="bare" />

    Almost always the record has not propagated yet: DNS changes are not instant. Give it a
    few minutes and press "Verify Domain" again. If it still fails, check the two things a
    propagation delay would not explain: the target has to match tracking.pipelime.ai
    exactly, with nothing appended, and the record has to sit on the name you typed: a
    subdomain needs its own record, not one on the root.
  </Accordion>

  <Accordion title="The account went into Error as soon as I saved">
    That is the same CNAME check, run again on the server during the save. When it fails, its
    message becomes the account's status message, so the red banner on the form explains the
    DNS failure, not anything about the mailbox. Fix the record at your DNS provider, then
    press Reconnect in that banner: it re-tests the mailbox connection and the tracking domain
    together, and puts the account back to Active when both pass. Full detail on
    [reconnecting](/en/email-accounts/reconnect-a-sender) and on
    [what each status means](/en/email-accounts/sender-statuses).
  </Accordion>

  <Accordion title="The tracking pixel uses my domain, but click links do not">
    The two read different things. The open pixel uses whatever domain is stored on the
    account; click links are only rewritten once the account also carries a stored,
    successful check. So this is a domain that was saved but never confirmed.

    It is what happens on a mailbox running on PipeLime managed infrastructure: saving does
    not re-run the DNS check for those accounts, so the green alert you saw in the panel is
    never stored, and reopening the account shows the domain as unconfirmed even when the
    record is fine. Nothing on the form fixes that on its own. Send the account address and
    the domain to [support@pipelime.ai](mailto:support@pipelime.ai).
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Sender settings" icon="sliders-horizontal" href="/en/email-accounts/sender-settings">
    Every other field on this account's form, and what each one accepts.
  </Card>

  <Card title="Sender statuses" icon="circle-dot" href="/en/email-accounts/sender-statuses">
    Active, Paused and Error, and what stops an account that is none of them.
  </Card>

  <Card title="Campaigns report" icon="chart-line" href="/en/analytics/campaigns-report">
    Where the open and click rates on your tracked links show up.
  </Card>

  <Card title="Fix a sender in Error: reconnect" icon="rotate-cw" href="/en/email-accounts/reconnect-a-sender">
    What Reconnect actually re-tests, including this domain.
  </Card>
</CardGroup>
