Status dnsafe.net ↗ Log in
Guides
Docs homeHome & PersonalMSP & BusinessAPI reference
Popular
Router setupEncrypted DNSTroubleshooting
Search docsLog in
Docs / API reference

API reference

Manage tenants, networks, rules and logs from your own tools. Every request is JSON over HTTPS.

Last updated September 2026Interactive schema: api.dnsafe.net/docs

Base URL#

Base URL
https://api.dnsafe.net/api/v1

Authentication#

Create an API key in the portal under API Keys and send it as a bearer token. The full key is shown once — keep it in a secret manager, never in a web page or app that users can download.

cURL
curl https://api.dnsafe.net/api/v1/tenants \
  -H "Authorization: Bearer $DNSAFE_API_KEY"

A key acts as the account that created it: a partner’s key can only reach that partner’s tenants. For safety, keys can’t manage API keys, billing, logins or passwords — those need a portal sign-in. Revoke a key any time from the API Keys page; it stops working immediately.

Rate limits#

TierRequests / minutePrice
Basic100$29/mo
Pro1,000$79/mo
EnterpriseUnlimited$199/mo

Over the limit you’ll get 429 Too Many Requests with a Retry-After header (seconds until the next minute starts).

Errors#

Errors return JSON with a detail message.

StatusMeaning
400Invalid request (e.g. nothing to update)
401Missing, invalid or revoked key — or the account is inactive
403Not your tenant, or an endpoint API keys can’t use
404Not found
422Validation failed — detail lists the fields
429Rate limit reached — wait for Retry-After

Tenants#

GET/tenantsAPI key · Portal login

List tenants

Every tenant your key can access, newest first.

Parameters

No parameters.
curl https://api.dnsafe.net/api/v1/tenants \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "tenants": [
    {
      "id": "3007624d-68b4-475f-91dd-9f5a798e68c9",
      "name": "Harbor Logistics",
      "active": true,
      "created_at": "2026-04-26T03:44:40Z",
      "partner_name": "Acme IT",
      "ip_count": 2,
      "rule_count": 4
    }
  ]
}
POST/tenantsAPI key · Portal login

Create a tenant

Adds a new client under your partner account.

Parameters

nameREQUIREDstringDisplay name for the client.
curl -X POST https://api.dnsafe.net/api/v1/tenants \
  -H "Authorization: Bearer $DNSAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Northwind Legal"}'
Response · 200
{
  "id": "3007624d-68b4-475f-91dd-9f5a798e68c9",
  "name": "Northwind Legal",
  "partner_id": "5f9b915d-\u2026",
  "active": true,
  "created_at": "2026-09-26T14:02:11Z"
}
GET/tenants/{tenant_id}API key · Portal login

Get a tenant

One tenant’s details.

Parameters

No parameters.
curl https://api.dnsafe.net/api/v1/tenants/$TENANT \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "id": "3007624d-68b4-475f-91dd-9f5a798e68c9",
  "name": "Harbor Logistics",
  "active": true,
  "notes": null,
  "safesearch_enforcement": false,
  "partner_id": "5f9b915d-\u2026",
  "partner_name": "Acme IT"
}
PATCH/tenants/{tenant_id}API key · Portal login

Update a tenant

Change the name, notes or SafeSearch. Send only the fields you want to change.

Parameters

namestringNew display name.
notesstringInternal notes.
safesearch_enforcementbooleanForce SafeSearch on Google, Bing and YouTube.
curl -X PATCH https://api.dnsafe.net/api/v1/tenants/$TENANT \
  -H "Authorization: Bearer $DNSAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"safesearch_enforcement": true}'
Response · 200
{
  "message": "updated"
}

Networks (IPs)#

The resolver identifies a tenant by the public IP its lookups come from. Register each office’s public IPv4 address (or a range up to /16).

GET/tenants/{tenant_id}/ipsAPI key · Portal login

List IPs

Registered networks for a tenant.

Parameters

No parameters.
curl https://api.dnsafe.net/api/v1/tenants/$TENANT/ips \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "ips": [
    {
      "id": "a41e\u2026",
      "client_ip": "203.0.113.10",
      "note": "Main office",
      "created_at": "2026-09-20T10:00:00Z"
    }
  ]
}
POST/tenants/{tenant_id}/ipsAPI key · Portal login

Register an IP

Starts filtering lookups from this network within a few minutes.

Parameters

client_ipREQUIREDstringPublic IPv4 address or CIDR, e.g. 203.0.113.10 or 203.0.113.0/28.
notestringLabel shown in the portal.
curl -X POST https://api.dnsafe.net/api/v1/tenants/$TENANT/ips \
  -H "Authorization: Bearer $DNSAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_ip": "203.0.113.10", "note": "Main office"}'
Response · 200
{
  "id": "a41e\u2026",
  "client_ip": "203.0.113.10",
  "note": "Main office",
  "created_at": "2026-09-26T14:02:11Z"
}
DELETE/tenants/{tenant_id}/ips/{ip_id}API key · Portal login

Remove an IP

Stops filtering for that network.

Parameters

No parameters.
curl -X DELETE https://api.dnsafe.net/api/v1/tenants/$TENANT/ips/$IP_ID \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "message": "deleted"
}

Rules#

GET/tenants/{tenant_id}/rulesAPI key · Portal login

List rules

All allow/block rules on a tenant, A→Z by domain.

Parameters

actionstringFilter: block or allow.
searchstringDomain contains…
curl "https://api.dnsafe.net/api/v1/tenants/$TENANT/rules?action=block" \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "rules": [
    {
      "id": "b1c4\u2026",
      "domain": "tiktok.com",
      "action": "block",
      "note": null,
      "days": 31,
      "time_start": "08:00:00",
      "time_end": "15:00:00"
    }
  ]
}
POST/tenants/{tenant_id}/rulesAPI key · Portal login

Add a rule

Blocks or allows a domain (and its subdomains) for one tenant. Add days and times to make it a scheduled rule.

Parameters

domainREQUIREDstringe.g. tiktok.com — subdomains are included.
actionREQUIRED"block" | "allow"What to do with matching lookups.
daysinteger 1–127Days bitmask: Mon=1, Tue=2, Wed=4, Thu=8, Fri=16, Sat=32, Sun=64. Default 127 (every day).
time_start / time_end"HH:MM"Active window (server time, US Eastern). Overnight windows like 22:00–06:00 work. Omit for all day.
notestringShown in the portal.
curl -X POST https://api.dnsafe.net/api/v1/tenants/$TENANT/rules \
  -H "Authorization: Bearer $DNSAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "tiktok.com", "action": "block", "days": 31, "time_start": "08:00", "time_end": "15:00"}'
Response · 200
{
  "id": "b1c4\u2026",
  "domain": "tiktok.com",
  "action": "block",
  "note": null,
  "days": 31,
  "time_start": "08:00:00",
  "time_end": "15:00:00",
  "created_at": "2026-09-26T14:02:11Z"
}
POST/tenants/{tenant_id}/rules/bulkAPI key · Portal login

Bulk import

Add many rules at once. Each item takes the same fields as “Add a rule”. Duplicates are skipped.

Parameters

rulesREQUIREDarrayList of rule objects.
curl -X POST https://api.dnsafe.net/api/v1/tenants/$TENANT/rules/bulk \
  -H "Authorization: Bearer $DNSAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rules": [{"domain": "example-casino.com", "action": "block"}, {"domain": "partner-portal.com", "action": "allow"}]}'
Response · 200
{
  "imported": 2
}
DELETE/tenants/{tenant_id}/rules/{rule_id}API key · Portal login

Delete a rule

Removes one rule. To delete several, send DELETE /tenants/{{tenant_id}}/rules/bulk with {{"rule_ids": [...]}}.

Parameters

No parameters.
curl -X DELETE https://api.dnsafe.net/api/v1/tenants/$TENANT/rules/$RULE \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "message": "deleted"
}

IP groups#

Groups let part of a tenant’s network (say, a guest Wi-Fi range) have its own rules. Group rules are checked before tenant rules.

MethodPathWhat it does
GET/tenants/{tenant_id}/groupsList groups
POST/tenants/{tenant_id}/groupsCreate — {"name", "description"}
DELETE/tenants/{tenant_id}/groups/{group_id}Delete a group
GET…/groups/{group_id}/membersList member ranges
POST…/groups/{group_id}/membersAdd a range — {"cidr", "note"}
DELETE…/groups/{group_id}/members/{member_id}Remove a range
GET…/groups/{group_id}/rulesList group rules
POST…/groups/{group_id}/rulesAdd a group rule — same fields as tenant rules
DELETE…/groups/{group_id}/rules/{rule_id}Delete a group rule

Logs#

GET/tenants/{tenant_id}/logsAPI key · Portal login

Query logs

Recent DNS lookups for a tenant, newest first, with a total count for paging.

Parameters

limitinteger1–1000, default 100.
offsetintegerFor paging.
actionstringExact action recorded, e.g. block or allow.
searchstringDomain contains…
curl "https://api.dnsafe.net/api/v1/tenants/$TENANT/logs?action=block&limit=50" \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
{
  "logs": [
    {
      "id": 91822,
      "client_ip": "203.0.113.10",
      "domain": "c2-beacon.xyz",
      "action": "block",
      "logged_at": "2026-09-26T14:02:11Z"
    }
  ],
  "total": 284
}
GET/tenants/{tenant_id}/export/csvAPI key · Portal login

Export CSV

Downloads the latest 10,000 lookups as a CSV file (client IP, domain, action, time).

Parameters

No parameters.
curl https://api.dnsafe.net/api/v1/tenants/$TENANT/export/csv \
  -H "Authorization: Bearer $DNSAFE_API_KEY"
Response · 200
client_ip,domain,action,logged_at
203.0.113.10,c2-beacon.xyz,block,2026-09-26 14:02:11
Was this page helpful?