Docs

Manage Domains with the Public API

Here are examples to help you manage domains using the Public API.

List Domains for a Service

Get all domains (both Railway-provided and custom) for a service:

Required
query domains($projectId: String!, $environmentId: String!, $serviceId: String!) {
  domains(
    projectId: $projectId
    environmentId: $environmentId
    serviceId: $serviceId
  ) {
    serviceDomains {
      id
      domain
      suffix
      targetPort
    }
    customDomains {
      id
      domain
      status {
        dnsRecords {
          hostlabel
          requiredValue
          currentValue
          status
        }
      }
    }
  }
}
Variables
{
  "projectId": "project-id",
  "environmentId": "environment-id",
  "serviceId": "service-id"
}

Service Domains (*.railway.app)

Create a Service Domain

Generate a Railway-provided domain:

Required
mutation serviceDomainCreate($input: ServiceDomainCreateInput!) {
  serviceDomainCreate(input: $input) {
    id
    domain
  }
}
Variables
{
  "input": {
    "serviceId": "service-id",
    "environmentId": "environment-id"
  }
}

Delete a Service Domain

Required
mutation serviceDomainDelete($id: String!) {
  serviceDomainDelete(id: $id)
}
Variables
{
  "id": "service-domain-id"
}

Custom Domains

Check Domain Availability

Check if a custom domain can be added:

Required
query customDomainAvailable($domain: String!) {
  customDomainAvailable(domain: $domain) {
    available
    message
  }
}
Variables
{
  "domain": "api.example.com"
}

Add a Custom Domain

Required
mutation customDomainCreate($input: CustomDomainCreateInput!) {
  customDomainCreate(input: $input) {
    id
    domain
    status {
      dnsRecords {
        hostlabel
        requiredValue
        status
      }
    }
  }
}
Variables
{
  "input": {
    "projectId": "project-id",
    "environmentId": "environment-id",
    "serviceId": "service-id",
    "domain": "api.example.com"
  }
}

Get Custom Domain Status

Check DNS configuration status:

Required
query customDomain($id: String!, $projectId: String!) {
  customDomain(id: $id, projectId: $projectId) {
    id
    domain
    status {
      dnsRecords {
        hostlabel
        requiredValue
        currentValue
        status
      }
      certificateStatus
    }
  }
}
Variables
{
  "id": "custom-domain-id",
  "projectId": "project-id"
}

Update a Custom Domain

Required
mutation customDomainUpdate($id: String!, $environmentId: String!, $targetPort: Int) {
  customDomainUpdate(id: $id, environmentId: $environmentId, targetPort: $targetPort)
}
Variables
{
  "id": "custom-domain-id",
  "environmentId": "environment-id",
  "targetPort": "8080"
}

Delete a Custom Domain

Required
mutation customDomainDelete($id: String!) {
  customDomainDelete(id: $id)
}
Variables
{
  "id": "custom-domain-id"
}

DNS Configuration

After adding a custom domain, you need to configure DNS records. The required records are returned in the status.dnsRecords field.

For Root Domains (example.com)

Add an A record or ALIAS record pointing to the Railway IP.

For Subdomains (api.example.com)

Add a CNAME record pointing to your Railway service domain.

DNS Record Statuses

StatusDescription
PENDINGDNS record not yet configured
VALIDDNS record is correctly configured
INVALIDDNS record is configured incorrectly

Certificate Statuses

StatusDescription
PENDINGCertificate is being issued
ISSUEDCertificate is active
FAILEDCertificate issuance failed
Edit this file on GitHubLast updated Feb 3, 2026