Admin API: domains
Eleven Admin API methods for domains: list, add, settings, check, groups and access to them, routing to a reverse proxy node.
The API offers the same actions as the Domains section of the panel: add a domain, change its settings, run a check, collect domains into groups and route them to a node. All methods require a token with Full access («Полный доступ») (full). Authorization is described on the Admin API: overview and authorization page, and the response and error format on the Request, response and error format page.
Domain object
| Field | Type | Description |
|---|---|---|
id | string, UUID | Domain ID |
name | string | Domain name in lower case |
cloudflare | boolean | The domain was added as a domain behind Cloudflare |
dns_status | string | DNS state at the time of adding: proxied — a domain behind Cloudflare pointed to the Cloudflare network, pending — in all other cases. See health for the current state |
ssl_status | string | Internal field. See health.tls for the certificate state |
group_id | string, UUID or null | The domain's group |
group_name | string or null | Group name |
no_index | boolean | Search engines are not allowed to index the domain |
index_campaign_id | string, UUID or null | The campaign that opens at the domain root |
index_campaign | string or null | That campaign's name |
campaign_count | number | How many campaigns use the domain |
proxy_node_id | string, UUID or null | The node the domain is routed to |
blocked | boolean | The domain was found in a blocklist registry |
blocked_at | string, RFC 3339 date | When the domain was found in the registry. The field is absent if the domain is not in a registry |
blocked_source | string | Registry name or address. The field is absent if the domain is not in a registry |
health | object | Result of the last check. The field is absent until the domain has been checked |
The health block
| Field | Type | Description |
|---|---|---|
ready | boolean | true when all four stages succeeded, and for a domain behind Cloudflare proxy is also proxied |
dns, http, https, tls | object | A check stage: state — ok, warning, error or pending; message — result text; status — HTTP response code, if a response was received |
addresses | array of strings | Addresses returned by DNS. The field is absent if no addresses were received |
proxy | string | proxied — all addresses belong to the Cloudflare network, direct — not all of them. The field is absent if no addresses were received |
certificate_expires | string, RFC 3339 date | Certificate expiration date. The field is absent if no certificate was received |
checked_at | string, RFC 3339 date | Check time |
next_check_at | string, RFC 3339 date | Time of the next automatic check |
attempts | number | Number of failed checks in a row |
What each stage message means is described on the Domain check page.
Domains
List domains
GET /api/v1/domainsReturns all of the team's domains. No parameters and no pagination.
Response — code 200 and an array of domain objects. Recently added ones come first. If there are no domains, an empty array [] is returned.
Add domains
POST /api/v1/domainsAdds one or more domains with the same settings.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Domain name. Separate several names with a comma, a space or a line break |
cloudflare | boolean | no | The domain is behind Cloudflare. Default false |
group_id | string, UUID | no | The group the domains go into |
new_group | string | no | Name of a new group. The group is created and the domains go into it. Ignored if group_id is passed |
no_index | boolean | no | Disallow indexing. Default true |
index_campaign_id | string, UUID | no | Campaign at the domain root |
Response — code 201 and an object with the items array: the added domains. The group_name, index_campaign, campaign_count and health fields are not filled in this response — read them with a list request.
Names are converted to lower case. A domain that is already in the tracker is skipped without an error and does not appear in items.
With cloudflare: true, the tracker checks where the domain's DNS points. If the domain does not point to the Cloudflare network, it is not added. If DNS does not respond yet, the domain is added with the pending status. More on the Working with Cloudflare page.
Errors:
| Code | code | When |
|---|---|---|
422 | validation | The name field is empty or the body was not parsed. The message is name is required |
422 | cloudflare_not_proxied | Some domains behind Cloudflare are not proxied. Their names are listed in the message |
400 | bad_request | group_id or index_campaign_id is not a UUID. The message is некорректный идентификатор или значение (invalid ID or value) |
If the response is 422 with the cloudflare_not_proxied code, the other domains from the request have already been added. Before repeating, request the list and send only the missing names.
Example request:
curl -X POST https://panel.example.com/api/v1/domains \
-H "Api-Key: <token>" \
-H "Content-Type: application/json" \
-d '{"name":"track.example.com","new_group":"Nutra PL","no_index":true}'Example response:
{
"items": [
{
"id": "3f2a9c1e-5b7d-4e8f-a1b2-c3d4e5f6a7b8",
"name": "track.example.com",
"ssl_status": "pending",
"dns_status": "pending",
"cloudflare": false,
"group_id": "9d8c7b6a-1f2e-4d3c-b5a4-0e9f8d7c6b5a",
"group_name": null,
"no_index": true,
"index_campaign_id": null,
"index_campaign": null,
"campaign_count": 0,
"proxy_node_id": null,
"blocked": false
}
]
}Edit a domain
PUT /api/v1/domains/{id}Changes the settings of the domain with the ID from the path. Only the fields you pass change. The domain name cannot be changed.
| Field | Type | Required | Description |
|---|---|---|---|
cloudflare | boolean | no | The domain is behind Cloudflare |
group_id | string, UUID | no | Move the domain to this group |
clear_group | boolean | no | true — remove the domain from its group. Takes precedence over group_id |
no_index | boolean | no | Disallow indexing |
index_campaign_id | string, UUID | no | Campaign at the domain root |
clear_index | boolean | no | true — remove the campaign from the domain root. Takes precedence over index_campaign_id |
null and an empty string in group_id and index_campaign_id change nothing. To clear a value, pass clear_group or clear_index.
Response — code 200 and the domain object after the change.
If after the change the domain counts as a domain behind Cloudflare, the tracker checks its DNS again. When the domain does not point to the Cloudflare network, the whole request is rejected and no field changes.
Errors:
| Code | code | When |
|---|---|---|
400 | bad_request | The body was not parsed or the ID is not a UUID |
404 | not_found | There is no domain with this ID |
422 | cloudflare_not_proxied | The domain behind Cloudflare is not proxied |
Check a domain
POST /api/v1/domains/{id}/verifyRuns the DNS, HTTP, HTTPS and certificate check and waits for it to finish. No body is needed.
Response — code 200 and an object with two fields: dns_status and health. The health format is described in The health block. Here dns_status is pending if the dns stage is not in the ok state; otherwise it is the health.proxy value: proxied or direct.
Errors:
| Code | code | When |
|---|---|---|
400 | bad_request | The ID is not a UUID |
404 | not_found | There is no domain with this ID |
409 | check_running | The domain is already being checked. Request the list in a few seconds |
429 | rate_limit | More than 20 checks per minute for the whole team. Try again in a minute |
Delete a domain
DELETE /api/v1/domains/{id}Deletes a domain. The domain does not go to the trash. Campaigns that used it are left without a domain.
Response — code 204 with no body. If there is no domain with this ID, you get 404 with the not_found code; if the ID is not a UUID, 400 with the bad_request code.
Domain groups
Groups determine which domains media buyers and designers see. More on the Domain groups and media buyer access page.
List groups
GET /api/v1/domain-groupsResponse — code 200 and an array of groups sorted by name.
| Field | Type | Description |
|---|---|---|
id | string, UUID | Group ID |
name | string | Name |
domain_count | number | Number of domains in the group |
shared_to | array of strings | IDs of the users the group is shared with |
Create a group
POST /api/v1/domain-groups| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Group name. Leading and trailing spaces are removed |
Response — code 201 and a group object with an empty shared_to and domain_count equal to 0. If name is empty or the body was not parsed — 422 with the validation code and the message name is required.
Delete a group
DELETE /api/v1/domain-groups/{id}Deletes a group. The domains stay in the tracker without a group, and users lose access to them through this group.
Response — code 204 with no body. If there is no such group, you get 404 with the not_found code; if the ID is not a UUID, 400 with the bad_request code.
Share a group with users
POST /api/v1/domain-groups/{id}/shareSets the list of users who can see the group and its domains. The list is replaced as a whole.
| Field | Type | Required | Description |
|---|---|---|---|
user_ids | array of strings, UUID | no | User IDs. An empty array or a request without the field closes the group for everyone |
IDs that are not in the team are skipped without an error. User IDs are returned by the list method on the Admin API: users page.
Response — code 204 with no body.
Errors: 400 with the bad_request code — the body was not parsed or an ID is not a UUID; 404 with the not_found code — the group does not exist.
Example request:
curl -X POST https://panel.example.com/api/v1/domain-groups/9d8c7b6a-1f2e-4d3c-b5a4-0e9f8d7c6b5a/share \
-H "Api-Key: <token>" \
-H "Content-Type: application/json" \
-d '{"user_ids":["1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"]}'Routing to a reverse proxy node
Both methods set the domain's proxied A record to the node's address through the Cloudflare account added to the tracker, and remember the binding. The node must be in the ready status. Preparation is described on the Reverse proxy nodes and Working with Cloudflare pages, and the node and account methods on the Admin API: reverse proxy nodes and Cloudflare page.
Route a domain to a node
POST /api/v1/domains/{id}/routeRoutes the domain with the ID from the path to a node.
| Field | Type | Required | Description |
|---|---|---|---|
node_id | string, UUID | yes | Node ID |
Response — code 200 and an object: ok — true, node_ip — the node's address.
Errors:
| Code | code | When |
|---|---|---|
400 | bad_request | The domain ID or node_id is not a UUID |
404 | not_found | There is no domain or node with this ID |
422 | validation | node_id was not passed or the body was not parsed |
422 | not_ready | The node is not ready. Its status is given in the message |
422 | cf_error | The A record could not be set. The cause is in the message. The text not found means the domain's zone was not found in any of the added Cloudflare accounts |
503 | disabled | Reverse proxy nodes are turned off on this installation |
Route several domains
POST /api/v1/domains/route-bulkRoutes up to 500 domains per request to one node.
| Field | Type | Required | Description |
|---|---|---|---|
node_id | string, UUID | yes | Node ID |
domain_ids | array of strings, UUID | yes | Domain IDs, from 1 to 500 |
Response — code 200, even if some domains could not be routed. Check the failed array.
| Field | Type | Description |
|---|---|---|
routed | number | How many domains were routed |
failed | array of objects | Domains that could not be routed. A domain that was not found has id and error with the text домен не найден (domain not found); the others have domain with the name and error with the cause. An empty array if all were routed |
node_ip | string | The node's address |
The errors are the same as for the previous method, except cf_error: the causes for each domain come in failed. Codes 400 and 404 refer only to the node: a domain with an invalid or unknown ID goes into failed. The validation code is also returned for an empty domain_ids and for a list longer than 500 IDs.