Reference

API Reference

xdns.wtf exposes three REST endpoints for tenant management.

Authentication

All endpoints require a Bearer token in the Authorization header.

Authorization: Bearer <ADMIN_TOKEN>

Requests with a missing or invalid token receive a 401 Unauthorized response.

Base URL

https://xdns.wtf

Endpoints

POST/api/tenantsauth required

Create a new tenant mapping, or upsert an existing one by slug. The operation is idempotent — re-posting the same slug updates the target origin.

Request body
{
  "slug": "myapp",
  "target_origin": "https://myapp.vercel.app",
  "subnet_id": "optional-group-id"
}
Fields
FieldTypeRequiredDescription
slugstringyesSubdomain slug. Lowercase alphanumeric + hyphens, 2–63 chars. Must not be reserved.
target_originstringyesTarget origin URL. Must start with http:// or https://. Private IPs blocked.
subnet_idstringnoOptional group identifier. Sets X-XDNS-Subnet header on upstream requests.
Responses
200Tenant created or updated
{
  "ok": true,
  "fqdn": "myapp.xdns.wtf",
  "target_origin": "https://myapp.vercel.app"
}
400Validation error
{ "error": "bad_slug" }
{ "error": "bad_target_origin" }
{ "error": "reserved_slug" }
{ "error": "private_origin_blocked" }
401Missing or invalid token
Unauthorized
GET/api/tenants/:slugauth required

Retrieve the full configuration of a tenant by slug.

Responses
200Tenant found
{
  "slug": "myapp",
  "target_origin": "https://myapp.vercel.app",
  "subnet_id": null,
  "status": "active",
  "created_at": 1740600000
}
404Tenant not found
{ "error": "not_found" }
401Missing or invalid token
Unauthorized
DELETE/api/tenants/:slugauth required

Remove a tenant mapping. The subdomain stops routing immediately — there is no propagation delay.

Responses
200Tenant removed
{ "ok": true }
401Missing or invalid token
Unauthorized

Error codes

CodeStatusMeaning
bad_slug400Slug fails regex or length validation
reserved_slug400Slug is on the reserved list
bad_target_origin400target_origin doesn't start with http(s)://
private_origin_blocked400target_origin resolves to a private IP range
not_found404Tenant slug doesn't exist

Slug validation rules

  • ·Regex: ^[a-z0-9-]{2,63}$
  • ·Lowercase alphanumeric characters and hyphens only
  • ·2–63 characters
  • ·Must not appear in the reserved slugs list (see Architecture docs)