Custom API Domains
Serve your project’s API on your own domain — api.yourproduct.com instead of api.foir.dev — so your frontend’s network traffic stays entirely on your brand.
How it works
A custom API domain is cosmetic routing. Requests through it behave exactly like requests to api.foir.dev:
- Authentication is unchanged. Every request still carries your project’s API key (and customer JWT where applicable). The domain never grants access by itself — a request without a valid key fails identically on either hostname.
- The key still selects the project. Your
pk_/sk_key is bound to its project; the domain doesn’t change that. As a safety check, the platform rejects requests whose custom domain belongs to a different project than the key’s — you can’t accidentally (or deliberately) serve project A’s data dressed as project B’s API. - Caching, rate limits, and errors are identical on both hostnames.
TLS is provisioned automatically: once your domain is verified, the first request triggers certificate issuance (Let’s Encrypt), and renewal is handled for you.
What’s served on a custom API domain
| Path | Purpose |
|---|---|
/graphql (and /graphql/ws) | The GraphQL API, including subscriptions |
/schema | Introspection for codegen |
/api/files/* | File upload endpoints |
Everything else about your integration — headers, SDK configuration, tokens — works as documented for api.foir.dev; you only change the base URL.
Setup
Register the domain yourself, either in the studio under Access → Sign-in, or by adding it to your project’s config and running foir push. You need the domains:write permission, which project admins and tenant owners hold by default.
Registering prints two DNS records to add at your DNS provider:
-
CNAME — points your domain at Foir’s edge:
Type CNAME Name api.yourproduct.com Value api-edge.foir.dev -
TXT — proves you control the domain:
Type TXT Name _foir-challenge.api.yourproduct.com Value foir-verify=<token from registration>
After adding both records (allow a few minutes for DNS propagation), the domain is verified and goes live. The first HTTPS request may take a moment while the certificate is issued; retry once and it’s warm from then on.
Who owns a hostname
Registering a hostname does not reserve it. Proving control does.
More than one project can hold a pending claim on the same hostname at once, and the first one to publish the matching _foir-challenge TXT record becomes its single verified owner. Everyone else’s claim stays pending and never issues a certificate. This means nobody can take a hostname off you by registering it first, and equally that registering early does not hold your place: add the DNS records to make the claim real.
Pending claims are cleared after seven days. If yours expires before the DNS records are in place, register it again — nothing else is lost.
Pointing your app at it
Change the base URL — nothing else:
const response = await fetch("https://api.yourproduct.com/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.NEXT_PUBLIC_FOIR_API_KEY,
},
body: JSON.stringify({ query, variables }),
});If you generate types from introspection, point codegen at https://api.yourproduct.com/schema with the same key you ship — the schema it sees is the schema that key sees (see scoped keys).
Troubleshooting
- TLS handshake fails on the very first request — certificate issuance happens on first contact with a newly verified domain. Retry after a few seconds.
403 This API domain is not bound to the key's project— the API key in the request belongs to a different project than the domain. Use the key of the project the domain was registered for.- Certificate stops renewing — almost always a removed or changed CNAME. Confirm
api.yourproduct.comstill points atapi-edge.foir.dev. - Verification says the hostname is already verified elsewhere — another project published the challenge record for it first and now owns it. If that project is also yours, remove the domain there before claiming it here.
- The domain vanished before you finished — pending claims expire after seven days. Register it again, then add the DNS records.
- Custom login domains are separate. White-label hosted login (
login.yourproduct.com) is configured per relying party viacustomDomains— see Config reference, and SPA (no backend) for what a verified login domain unlocks. An API domain, by contrast, never carries login sessions or cookies; it is header-authenticated only.