Tracking Domains

Run in Postman
Import the SparkPost API as a Postman collection

Tracking domains are used in engagement tracking to report email opens and link clicks. They wrap the open pixel and all links in your emails. When clicked, these links report the event to SparkPost, then quickly forward to the intended destination. By default, the tracking domain on your account is spgo.io (eu.spgo.io for EU accounts). This API allows you to set up and manage custom tracking domains. You can also set one up from your account (EU).

As an example, say your email contains this link:

<a href="https://www.heml.io">Build responsive emails</a>

In order to track clicks on that link, we wrap it. The resulting HTML would look something like this:

<a href="http://spgo.io/e/nInKCLCf9wnO2brop7RTsg...">Build responsive emails</a>

With a custom tracking domain you can replace the domain part of the link. So if your tracking domain was click.heml.io, your HTML would look like this:

<a href="http://click.heml.io/e/nInKCLCf9wnO2brop7RTsg...">Build responsive emails</a>

Association to Sending Domains and Defaults

In order for a tracking domain to be used, it must be associated to a sending domain or set as a default. Once that is done, templates and transmissions that have open or click tracking on will automatically use the domain to wrap links. If a tracking domain is set as default, it will automatically be used with sending domains that aren't associated with a different tracking domain. Default tracking domains do not override associated tracking domains. You can set a default for each subaccount as well. SparkPost picks the first tracking domain it can find to use in this order: 1. Associated tracking domain. 2. Subaccount default. 3. Account default.

DNS

Tracking domains need to be verified via DNS. You'll need to add a CNAME record to the domain's DNS settings before it can be used or set as the default. The CNAME value can change according to the account region or HTTPS support:

ServiceCNAME valueSupports Managed HTTPSSupports HTTPS through CDN/Proxy
SparkPost US V2v2.spgo.ioYesYes
SparkPost EU V2eu.v2.spgo.ioYesYes
SparkPost USspgo.ioNoYes
SparkPost EUeu.spgo.ioNoYes
SparkPost Enterprise<tenant>.et.e.sparkpost.comNoYes

For more information and Enterprise settings go here.

Security

Tracking domains use HTTP by default. When using the Tracking Domains API, HTTPS support must be explicitly enabled. For more information, see this guide.

Subaccounts

Tracking domains can only be assigned to subaccounts on creation. They cannot be re-assigned at a later point. If assigned and verified, a tracking domain can also be set as the default for that subaccount. In order to be associated to a subaccount's sending domain, a tracking domain has to be assigned to the same subaccount.

Tracking Domain Object

Example

{
    "domain": "example.domain.com",
    "port": 443,
    "secure": true,
    "default": false,
    "uses_managed_certificate": true,
    "status": {
        "verified": false,
        "cname_status": "pending",
        "compliance_status": "pending"
    },
    "tls_certificate": {
        "issued_at": "2026-01-27T19:09:17.000Z",
        "expires_at": "2026-04-27T19:09:16.000Z",
        "error_code": null
    },
}

Request Body

domain string

Name of the tracking domain.

port number

The port used when constructing the tracking URL. 80 if secure is false, 443 if secure is true.

secure boolean, default is false

Whether the tracking URL should use HTTPS. HTTP will be used if false.

default boolean, default is false

Whether the tracking domain should be used when not explicitly associated with a sending domain. Only one default domain per account and subaccount can be set. The domain has to be verified to be set as the default.

status object

Contains status details like verification, DNS and TLS.

subaccount_id number

ID of the subaccount the tracking domain is assigned to. Not returned unless set and can only be set on creation.

uses_managed_certificate boolean

Whether a managed TLS certificate should be enabled for the domain. Read more

tls_certificate object

Contains details about the managed TLS certificate attached to the domain if present.

Request

POST /api/v1/tracking-domains
{
  "domain": "example.domain.com",
  "secure": true
}

Response

{
  "results": {
    "domain": "example.domain.com"
  }
}
{
  "errors": [
    {
      "param": "domain",
      "message": "domain is on a DNS blacklist",
      "value": "baddomain.com"
    }
  ]
}
{
  "errors": [
    {
      "message": "The tracking domain already exists"
    }
  ]
}
{
  "errors": [
    {
      "param": "domain",
      "message": "domain must be valid",
      "value": "baddomain"
    }
  ]
}

Create a Tracking Domain

POST/api/v1/tracking-domains

Request Body

domain string required

Name of the tracking domain.

secure boolean, default is false

Whether the tracking URL should use HTTPS. HTTP will be used if false.

Request

POST /api/v1/tracking-domains//verify

Response

{
  "results": {
    "verified": true,
    "cname_status": "",
    "compliance_status": "valid"
  }
}
  {
      "errors": [
          {
              "message": "HTTP request to https://example.domain.com:443 failed.  Please verify that your redirect is functioning and that your SSL certificate is valid.",
          }
      ]
  }
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}

Verify a Tracking Domain

POST/api/v1/tracking-domains/{domain}/verify

Parameters

domain string required

Initiate a check against the configured redirect for the specified tracking domain. The domain's status object is returned on success.

Request

GET /api/v1/tracking-domains/

Response

{
  "results": {
    "port": 443,
    "domain": "example.domain.com",
    "secure": true,
    "default": true,
    "status": {
      "verified": false,
      "cname_status": "pending",
      "compliance_status": "pending"
    }
  }
}
{
  "errors": [
    {
      "param": "domain",
      "message": "domain must be valid",
      "value": "baddomain"
    }
  ]
}
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}

Retrieve a Tracking Domain

GET/api/v1/tracking-domains/{domain}

Parameters

domain string required

Retrieve an existing tracking domain.

Request

PUT /api/v1/tracking-domains/
{
  "secure": true,
  "default": true
}

Response

{
  "results": {
    "domain": "example.domain.com"
  }
}
{
  "errors": [
    {
      "param": "domain",
      "message": "domain must be valid",
      "value": "baddomain"
    }
  ]
}
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}
{
  "errors": [
    {
      "message": "Tracking domain 'example.domain.com' unverified."
    }
  ]
}

Update a Tracking Domain

PUT/api/v1/tracking-domains/{domain}

Parameters

domain string required

Update the attributes of an existing tracking domain. The primary account and each subaccount can only have one default tracking domain. Setting a new default automatically unsets the current relevant default, if it exists.

Request Body

secure boolean

Whether the tracking URL should use HTTPS. HTTP will be used if false.

default boolean

Whether the tracking domain should be used when not explicitly associated with a sending domain. The domain has to be verified to be set as the default.

Request

POST /api/v1/tracking-domains//certificate/check

Response

{
  "results": {
    "domain": "example.domain.com",
    "supportsManagedCertificate": true
  }
}
{
  "errors": [
    {
      "message": "Certificate eligibility check failed"
    }
  ]
}
{
  "errors": [
    {
      "message": "Domain is not eligible for managed certificates due to Let's Encrypt policies"
    }
  ]
}
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}
{
  "errors": [
    {
      "message": "Certificate eligibility check timed out"
    }
  ]
}

Check Certificate Eligibility

POST/api/v1/tracking-domains/{domain}/certificate/check

Parameters

domain string required

Check if a tracking domain is eligible for managed TLS certificates. This is a read-only operation that queries Let's Encrypt to determine if the domain can be used with SparkPost's managed HTTPS feature. Unlike the enable endpoint, this check can be performed on unverified domains and does not modify the tracking domain configuration.

Use this endpoint before enabling managed certificates to confirm eligibility and avoid potential failures.

For more information, see the Managed HTTPS guide.

Request

POST /api/v1/tracking-domains//certificate/enable

Response

{
  "results": {
    "message": "Certificate issuance initiated for example.domain.com"
  }
}
{
  "errors": [
    {
      "message": "Domain must be verified before enabling managed certificates"
    }
  ]
}
{
  "errors": [
    {
      "message": "Managed certificates cannot be issued for this domain due to Let's Encrypt policies"
    }
  ]
}
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}
{
  "errors": [
    {
      "message": "Certificate eligibility check timed out"
    }
  ]
}

Enable Managed Certificate

POST/api/v1/tracking-domains/{domain}/certificate/enable

Parameters

domain string required

Enable managed TLS certificate for an existing tracking domain. This initiates the certificate issuance process using Let's Encrypt. The domain must be verified and point to a V2 endpoint (v2.spgo.io or eu.v2.spgo.io) before enabling managed certificates. Once enabled, SparkPost will automatically issue and renew TLS certificates for the domain.

After receiving a successful response, monitor the domain's status.tls_status field to track the certificate issuance progress. The TLS status will change from pending to valid once the certificate is successfully issued. Other TLS-related fields will also be updated automatically: uses_managed_certificate and secure will be set to true, and port will be set to 443.

For more information, see the Managed HTTPS guide.

Request

DELETE /api/v1/tracking-domains/

Response

// Empty response body
{
  "errors": [
    {
      "param": "domain",
      "message": "domain must be valid",
      "value": "baddomain"
    }
  ]
}
{
  "errors": [
    {
      "message": "resource not found"
    }
  ]
}

Delete a Tracking Domain

DELETE/api/v1/tracking-domains/{domain}

Parameters

domain string required

Delete an existing tracking domain.

Request

GET /api/v1/tracking-domains

Response

{
  "results": [
    {
      "port": 443,
      "domain": "example.domain.com",
      "secure": true,
      "default": true,
      "status": {
        "verified": false,
        "cname_status": "pending",
        "compliance_status": "pending"
      }
    },
    {
      "port": 80,
      "domain": "example2.domain.com",
      "secure": false,
      "default": false,
      "status": {
        "verified": true,
        "cname_status": "valid",
        "compliance_status": "valid"
      },
      "subaccount_id": 215
    }
  ]
}

List All Tracking Domains

GET/api/v1/tracking-domains{?default,subaccounts}

Parameters

default boolean

Restrict results to default domains when true and non-default domains when false.

subaccounts list

Comma delimited list of subaccounts to include in results.

Returns an array with all tracking domains. Each item in the array is a full tracking domain object.