Skip to main content
A custom domain route is the binding between a path on a verified custom domain and a concrete piece of content — a chatbot, a knowledge base, or a page. A custom domain on its own doesn’t route anything. Routes are how acme.com/, acme.com/support, and acme.com/docs end up serving different resources from the same hostname.

When to use a route

  • Hosting your chatbot at support.acme.com (one route, default slug).
  • Splitting one hostname into multiple destinations — acme.com/help for the knowledge base, acme.com/chat for the chatbot.
  • A microsite per product, each on its own subdomain.

Path model

Every route lives on exactly one custom domain and owns exactly one slug. The full URL is https://<domain>/<slug>.
slugURLNotes
""https://acme.com/The default route. Visitors landing on the bare hostname see this.
"support"https://acme.com/supportLives at the /support path.
"docs"https://acme.com/docsLives at the /docs path.
The combination (domain_id, slug) is unique — you can’t have two routes at the same path on the same domain. To re-point a path, delete the existing route and create a new one.
Slugs are lowercase alphanumeric + hyphen only (^[a-z0-9-]*$). A small list of slugs is reserved for platform internals (api, health, _next, .well-known, etc.) and cannot be used.

Resource types

Exactly one of chatbot_id, kb_id, or page_id is set on every route, and it must match the type discriminator:
typeRequired id fieldServes
chatbotchatbot_idA chatbot.
kbkb_idA knowledge base.
pagepage_idA page.
The referenced resource must belong to the same organization as the domain — the API rejects cross-org references with 400 invalid_payload.

Create a route

cURL
curl https://api.awardee.dev/v1/custom-domain-routes \
  -H "Authorization: Bearer aw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_id": "2c8a4d6f-1e3b-4d5a-9b7c-8e1f2a3b4c5d",
    "slug": "",
    "type": "chatbot",
    "chatbot_id": "8f3a9d2e-1b4c-4f5d-9e8a-7c3b2a1d0f9e",
    "is_default": true
  }'
Response
{
  "object": "custom_domain_route",
  "id": "b7e1a3c2-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
  "domain_id": "2c8a4d6f-1e3b-4d5a-9b7c-8e1f2a3b4c5d",
  "slug": "",
  "type": "chatbot",
  "chatbot_id": "8f3a9d2e-1b4c-4f5d-9e8a-7c3b2a1d0f9e",
  "kb_id": null,
  "page_id": null,
  "is_default": true,
  "url": "https://acme.com",
  "created_at": "2026-05-25T11:10:00+00:00",
  "updated_at": "2026-05-25T11:10:00+00:00"
}
The parent domain doesn’t need to be verified yet — routes can be configured up front and start serving the moment verification flips to true. POST /custom-domain-routes accepts an Idempotency-Key header so retries are safe. See Idempotency.
A domain can have at most one default route. If you create or PATCH a route with is_default: true while another route on the same domain is already the default, the request is rejected with 409. Clear is_default on the existing default route first (or move it with a single update), then set the new one.

List routes on a domain

domain_id is required — listing across every domain in an org isn’t supported.
cURL
curl "https://api.awardee.dev/v1/custom-domain-routes?domain_id=2c8a4d6f-1e3b-4d5a-9b7c-8e1f2a3b4c5d" \
  -H "Authorization: Bearer aw_live_…"
Returns every route on the domain in a single envelope — the list is bounded by (domain_id, slug) uniqueness, so pagination isn’t necessary.

Update

PATCH /custom-domain-routes/{id} accepts slug and is_default. The route type and underlying resource id are immutable — delete and recreate to re-point a path.
cURL
curl -X PATCH https://api.awardee.dev/v1/custom-domain-routes/b7e1a3c2-4d5e-6f7a-8b9c-0d1e2f3a4b5c \
  -H "Authorization: Bearer aw_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "slug": "help" }'

Delete

cURL
curl -X DELETE https://api.awardee.dev/v1/custom-domain-routes/b7e1a3c2-4d5e-6f7a-8b9c-0d1e2f3a4b5c \
  -H "Authorization: Bearer aw_live_…"
Returns 204 No Content. The parent domain and the underlying chatbot/kb/page are untouched — only the binding is removed.
Deleting a route makes its URL fall through. If it was the default route (slug ""), the bare hostname returns the platform’s “domain configured but no routes” placeholder until you add a new default.

Permissions

EndpointRequired scope
POST /custom-domain-routesdomains.manage
GET /custom-domain-routesdomains.view
GET /custom-domain-routes/{id}domains.view
PATCH /custom-domain-routes/{id}domains.manage
DELETE /custom-domain-routes/{id}domains.manage