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

# Connect a custom subdomain

> Serve your Flows from your own subdomain, such as start.example.com, with DNS, TLS and an explicit go-live step.

By default every app serves its Flows from a FloKit-hosted fallback host that looks like
`f-a1b2c3.funnels.flokitai.com`. That host works immediately and never goes away.

Connecting your own subdomain lets the same Flows run on your brand instead:

```text theme={null}
https://start.example.com/lose-weight-without-counting-calories
```

<Note>
  Use a **dedicated subdomain**, not your main website domain. Good choices are
  `start.example.com`, `go.example.com` or `try.example.com`. Pointing your apex domain
  (`example.com`) at FloKit would take over your marketing site.
</Note>

## Where to find it

1. Open [dashboard.flokitai.com/integrations](https://dashboard.flokitai.com/integrations).
2. Make sure the app selector at the top is on the app whose Flows you want to move.
3. The **Flow delivery domain** panel is the first panel on the page.

Domain changes require the **company owner** or **company admin** role. Other roles can see the
panel but not add, verify or activate a domain.

## Prerequisites

* Access to your DNS provider (Cloudflare, Route 53, GoDaddy, Namecheap and so on). FloKit never
  edits your DNS — you publish every record yourself.
* A subdomain nobody else is using. FloKit rejects a host already claimed by another app.

## Step 1 — Add the subdomain

In **Flow delivery domain**, enter the full hostname and keep **DNS routing** on
**CNAME (subdomain)**:

```text theme={null}
start.example.com
```

Select **Connect domain**. The panel now shows the domain with the status **pending dns** and the
DNS records you need to publish.

<Warning>
  The **A/ALIAS (apex)** option exists only for older apex setups. Do not pick it for a new
  subdomain — CNAME is the supported path, and apex domains are not recommended.
</Warning>

## Step 2 — Publish the ownership and routing records

Two records appear immediately. Create both at your DNS provider exactly as shown:

| Purpose   | Type    | Name                                     | Value                                        |
| --------- | ------- | ---------------------------------------- | -------------------------------------------- |
| Ownership | `TXT`   | `_flokit-verification.start.example.com` | `flokit-verification=<token from the panel>` |
| Routing   | `CNAME` | `start.example.com`                      | `edge.flokitai.com`                          |

<Warning>
  **Cloudflare users:** set the `CNAME` record to **DNS only** (grey cloud), not **Proxied**
  (orange cloud).

  A proxied record does not return a `CNAME` at all — it returns Cloudflare's own addresses — so
  FloKit's routing check can never match the target, and the domain never reaches **ready**. A
  proxied record also terminates TLS at Cloudflare, so the certificate FloKit issues for your
  hostname is never presented to visitors.
</Warning>

<Note>
  Always copy the routing target from the dashboard panel rather than from this page. The panel
  shows the value FloKit will actually verify against, which is the authoritative one.
</Note>

Copy the token from the dashboard rather than retyping it. The ownership value is unique per
domain and rotates if you remove and re-add the host.

## Step 3 — Publish the certificate record

Once FloKit sees your ownership `TXT`, it asks Google to issue a managed certificate. That produces
a **third** record, shown in the panel as a certificate `CNAME`:

```text theme={null}
CNAME  <generated name>  →  <generated target>
```

This record does not exist up front. It appears only after ownership has been recognised, so
expect to visit your DNS provider twice.

Publish it, and the domain moves to **certificate provisioning**.

## Step 4 — Wait for ready

FloKit re-checks your domain on its own in the background — you can close the dashboard, and
progress continues. **Check now** simply asks for an immediate re-check instead of waiting for the
next scheduled one.

The status field walks through:

```text theme={null}
pending dns → verifying → certificate provisioning → ready
```

Typical timing:

* DNS propagation: seconds to a few hours, depending on your provider's TTL.
* Certificate issuance: usually a few minutes after the certificate record resolves.

If a step stalls, the panel shows the specific record that is still missing, plus any error.

## Step 5 — Make it primary

Reaching **ready** means DNS, routing and TLS all work — it does **not** move your traffic. This is
deliberate: nothing switches hosts until you say so.

Select **Make primary** on the ready domain. From that moment:

* New publications and campaign destinations use the custom host.
* Your previous host keeps serving its existing URLs, so live ads and bookmarks keep working.
* The FloKit fallback host stays available and can never be deleted.

<Note>
  To roll back, select **Make primary** on the previous host. Both hosts keep serving throughout,
  so a rollback needs no DNS change and no republish.
</Note>

## Your Flow URLs

Once the domain is primary, Flows are served at a clean, human-readable path:

```text theme={null}
https://start.example.com/<flow-slug>
```

The older identifier-based URL keeps working and issues a permanent redirect:

```text theme={null}
https://start.example.com/f/<flowId>/<slug>
  → 308 → https://start.example.com/<slug>
```

Republishing a Flow keeps the same public URL — the slug is frozen when the Flow is first
published, so ad links stay valid across republishes.

## Selling Flows and Paddle

If Flows on the domain take payment, Paddle must approve the **exact** hostname before checkout
works there.

1. In Paddle, add `start.example.com` under website/domain approval.
2. Approval of `example.com` or a different subdomain does **not** cover `start.example.com`.
   Paddle rejects a checkout URL on an unapproved host.
3. Your Paddle API key needs `checkout_domain.read` for FloKit to display the approval status.

Approval in Paddle is a manual step in Paddle's own dashboard.

## Troubleshooting

**Stuck on `pending dns`.** The ownership `TXT` is not resolving publicly yet. Verify with:

```bash theme={null}
dig +short TXT _flokit-verification.start.example.com
dig +short CNAME start.example.com
```

Some providers append the zone automatically — entering `_flokit-verification.start.example.com`
can create `_flokit-verification.start.example.com.example.com`. Check the record's final name.

**Stuck on `certificate provisioning`.** The certificate `CNAME` from step 3 has not propagated, or
the routing record is proxied rather than DNS-only.

**`CUSTOM_DOMAIN_CONFLICT` when adding.** Another company or app already owns that hostname.

**`CUSTOM_DOMAIN_RESERVED`.** The hostname is a FloKit platform host and cannot be claimed.

**Removing a domain.** Removing a custom host soft-disables it and re-promotes the FloKit fallback,
so Flows keep serving. The same app can reconnect the host later by re-verifying ownership with a
freshly rotated token.
