Skip to main content

Subdomain API

Kuploy provides free *.kuploy.app subdomains for your applications. This API allows kuploy-cloud instances to provision and manage subdomains programmatically.

For Tenants

This documentation is for tenant operators integrating subdomain provisioning into their kuploy-cloud instances. End users typically interact with subdomains through the application UI, not directly via this API.

Overview

The subdomain API enables:

  • Checking subdomain availability
  • Reserving subdomains for instances
  • Provisioning DNS records
  • Releasing subdomains when no longer needed

All endpoints require authentication via your license key.

Configuration

Your kuploy-cloud instance should have these environment variables configured:

VariableDescription
LICENSE_HUB_URLBase URL of the kuploy-app instance (e.g., https://kuploy.app)
LICENSE_KEYYour license key from kuploy-app

Base URL

The subdomain API is available at:

{LICENSE_HUB_URL}/api/subdomain

For example: https://kuploy.app/api/subdomain

Authentication

All requests must include your LICENSE_KEY as the licenseKey in the request body:

{
"licenseKey": "{LICENSE_KEY}",
...
}

Endpoints

Check Availability

Check if a subdomain name is available.

POST /api/subdomain/check

Request:

{
"name": "my-app"
}

Response (available):

{
"available": true,
"name": "my-app",
"fqdn": "my-app.kuploy.app"
}

Response (unavailable):

{
"available": false,
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"error": "This subdomain is already taken"
}

Reserve Subdomain

Reserve a subdomain for an instance. This does not create DNS records yet.

POST /api/subdomain/reserve

Request:

{
"name": "my-app",
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Response:

{
"success": true,
"subdomain": {
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"status": "pending"
}
}

Error (limit reached):

{
"success": false,
"error": "Subdomain limit reached (5). Upgrade your plan for more subdomains."
}

Provision DNS Record

Create the actual DNS record for a reserved subdomain.

POST /api/subdomain/provision

Request:

{
"subdomainId": "sub_xxxxxxxxxxxxxxxx",
"ipAddress": "203.0.113.50",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Response:

{
"success": true,
"subdomain": {
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"ipAddress": "203.0.113.50",
"status": "active"
}
}
tip

DNS propagation is typically instant since Kuploy manages the authoritative DNS for kuploy.app.

Release Subdomain

Release a subdomain and delete its DNS record.

POST /api/subdomain/release

Request:

{
"subdomainId": "sub_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Response:

{
"success": true,
"message": "Subdomain my-app.kuploy.app has been released"
}

List Subdomains

List all subdomains for an instance.

POST /api/subdomain/list

Request:

{
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Response:

{
"success": true,
"subdomains": [
{
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"ipAddress": "203.0.113.50",
"status": "active",
"provisionedAt": "2025-01-10T12:00:00Z",
"createdAt": "2025-01-10T11:55:00Z"
}
]
}

Subdomain Status

StatusDescription
pendingReserved but DNS not yet provisioned
activeDNS record created and live
suspendedTemporarily disabled
releasedPreviously used, now available

Subdomain Naming Rules

Subdomains must follow these rules:

  • Length: 3-63 characters
  • Characters: Lowercase letters, numbers, and hyphens only
  • Format: Cannot start or end with a hyphen
  • Uniqueness: Must be unique across all Kuploy users

Reserved Names

The following subdomain names are reserved and cannot be used:

www, app, api, admin, mail, smtp, pop, imap, ftp, ssh,
ns1, ns2, dns, test, dev, staging, prod, production,
beta, alpha, status, help, support, docs, blog, cdn,
static, assets, media, images, img, dashboard, billing,
account, login, signup, register, auth, oauth, sso, kuploy

Error Codes

HTTP StatusErrorDescription
400INVALID_SUBDOMAINName doesn't meet naming rules
400INVALID_IPInvalid IPv4 address format
403LIMIT_REACHEDSubdomain limit for plan exceeded
404NOT_FOUNDSubdomain or instance not found
409ALREADY_TAKENSubdomain already reserved by another user

Integration Example

Here's a typical flow for provisioning a subdomain:

const LICENSE_HUB_URL = process.env.LICENSE_HUB_URL;
const LICENSE_KEY = process.env.LICENSE_KEY;

// 1. Check availability
const check = await fetch(`${LICENSE_HUB_URL}/api/subdomain/check`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'my-app' })
});
const { available } = await check.json();

if (!available) {
throw new Error('Subdomain not available');
}

// 2. Reserve the subdomain
const reserve = await fetch(`${LICENSE_HUB_URL}/api/subdomain/reserve`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'my-app',
instanceId: 'inst_xxx',
licenseKey: LICENSE_KEY
})
});
const { subdomain } = await reserve.json();

// 3. Provision DNS (once you know the IP)
const provision = await fetch(`${LICENSE_HUB_URL}/api/subdomain/provision`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
subdomainId: subdomain.id,
ipAddress: '203.0.113.50',
licenseKey: LICENSE_KEY
})
});

// Subdomain is now live at my-app.kuploy.app

Rate Limits

API requests are rate-limited per license:

OperationLimit
Check availability60/minute
Reserve/Provision/Release10/minute
List subdomains30/minute

Exceeding limits returns HTTP 429 with a Retry-After header.