Custom tracking domains
Serve short-link redirects and ingestion from your own subdomain instead of api.retidal.com, via Cloudflare custom hostnames or NS delegation.
A custom tracking domain lets Short links redirects and
event ingestion resolve under your own subdomain (e.g. track.yourbrand.com) instead of
api.retidal.com — useful for first-party cookie durability and brand consistency in ad
destination URLs.
This is the tracking domain, not the email sending domain
This page covers GET /api/projects/{projectId}/domains and POST /api/projects/{projectId}/domains, the tracking-traffic custom domain. Retidal also
has a separate email sending domain feature (GET /api/projects/{projectId}/email/domains) for deliverability (SPF/DKIM) — that is a
different feature with its own onboarding flow, not covered here. Don’t point one at
the other’s DNS setup.
Prerequisites
Section titled “Prerequisites”- Ownership of the subdomain you want to onboard, and (for
ns_delegationmode) the ability to update your registrar’s nameserver records for that subdomain.
Authentication
Section titled “Authentication”Every /api/projects/{projectId}/domains... endpoint on this page is a Management API
call — host https://retidal.com, authenticated with the trackly_session cookie from a
logged-in console user, not a project API key. The redirect endpoint itself
(GET https://api.retidal.com/s/{code}, used to verify a domain in the last step below) is
the separate Ingestion API — see Authentication for the full
two-API split.
Listing and creating domains
Section titled “Listing and creating domains”GET https://retidal.com/api/projects/{projectId}/domainsPOST https://retidal.com/api/projects/{projectId}/domainshostnamebodystringrequiredThe subdomain to onboard, 3–255 characters (e.g. track.yourbrand.com).
displayNamebodystringrequiredA human-readable label shown in the console.
onboardingModebodystringcloudflare_custom_hostname (Cloudflare manages the hostname directly) or
ns_delegation (you delegate the subdomain’s nameservers to Retidal’s Route53 zone).
POST /api/projects/{projectId}/domains returns 409 if the hostname is already
occupied by another domain record.
Console → Projects → Settings → Domains is where a domain is created and its provisioning status tracked end to end.
Provisioning
Section titled “Provisioning”Which provisioning call you make depends on onboardingMode:
POST https://retidal.com/api/projects/{projectId}/domains/{id}/cloudflare/provisionFor cloudflare_custom_hostname domains — provisions the Cloudflare-managed custom
hostname. POST /api/projects/{projectId}/domains/{id}/cloudflare/provision returns
400 if called on an ns_delegation domain, or if the domain’s current state doesn’t
allow provisioning yet.
POST https://retidal.com/api/projects/{projectId}/domains/{id}/route53/provisionFor ns_delegation domains — provisions the Route53 hosted zone and returns the
nameservers you must point your registrar at. POST /api/projects/{projectId}/domains/{id}/route53/provision returns 400 if called on a
cloudflare_custom_hostname domain.
Refreshing and verifying (optional)
Section titled “Refreshing and verifying (optional)”POST https://retidal.com/api/projects/{projectId}/domains/{id}/cloudflare/refreshPOST https://retidal.com/api/projects/{projectId}/domains/{id}/route53/verifycloudflare/refresh re-checks a Cloudflare-mode domain’s hostname status. route53/verify
checks whether your registrar’s NS delegation has propagated and, once it has, triggers
the one-shot Cloudflare hostname supply that finishes an ns_delegation domain’s setup.
Domain detail and deletion (optional)
Section titled “Domain detail and deletion (optional)”GET https://retidal.com/api/projects/{projectId}/domains/{id}DELETE https://retidal.com/api/projects/{projectId}/domains/{id}DELETE /api/projects/{projectId}/domains/{id} retires the Cloudflare hostname before
soft-deleting the record — it returns 502 if the Cloudflare-side retire call fails, so
a failed delete does not silently leave an orphaned hostname pointed at Retidal.
What this unlocks
Section titled “What this unlocks”A verified custom domain lets short links redirect from
your own host, so ad destination URLs carry your brand instead of api.retidal.com. The
redirect sets a host-only cookie on that subdomain, which improves attribution continuity
for repeat visits on the same device.
It does not link devices. A custom domain’s cookie is scoped to that host and is not
shared with your site; connecting a phone to a laptop still depends entirely on both
calling identify with the same userId — see
cross-device attribution.
Verify it worked
Section titled “Verify it worked”Confirm domain status
Console → Projects → Settings → Domains shows the domain’s status directly. Equivalently, from a browser session already logged into the console (so the
trackly_sessioncookie is sent automatically):bash curl -s https://retidal.com/api/projects/{projectId}/domains/{id} \-H "Cookie: trackly_session=$SESSION_COOKIE"# expect: 200 with the domain's status showing fully provisioned — Cloudflare# hostname active, or Route53 delegation verifiedConfirm redirects resolve on the custom hostname
bash curl -s -o /dev/null -D - https://api.retidal.com/s/{code} | grep -i location# expect: HTTP/2 302 — repeat the same request against your own provisioned# subdomain instead of api.retidal.com and confirm it redirects identically# (see Short links)
If it doesn’t work
Section titled “If it doesn’t work”- If DNS/TLS provisioning never completes and nothing sent through the domain arrives at all, work through Events not arriving.
- If you’re stuck mid-setup with no single clear symptom yet (nameservers not showing as delegated, hostname status stuck pending), work through the health checklist.
Worked example
Section titled “Worked example”Onboarding track.example-brand.com via NS delegation:
{ "hostname": "track.example-brand.com", "displayName": "Example Brand — Tracking", "onboardingMode": "ns_delegation"}{ "ok": true, "nameServers": [ "ns-1234.awsdns-12.org", "ns-567.awsdns-34.com", "ns-890.awsdns-56.net", "ns-345.awsdns-78.co.uk" ]}Point track.example-brand.com’s nameservers at the four values returned above at your
registrar, then call route53/verify to confirm delegation and trigger the final
Cloudflare hostname supply.
Guardrails
Section titled “Guardrails”DNS propagation is not instant — calling route53/verify before your registrar has
actually applied the nameserver change reads as stuck provisioning, not a Retidal
failure; re-check after normal DNS TTL windows (often up to 24–48 hours) before treating
it as broken. Separately, deleting a domain (DELETE /api/projects/{projectId}/domains/{id}) retires the Cloudflare hostname first — if that
retire call fails, the whole delete fails with 502 rather than leaving an
orphaned hostname silently pointed at Retidal after the record is gone from your
console.
Next steps
Section titled “Next steps”Redirect through your custom domain once it’s provisioned.
Keep destination URLs on-brand end to end.