4 months ago
I’m building a multi-tenant SaaS app, and I need help figuring out how to handle dynamic custom subdomains.
Here’s the situation:
My main web app is hosted on a custom domain connected to Railway, for example:
app.myapp.comI’d like my users to be able to connect their own subdomains to it, like:
dashboard.customer.com → CNAME → app.myapp.comWhen someone visits
dashboard.customer.com, I want Railway to serve the same app (my backend detects the tenant based on the Host header).
Right now, if I try this, I get the “Train has not arrived at the station” message — which I understand means Railway doesn’t recognize the domain until it’s manually added under Settings → Networking → Custom Domains.
That works for testing, but in production this won’t scale. I need a setup where customers can connect their own subdomains automatically (like other SaaS platforms that use wildcard or dynamic domain mapping).
So my questions are:
Does Railway support dynamic custom domains - so any CNAME pointing to my base domain is accepted automatically?
If not, is there an API or programmatic way to register new custom domains from my app when a customer adds theirs?
I’m basically trying to let customers point subdomain.theirdomain.com → app.myapp.com and have it just work, without manually adding every new domain inside Railway.
Thanks so much for any clarification or suggestions! 
4 Replies
4 months ago
Hey there! We've found the following might help you get unblocked faster:
If you find the answer from one of these, please let us know by solving the thread!
3 months ago
Any update on this please? I'm stuck.
3 months ago
Hey! I found out your question was interesting, so here is my answer :
Option 1: Wildcard Subdomains (What I Use)
Just add *.myapp.com in Railway → Settings → Custom Domains
DNS Setup:
*.myapp.com → CNAME → <your-railway-domain>.up.railway.app
*.myapp.com → CNAME → authorize.railwaydns.net
Important: If you're using Cloudflare, make sure authorize.railwaydns.net is DNS-only (gray cloud, not proxied).
In my app:
const host = req.headers.host; // "customer1.myapp.com"
const tenant = host.split('.')[0]; // "customer1"
That's it! Now customer1.myapp.com, customer2.myapp.com, etc. all work without touching Railway again.
Option 2: True Custom Domains (Their Own Domain)
If customers want dashboard.customer.com pointing to your app, you'll need to use Railway's API:
const addCustomDomain = async (domain) => {
await fetch('https://backboard.railway.app/graphql/v2', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.RAILWAY_API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `mutation customDomainCreate($input: CustomDomainCreateInput!) {
customDomainCreate(input: $input) { id domain status }
}`,
variables: {
input: {
domain,
serviceId: process.env.RAILWAY_SERVICE_ID,
environmentId: process.env.RAILWAY_ENVIRONMENT_ID
}
}
})
});
};
The flow: customer enters their domain → my backend calls Railway API → customer adds the CNAME → Railway handles SSL automatically.
My recommendation: Start with wildcards. It's zero maintenance and scales perfectly. Only add the API integration if customers really need their own branded domains.
Check out the docs here: https://docs.railway.com/guides/public-networking#wildcard-domains
Hope this helps! 
callmeal3x
Hey! I found out your question was interesting, so here is my answer :Option 1: Wildcard Subdomains (What I Use)Just add *.myapp.com in Railway → Settings → Custom DomainsDNS Setup:*.myapp.com → CNAME → <your-railway-domain>.up.railway.app *.myapp.com → CNAME → authorize.railwaydns.netImportant: If you're using Cloudflare, make sure authorize.railwaydns.net is DNS-only (gray cloud, not proxied).In my app:const host = req.headers.host; // "customer1.myapp.com" const tenant = host.split('.')[0]; // "customer1"That's it! Now customer1.myapp.com, customer2.myapp.com, etc. all work without touching Railway again.Option 2: True Custom Domains (Their Own Domain)If customers want dashboard.customer.com pointing to your app, you'll need to use Railway's API:const addCustomDomain = async (domain) => { await fetch('https://backboard.railway.app/graphql/v2', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RAILWAY_API_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ query: `mutation customDomainCreate($input: CustomDomainCreateInput!) { customDomainCreate(input: $input) { id domain status } }`, variables: { input: { domain, serviceId: process.env.RAILWAY_SERVICE_ID, environmentId: process.env.RAILWAY_ENVIRONMENT_ID } } }) }); };The flow: customer enters their domain → my backend calls Railway API → customer adds the CNAME → Railway handles SSL automatically.My recommendation: Start with wildcards. It's zero maintenance and scales perfectly. Only add the API integration if customers really need their own branded domains.Check out the docs here: https://docs.railway.com/guides/public-networking#wildcard-domainsHope this helps!
2 months ago
hey, thanks for the detailed response. But how many entries can I add through railway API? I'm sure there's a very small limit.