DNS
Read a workspace's DNS zones and manage the records in them.
A domain bought through the workspace gets a live DNS zone on Simplifyd Cloud's nameservers. Every call on this page takes a workspace token (sk_ws_…) with the dns scope. A project token (sk_proj_…) is refused.
You don't need these calls to send a domain to a service. Add the domain to the service, and the records it needs are written to the zone for you, as platform records.
Throughout this page:
BASE = https://api.cloud.simplifyd.com/v1/workspaces/{workspace}/dns/zones{workspace} | The workspace's id. See how resources are addressed. |
{zone} | A zone's id, the slug from list zones. Not its name. |
{record} | A record's id, the slug from list records. |
Endpoints
| Method | Path | What it does |
|---|---|---|
GET | {BASE} | Lists the workspace's zones |
GET | {BASE}/{zone} | One zone |
POST | {BASE}/{zone}/check | Looks for a pending zone's delegation now |
GET | {BASE}/{zone}/records | Lists a zone's records |
POST | {BASE}/{zone}/records | Adds a record |
PUT | {BASE}/{zone}/records/{record} | Replaces a record |
DELETE | {BASE}/{zone}/records/{record} | Deletes a record |
A token cannot add or delete a zone. Removing a zone takes its domain offline, so both are done by a person signed in to the console.
List zones
GET {BASE}curl "$BASE" -H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN"const response = await fetch(BASE, {
headers: { Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}` },
});
const { zones } = await response.json();
const zone = zones.find((z) => z.name === 'acme.io');client := cloud.NewClient(cloud.WithToken(os.Getenv("SIMPLIFYD_WORKSPACE_TOKEN")))
dns := client.Workspace(workspace).DNS()
list, err := dns.Zones(ctx)
// list.Zones, list.NameserversResponse
200 OK
{
"zones": [
{
"slug": "0192f3d4-2c3d-7e11-a2b3-6e7f8a9b0c12",
"name": "acme.io",
"status": "active",
"nameservers": ["taiwo.ns.simplifyd.net", "kehinde.ns.simplifyd.net"],
"activated_at": "2026-10-14T09:30:00Z",
"created_at": "2026-10-14T09:30:00Z"
}
],
"nameservers": ["taiwo.ns.simplifyd.net", "kehinde.ns.simplifyd.net"]
}| Field | Description |
|---|---|
slug | The zone's id, for the calls below. |
name | The domain. |
status | active when it is being served, pending until the domain is delegated to the nameservers. A domain bought through the workspace is active from the start. |
nameservers | Where the domain must be delegated. |
activated_at | When it went live. Absent while pending. |
last_checked_at | When a pending zone's delegation was last looked up. Absent otherwise. |
Get a zone
GET {BASE}/{zone}curl "$BASE/$ZONE_ID" -H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN"const response = await fetch(`${BASE}/${zoneId}`, {
headers: { Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}` },
});
const { zone } = await response.json();zone, err := dns.Zone(ctx, zoneID)Response
200 OK with { "zone": { ... } }, the zone as listed.
Check a zone
POST {BASE}/{zone}/checkLooks up a pending zone's delegation now, and activates the zone if it points at the nameservers. Pending zones are also checked in the background. An active zone is returned as it is.
curl -X POST "$BASE/$ZONE_ID/check" -H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN"const response = await fetch(`${BASE}/${zoneId}/check`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}` },
});
const { zone } = await response.json();zone, err := dns.CheckZone(ctx, zoneID)Response
200 OK with { "zone": { ... } }. A zone that is still pending is not an error.
List records
GET {BASE}/{zone}/recordsReturns the zone's records, including the platform records Simplifyd Cloud manages.
curl "$BASE/$ZONE_ID/records" -H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN"const response = await fetch(`${BASE}/${zoneId}/records`, {
headers: { Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}` },
});
const { records } = await response.json();records, err := dns.Records(ctx, zoneID)Response
200 OK
{
"records": [
{
"slug": "0192f3d4-3d4e-7f22-b3c4-7f8a9b0c1d23",
"name": "@",
"type": "MX",
"ttl": 300,
"value": "mail.acme.io",
"priority": 10,
"owner": "user",
"created_at": "2026-10-14T09:40:00Z",
"updated_at": "2026-10-14T09:40:00Z"
}
]
}| Field | Description |
|---|---|
slug | The record's id. |
name | Relative to the zone: @ for the domain itself, www, *.api. |
type | A, AAAA, CNAME, ALIAS, MX, TXT, SRV, CAA or NS. |
ttl | In seconds. |
value | See the record body. |
priority | An MX's preference or an SRV's priority. Absent otherwise. |
owner | user, or platform for a record Simplifyd Cloud manages. A platform record can be read but not changed. |
managed_by | What wrote a platform record. Absent otherwise. |
Add a record
POST {BASE}/{zone}/records
Content-Type: application/jsonA record in an active zone is served once the call returns. If the nameservers refuse it, it isn't saved and the call fails.
Body
| Field | Description | |
|---|---|---|
type | Required | A, AAAA, CNAME, ALIAS, MX, TXT, SRV, CAA or NS. |
value | Required | An IP address for A and AAAA. A hostname for CNAME, ALIAS, MX and NS. The text as it should read for TXT, up to 4,096 characters. weight port target for SRV. flags tag "value" for CAA. |
name | Optional | www, *.api, or in full, www.acme.io. Empty or @ means the domain itself. |
ttl | Optional | 60 to 86400 seconds. Defaults to 300. |
priority | MX and SRV | Required for MX and SRV, ignored otherwise. |
A CNAME cannot be at the domain itself (use ALIAS) or share a name with other records. An ALIAS cannot share a name with A or AAAA records. NS records can only delegate a subdomain.
curl -X POST "$BASE/$ZONE_ID/records" \
-H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"_verify","type":"TXT","value":"token=abc123"}'const response = await fetch(`${BASE}/${zoneId}/records`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: '_verify', type: 'TXT', value: 'token=abc123' }),
});
const { record } = await response.json();record, err := dns.CreateRecord(ctx, zoneID, cloud.DNSRecordInput{
Name: "_verify",
Type: "TXT",
Value: "token=abc123",
})Response
201 Created with { "record": { ... } }, the record as listed.
Change a record
PUT {BASE}/{zone}/records/{record}
Content-Type: application/jsonReplaces the record. Takes the same body as adding one, so send every field: a ttl left out goes back to 300.
curl -X PUT "$BASE/$ZONE_ID/records/$RECORD_ID" \
-H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"_verify","type":"TXT","value":"token=def456","ttl":600}'const response = await fetch(`${BASE}/${zoneId}/records/${recordId}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: '_verify', type: 'TXT', value: 'token=def456', ttl: 600 }),
});
const { record } = await response.json();record, err := dns.UpdateRecord(ctx, zoneID, recordID, cloud.DNSRecordInput{
Name: "_verify",
Type: "TXT",
Value: "token=def456",
TTL: 600,
})Response
200 OK with { "record": { ... } }.
Delete a record
DELETE {BASE}/{zone}/records/{record}curl -X DELETE "$BASE/$ZONE_ID/records/$RECORD_ID" \
-H "Authorization: Bearer $SIMPLIFYD_WORKSPACE_TOKEN"await fetch(`${BASE}/${zoneId}/records/${recordId}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${process.env.SIMPLIFYD_WORKSPACE_TOKEN}` },
});err := dns.DeleteRecord(ctx, zoneID, recordID)Response
200 OK
{ "success": true }Errors
Error responses include a message describing the failure:
{
"type": "VALIDATION_ERROR",
"message": "www already has a CNAME record, and a name can only have one"
}| Status | Meaning |
|---|---|
400 | The record is not valid or clashes with one already there; the record is a platform one; or the zone or record does not exist in this workspace. message says which. |
401 | The token is missing, malformed, deleted, or its workspace was deleted. |
403 | The token is for another workspace, lacks the dns scope, tried to add or delete a zone, or its creator can no longer change DNS. |
5xx | Our side, or the nameservers refused the change. Nothing was saved. |