ZeroBot REST API
Programmatically manage authorized domains, custom rules, traffic logs, IP allow/blocklists, your shortener links, and your private hosting (buy, change domain, allowed countries, Under Attack mode, subdomains, cPanel login, visitor logs). Test any endpoint live from this page — paste your license key in the top bar, fill in the parameters, and click Send Request.
Quick Start
- Grab your license key from your dashboard and paste it into the key field at the top right — it's saved locally and reused for every test on this page.
- Send it as
Authorization: Bearer YOUR_LICENSE_KEYon every API request, or use theX-License-Keyheader /?license=query parameter. - All responses use the same envelope:
{ "status": "ok", "data": ..., "meta": ... }. - Errors return
{ "status": "error", "message": "..." }with a matching HTTP status code. - Lists are paginated via
?page=1&per_page=25.
Open AntiBot Check
Lightweight external API for IP intelligence and bot detection. Pass an IP and optionally a domain and User-Agent. Returns IP classification (VPN, Tor, Datacenter), ISP, geolocation, and a bot verdict — without requiring custom rules.
Parameters
| ipREQUIRED string | IP address to check. |
| domainREQUIRED string | An authorized domain on your account. Required. |
| useragent string | Visitor User-Agent string for bot pattern detection. |
| vpn integer | 1 = block VPN (default), 0 = allow. |
| datacenter integer | 1 = block datacenter (default), 0 = allow. |
| residential_proxy integer | 1 = block residential-proxy IPs, 0 = allow (default).Warning: residential-proxy IPs are shared with real users — blocking can affect legitimate visitors. |
curl https://api.zerobot.info/v3/openapi -G --data-urlencode "ip=185.220.101.1" --data-urlencode "domain=https://example.com" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"const res = await fetch("https://api.zerobot.info/v3/openapi?" +
new URLSearchParams({
ip: "185.220.101.1",
domain: "https://example.com"
}), {
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" }
});
const data = await res.json();r = requests.get("https://api.zerobot.info/v3/openapi",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
params={
"ip": "185.220.101.1",
"domain": "https://example.com"
})
{
"username": "aBcDeFgHiJk...",
"asn": "AS15169",
"country_name": "United States",
"isp": "Google LLC",
"is_bot": false,
"reason": "ISP",
"risk_score": 0,
"vpn": false,
"tor": false,
"datacenter": false,
"residential_proxy": false
}Account stats & usage
Returns the authenticated user's account info, plan, quota, lifetime/24h/7d traffic counters, and resource counts (domains, rules, whitelist, blacklist, links). The fastest way to power a "Status" widget in your own app.
Errors
curl https://api.zerobot.info/v3/account/stats \
-H "Authorization: Bearer YOUR_LICENSE_KEY"const res = await fetch("https://api.zerobot.info/v3/account/stats", {
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" }
});
const { data } = await res.json();r = requests.get("https://api.zerobot.info/v3/account/stats",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": {
"account": {
"username": "yourname",
"plan": "Premium",
"days_left": 287
},
"quota": { "remaining": "unlimited" },
"lifetime": { "bots_blocked": 1001399, "humans_passed": 511864 },
"last_24h": { "bots": 1240, "humans": 8765 },
"resources": { "authorized_domains": 5, "custom_rules": 12 }
}
}List authorized domains
Returns a paginated list of all domains authorized for your account.
Parameters
| page integer | Page number, default 1. |
| per_page integer | Items per page (1-100), default 25. |
curl https://api.zerobot.info/v3/account/domains \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/domains", {
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" }
})requests.get("https://api.zerobot.info/v3/account/domains",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
Add an authorized domain
Adds a domain to your authorized domains. Once added, you can attach rules and traffic will be tracked.
Parameters
| domainREQUIRED string | Domain to add (protocol stripped automatically). |
Errors
curl -X POST https://api.zerobot.info/v3/account/domains \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'fetch("https://api.zerobot.info/v3/account/domains", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_LICENSE_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ domain: "example.com" })
})requests.post("https://api.zerobot.info/v3/account/domains",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com"})
Remove an authorized domain
Removes a domain from your authorized list. Any rules attached to it should be deleted separately.
Parameters
| domainREQUIRED string | Domain to remove. |
curl -X DELETE https://api.zerobot.info/v3/account/domains \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'fetch("https://api.zerobot.info/v3/account/domains", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com" })
})requests.delete("https://api.zerobot.info/v3/account/domains",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com"})
List custom rules
Returns paginated custom rules. Each rule defines blocking behavior for a specific authorized domain — VPN/Tor/datacenter blocking, allowed countries/devices, risk threshold, and edge cache TTL.
curl https://api.zerobot.info/v3/account/rules \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/rules", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/rules", headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
Create a custom rule
Creates a custom rule for one of your authorized domains. The domain must already be in your authorized domains list. All fields are optional except link — only send the ones you want to set. Fields are organized into 4 groups: Basic Information, Blocking Controls, Detection & Grabber, and Analytics.
Parameters
| linkREQUIRED string | Basic Info → Antibot link / authorized domain (e.g. example.com or full URL). Domain must already be in your authorized domains list. |
| redirect_link string | Basic Info → Where blocked visitors are sent. Accepts either a full URL (e.g. https://redirect.com) or a local file uploaded to your account (e.g. page.php, blocked.html). |
| block_vpn boolean | Blocking → Block VPN traffic. |
| block_tor boolean | Blocking → Block Tor traffic. |
| block_datacenter boolean | Blocking → Block datacenter / hosting IPs. |
| block_residential_proxy boolean | Blocking → Block residential-proxy exit IPs (daily-refreshed list). Default false (allowed).⚠ Warning: these are mostly real consumer/mobile IPs (mobile carriers, home ISPs) that are only temporarily used as proxies and rotate daily — enabling this can block some real visitors. Leave off unless you accept that trade-off. |
| fingerprint_mode boolean | Blocking → Enable advanced browser fingerprint protection. |
| wildcard boolean | Blocking → Apply rule to all subdomains of the authorized domain. |
| allowed_countries string | Devices & Countries → Comma-separated ISO codes (e.g. US,GB,DE). Empty = allow all countries. |
| allowed_devices string | Devices & Countries → Comma-separated device types: desktop,mobile,tablet. Empty = allow all. |
| check_red_page boolean | Detection & Grabber → Enable Red Page checking — get a Telegram alert if your redirect link gets flagged. |
| autograbber boolean | Detection & Grabber → Enable autograbber — automatically capture URL parameters (e.g. ?email=...) and append them to the redirect. |
| autograbber_code string | Detection & Grabber → Separator character used to append captured values. Default is #. |
| views_file_name string | Analytics → Name of the views/visitors file on your server (e.g. views.php). |
| captcha_activation boolean | Captcha → Enable Cloudflare Turnstile captcha challenge. |
| captcha_key string | Captcha → Cloudflare Turnstile site key (e.g. 0x4AAAAAAA...). |
| captcha_domain string | Captcha → Captcha domain name (optional, e.g. example.com). |
| captcha_logo string | Captcha → URL to your logo for the captcha page (optional). |
| telegram_token string | Telegram → Telegram bot token for visit notifications. |
| telegram_chat_id string | Telegram → Telegram chat ID to send notifications to. |
Errors
curl -X POST https://api.zerobot.info/v3/account/rules \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{
"link": "example.com",
"redirect_link": "https://redirect.com",
"block_vpn": true,
"block_tor": true,
"block_datacenter": true,
"fingerprint_mode": true,
"allowed_countries": "US,GB,DE",
"allowed_devices": "desktop,mobile",
"captcha_activation": true,
"captcha_key": "0x4AAAAAAA..."
}'fetch("https://api.zerobot.info/v3/account/rules", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({
link: "example.com",
redirect_link: "https://redirect.com",
block_vpn: true,
block_tor: true,
block_datacenter: true,
fingerprint_mode: true,
allowed_countries: "US,GB,DE",
allowed_devices: "desktop,mobile",
captcha_activation: true,
captcha_key: "0x4AAAAAAA..."
})
})requests.post("https://api.zerobot.info/v3/account/rules",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={
"link": "example.com",
"redirect_link": "https://redirect.com",
"block_vpn": True,
"block_tor": True,
"block_datacenter": True,
"fingerprint_mode": True,
"allowed_countries": "US,GB,DE",
"captcha_activation": True,
"captcha_key": "0x4AAAAAAA..."
})
Update a custom rule
Updates one or more fields of an existing rule. Only the fields you send are modified — others stay unchanged.
Parameters
| idREQUIRED integer | ID of the rule to update. |
| block_vpn boolean | Any field from POST /v3/account/rules can be updated — send only the ones you want to change. |
curl -X PUT https://api.zerobot.info/v3/account/rules \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"id":42,"block_vpn":false,"allowed_countries":"US,CA"}'fetch("https://api.zerobot.info/v3/account/rules", {
method: "PUT",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ id: 42, block_vpn: false, allowed_countries: "US,CA" })
})requests.put("https://api.zerobot.info/v3/account/rules",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"id": 42, "block_vpn": False, "allowed_countries": "US,CA"})
Delete a custom rule
Permanently deletes a custom rule. The associated authorized domain stays intact.
Parameters
| idREQUIRED integer | ID of the rule to delete. |
curl -X DELETE https://api.zerobot.info/v3/account/rules \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"id":42}'fetch("https://api.zerobot.info/v3/account/rules", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ id: 42 })
})requests.delete("https://api.zerobot.info/v3/account/rules",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"id": 42})
Query traffic logs
Returns paginated traffic events seen by your domains. Supports filters by date range, country, bot status, and domain. Pass summary=1 to also get aggregate bot/human counts in meta.summary.
Parameters
| page integer | Page number. |
| per_page integer | Items per page (max 100). |
| from date | Start date YYYY-MM-DD. |
| to date | End date YYYY-MM-DD. |
| is_bot boolean | Filter to bots (true) or humans (false). |
| country string | ISO country code. |
| domain string | Filter by domain. |
| summary integer | Set to 1 for aggregate counts. |
curl https://api.zerobot.info/v3/account/traffic -G --data-urlencode "from=2026-04-01" --data-urlencode "to=2026-04-07" --data-urlencode "summary=1" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"const params = new URLSearchParams({ from: "2026-04-01", to: "2026-04-07", summary: 1 });
fetch("https://api.zerobot.info/v3/account/traffic?" + params, {
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" }
})requests.get("https://api.zerobot.info/v3/account/traffic",
params={"from":"2026-04-01", "summary": 1},
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
List trusted IPs
Returns paginated list of IPs in your whitelist. Whitelisted IPs always pass through, even if they would otherwise be blocked.
curl https://api.zerobot.info/v3/account/whitelist \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/whitelist", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/whitelist", headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
Add to whitelist (IP / Range / ASN)
Whitelist supports three entry types: IP, CIDR Range, and ASN. Pass any combination of single values (ip, range, asn) or arrays (ips, ranges, asns). Up to 1000 entries per call. Duplicates skipped, invalid entries reported.
Parameters
| ip string | Single IPv4/IPv6 (e.g. 8.8.8.8). |
| ips array | Array of IPs (max 1000). |
| range string | Single CIDR range (e.g. 8.8.8.0/24). |
| ranges array | Array of CIDR ranges (max 1000). |
| asn string | Single ASN (e.g. AS15169 or 15169). |
| asns array | Array of ASNs (max 1000). |
curl -X POST https://api.zerobot.info/v3/account/whitelist \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"ips":["1.2.3.4","5.6.7.8"]}'fetch("https://api.zerobot.info/v3/account/whitelist", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ ips: ["1.2.3.4"] })
})requests.post("https://api.zerobot.info/v3/account/whitelist",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"ips": ["1.2.3.4"]})
Remove from whitelist (IP / Range / ASN)
Remove entries by their type. Pass ip/ips, range/ranges, or asn/asns — same shape as POST.
curl -X DELETE https://api.zerobot.info/v3/account/whitelist \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"ip":"1.2.3.4"}'fetch("https://api.zerobot.info/v3/account/whitelist", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ ip: "1.2.3.4" })
})requests.delete("https://api.zerobot.info/v3/account/whitelist",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"ip": "1.2.3.4"})
List blocked IPs
Returns paginated list of IPs in your blacklist. Blacklisted IPs are always blocked regardless of other rules.
curl https://api.zerobot.info/v3/account/blacklist \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/blacklist", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/blacklist", headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
Add to blacklist (IP / Range / ASN)
Blacklist supports three entry types: IP, CIDR Range, and ASN. Pass any combination of single values (ip, range, asn) or arrays (ips, ranges, asns). Up to 1000 entries per call.
Parameters
| ip string | Single IPv4/IPv6 to block. |
| ips array | Array of IPs (max 1000). |
| range string | Single CIDR range (e.g. 185.220.101.0/24). |
| ranges array | Array of CIDR ranges (max 1000). |
| asn string | Single ASN to block (e.g. AS14061). |
| asns array | Array of ASNs (max 1000). |
curl -X POST https://api.zerobot.info/v3/account/blacklist \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"ips":["185.220.101.1"]}'fetch("https://api.zerobot.info/v3/account/blacklist", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ ips: ["185.220.101.1"] })
})requests.post("https://api.zerobot.info/v3/account/blacklist",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"ips": ["185.220.101.1"]})
Remove from blacklist (IP / Range / ASN)
Remove blacklist entries by their type. Pass ip/ips, range/ranges, or asn/asns.
curl -X DELETE https://api.zerobot.info/v3/account/blacklist \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"ip":"185.220.101.1"}'fetch("https://api.zerobot.info/v3/account/blacklist", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ ip: "185.220.101.1" })
})requests.delete("https://api.zerobot.info/v3/account/blacklist",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"ip": "185.220.101.1"})
List shortener links
Returns a paginated list of your shortener links. Each entry includes the full short_url ready to share.
Parameters
| page integer | Page number. |
| per_page integer | Items per page (max 100). |
| q string | Search by link path. |
curl https://api.zerobot.info/v3/account/links \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/links", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/links", headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
List private hostings
Returns your private hosting accounts with status, expiry, server, cPanel URL and user, nameservers, allowed countries, traffic counters and subdomain usage. meta.purchase tells you whether a new purchase would succeed right now: service switch, price, your balance and the free slots on the pool you would be placed on (placement.mode is private when your account was granted a private server, otherwise public).
Hosting endpoints are gated on the hosting product itself — not on your dashboard plan — and do not consume anti-bot quota. Every hosting is addressed by its primary domain (or hosting_id).
Parameters
| page integer | Page number, default 1. |
| per_page integer | Items per page (1-100), default 25. |
Errors
curl https://api.zerobot.info/v3/account/hosting \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/hosting", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting", headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": [{
"id": 239, "domain": "example.com", "status": "Active",
"end_date": "2026-10-02 15:44:48", "days_left": 20,
"server": { "id": 6, "name": "Private 4" },
"cpanel": { "url": "https://private4.example-host.com:2083/", "user": "exampl6549" },
"nameservers": ["lauryn.ns.cloudflare.com", "sullivan.ns.cloudflare.com"],
"cloudflare_linked": true,
"allowed_countries": "all",
"block_residential_proxy": false,
"traffic": { "humans": 56, "bots": 1917 },
"subdomains": { "count": 1, "max": 5 }
}],
"meta": {
"page": 1, "per_page": 25, "total": 1, "total_pages": 1,
"purchase": {
"service_enabled": true, "price": 100, "currency": "USD",
"balance": 250, "can_buy": true, "reason": null,
"placement": { "mode": "public", "free_slots": 1 }
}
}
}Buy private hosting
Creates a new private hosting account for domain and charges the hosting price from your account balance.
Placement rule. The API first checks whether your account is authorized on a private server. If it is, the hosting is created on your private server only — public servers are never used, not even when your private server is full (you get 409 instead). If your account has no private authorization, the hosting goes to the public pool. GET /v3/account/hosting → meta.purchase.placement shows which pool applies to you and its free slots.
Placement, balance and domain checks all run before anything is charged. The deduction is atomic; if provisioning fails afterwards you are refunded in full. The response carries the cPanel credentials and the nameservers to point the domain to.
⚠ Real purchase. The tester below charges your balance and provisions a real account. Check meta.purchase.can_buy first.
Parameters
| domainREQUIRED string | Domain to host, e.g. example.com. Brand-impersonation and fraud keywords are rejected. |
| server_id integer | Optional. Pick one of your private servers (ids from meta.purchase.placement.servers). A public server id is refused for accounts authorized on a private server; accounts without private authorization cannot pick a server at all. Leave empty for automatic placement. |
Errors
curl -X POST https://api.zerobot.info/v3/account/hosting \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'fetch("https://api.zerobot.info/v3/account/hosting", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com" })
})requests.post("https://api.zerobot.info/v3/account/hosting",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com"})
{
"status": "ok",
"data": {
"hosting": { "id": 240, "domain": "example.com", "status": "Active", "days_left": 30, … },
"charged": 100, "currency": "USD",
"cpanel": { "url": "https://private4.example-host.com:2083/", "user": "exampl1234", "password": "••••••••" },
"nameservers": ["lauryn.ns.cloudflare.com", "sullivan.ns.cloudflare.com"],
"next_step": "Point the domain to the nameservers above. The site goes live once DNS propagates."
}
}cPanel login for a domain
Returns the cPanel URL, username and password of the hosting behind domain, plus login_url: a one-time link that opens cPanel already logged in. It is valid for a few minutes and works once; it is null when the server could not issue a session (fall back to the credentials). Treat the whole response as a secret.
Parameters
| domainREQUIRED string | Primary domain of the hosting. hosting_id is accepted instead. |
Errors
curl https://api.zerobot.info/v3/account/hosting/cpanel -G --data-urlencode "domain=example.com" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/hosting/cpanel?domain=example.com", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting/cpanel", params={"domain": "example.com"}, headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": {
"hosting_id": 239, "domain": "example.com", "status": "Active",
"cpanel": { "url": "https://private4.example-host.com:2083/", "user": "exampl6549", "password": "••••••••" },
"login_url": "https://private4.example-host.com:2083/cpsess0123456789/login/?session=exampl6549%3a…",
"login_url_note": "One-time auto-login link: open it right away, it expires within minutes and works once."
}
}Change hosting domain
Moves the hosting from domain to new_domain. Subdomains of the old domain are removed, the cPanel primary domain is changed, the old Cloudflare zone is replaced by a new one (A records + protection route) and the new nameservers are returned. The new name passes the same brand / fraud check as a purchase. A suspended hosting cannot be changed. POST is accepted as an alias of PUT.
Parameters
| domainREQUIRED string | Current primary domain (or hosting_id). |
| new_domainREQUIRED string | New primary domain. |
Errors
curl -X PUT https://api.zerobot.info/v3/account/hosting/domain \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"old.com","new_domain":"new.com"}'fetch("https://api.zerobot.info/v3/account/hosting/domain", {
method: "PUT",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "old.com", new_domain: "new.com" })
})requests.put("https://api.zerobot.info/v3/account/hosting/domain",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "old.com", "new_domain": "new.com"})
{
"status": "ok",
"data": {
"hosting": { "id": 239, "domain": "new.com", "status": "Active", … },
"old_domain": "old.com", "new_domain": "new.com", "changed": true,
"nameservers": ["lauryn.ns.cloudflare.com", "sullivan.ns.cloudflare.com"],
"message": "Domain changed to new.com",
"note": "Subdomains of the old domain were removed. Point the new domain to the nameservers above."
}
}Allowed countries
Restricts who can reach the hosting by country. Visitors from any other country get the country denied decision and show as denied in the visitor log. Applies to the primary domain and every subdomain. Send "all" (or an empty value) to lift the restriction. Visitors whose country cannot be resolved are never denied by this rule. POST is accepted as an alias of PUT.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
| countriesREQUIRED string | array | "all", a comma-separated list ("FR,DE,US") or a JSON array of ISO 3166-1 alpha-2 codes. |
Errors
curl -X PUT https://api.zerobot.info/v3/account/hosting/countries \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","countries":"FR,DE,US"}'fetch("https://api.zerobot.info/v3/account/hosting/countries", {
method: "PUT",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com", countries: ["FR", "DE", "US"] })
})requests.put("https://api.zerobot.info/v3/account/hosting/countries",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com", "countries": "FR,DE,US"})
{
"status": "ok",
"data": {
"hosting_id": 239, "domain": "example.com",
"allowed_countries": ["FR", "DE", "US"],
"applies_to": "the primary domain and all of its subdomains"
}
}Under Attack status
Current Cloudflare security level of the hosting's zone. under_attack is true while "I'm Under Attack" mode is on (every visitor gets a JavaScript challenge before reaching the site).
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
Errors
curl https://api.zerobot.info/v3/account/hosting/under-attack -G --data-urlencode "domain=example.com" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/hosting/under-attack?domain=example.com", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting/under-attack", params={"domain": "example.com"}, headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": { "hosting_id": 239, "domain": "example.com", "under_attack": false, "security_level": "medium" }
}Under Attack on / off
Switches Cloudflare "I'm Under Attack" mode for the hosting's zone. enabled: true sets the security level to under_attack; false returns it to medium (the same two levels the dashboard switch uses). Idempotent — changed is false when the zone was already in the requested state. POST is accepted as an alias of PUT.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
| enabledREQUIRED boolean | true to turn Under Attack mode on, false to turn it off. |
Errors
curl -X PUT https://api.zerobot.info/v3/account/hosting/under-attack \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","enabled":true}'fetch("https://api.zerobot.info/v3/account/hosting/under-attack", {
method: "PUT",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com", enabled: true })
})requests.put("https://api.zerobot.info/v3/account/hosting/under-attack",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com", "enabled": True})
{
"status": "ok",
"data": { "hosting_id": 239, "domain": "example.com", "under_attack": true, "security_level": "under_attack", "changed": true }
}Residential proxy status
Whether residential-proxy blocking is enabled for this hosting domain. Applies to the primary domain and all its subdomains. Allowed by default.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
Errors
curl https://api.zerobot.info/v3/account/hosting/residential-proxy -G --data-urlencode "domain=example.com" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/hosting/residential-proxy?domain=example.com", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting/residential-proxy", params={"domain": "example.com"}, headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": { "hosting_id": 239, "domain": "example.com", "block_residential_proxy": false }
}Residential proxy block / allow
Block or allow residential-proxy exit IPs for this hosting domain (and its subdomains).block: true blocks; false allows (default).POST is accepted as an alias of PUT.
⚠ Warning: residential-proxy IPs are mostly real consumer/mobile addresses (home ISPs, mobile carriers) that rotate daily and are only temporarily used as proxies — enabling blocking can affect some legitimate visitors.
Leave off unless you accept that trade-off.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
| blockREQUIRED boolean | true to block residential-proxy traffic, false to allow it. |
Errors
curl -X PUT https://api.zerobot.info/v3/account/hosting/residential-proxy \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","block":true}'fetch("https://api.zerobot.info/v3/account/hosting/residential-proxy", {
method: "PUT",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com", block: true })
})requests.put("https://api.zerobot.info/v3/account/hosting/residential-proxy",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com", "block": True})
{
"status": "ok",
"data": { "hosting_id": 239, "domain": "example.com", "block_residential_proxy": true }
}List subdomains
Subdomains created under the hosting, with the per-hosting limit in meta.max.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
Errors
curl https://api.zerobot.info/v3/account/hosting/subdomains -G --data-urlencode "domain=example.com" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"fetch("https://api.zerobot.info/v3/account/hosting/subdomains?domain=example.com", { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting/subdomains", params={"domain": "example.com"}, headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": [
{ "id": 838, "subdomain": "shop", "full_domain": "shop.example.com", "root_domain": "example.com", "created_at": "2026-09-02 15:45:28" }
],
"meta": { "hosting_id": 239, "domain": "example.com", "count": 1, "max": 5 }
}Create subdomain
Creates a subdomain on the hosting: cPanel subdomain, proxied Cloudflare DNS record, protection route and a placeholder index page. The name passes the same brand / fraud check as a domain. The web server needs 20-30 seconds to load the new virtual host, during which it may answer 403.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
| subdomainREQUIRED string | Prefix (shop) or full name (shop.example.com). Letters, digits and hyphens. |
Errors
curl -X POST https://api.zerobot.info/v3/account/hosting/subdomains \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","subdomain":"shop"}'fetch("https://api.zerobot.info/v3/account/hosting/subdomains", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com", subdomain: "shop" })
})requests.post("https://api.zerobot.info/v3/account/hosting/subdomains",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com", "subdomain": "shop"})
{
"status": "ok",
"data": {
"subdomain": { "id": 889, "subdomain": "shop", "full_domain": "shop.example.com", "root_domain": "example.com", "created_at": "2026-09-12 13:43:32" },
"note": "DNS and protection are active. The web server needs ~20-30 seconds to load the new virtual host, during which it may answer 403."
}
}Delete subdomain
Removes the subdomain from cPanel and Cloudflare (DNS record + protection route) together with its visitor log.
Parameters
| domainREQUIRED string | Primary domain (or hosting_id). |
| subdomainREQUIRED string | Prefix or full name. subdomain_id is accepted instead. |
Errors
curl -X DELETE https://api.zerobot.info/v3/account/hosting/subdomains \
-H "Authorization: Bearer YOUR_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","subdomain":"shop"}'fetch("https://api.zerobot.info/v3/account/hosting/subdomains", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_LICENSE_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ domain: "example.com", subdomain: "shop" })
})requests.delete("https://api.zerobot.info/v3/account/hosting/subdomains",
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"},
json={"domain": "example.com", "subdomain": "shop"})
{
"status": "ok",
"data": { "full_domain": "shop.example.com", "deleted": true }
}Hosting visitors
Visitor log of a hosting domain or one of its subdomains, newest first, with the anti-bot decision for each visit (human, bot, country_denied). By default one row per IP (its latest visit) — pass unique=0 for every visit. meta.summary carries the all-time counters for the domain.
Parameters
| domainREQUIRED string | Primary domain or subdomain (shop.example.com). |
| status string | Filter: human, bot, denied (country) or blocked (bot + denied). |
| country string | Filter by ISO country code, e.g. US. |
| unique boolean | 1 (default) one row per IP; 0 every visit. |
| from date | Start date YYYY-MM-DD. |
| to date | End date YYYY-MM-DD. |
| page integer | Page number. |
| per_page integer | Items per page (max 100). |
Errors
curl https://api.zerobot.info/v3/account/hosting/visitors -G --data-urlencode "domain=example.com" --data-urlencode "status=bot" --data-urlencode "per_page=50" \
-H "Authorization: Bearer YOUR_LICENSE_KEY"const params = new URLSearchParams({ domain: "example.com", status: "bot", per_page: 50 });
fetch("https://api.zerobot.info/v3/account/hosting/visitors?" + params, { headers: { "Authorization": "Bearer YOUR_LICENSE_KEY" } })requests.get("https://api.zerobot.info/v3/account/hosting/visitors",
params={"domain": "example.com", "status": "bot", "per_page": 50},
headers={"Authorization": "Bearer YOUR_LICENSE_KEY"})
{
"status": "ok",
"data": [{
"ip": "66.29.156.92", "decision": "bot", "allowed": false,
"country": { "code": "US", "name": "United States" },
"isp": "Namecheap Inc.", "asn": "AS22612", "hostname": "nc-ph-4031.web-hosting.com",
"device": "Unknown", "browser": "Unknown",
"user_agent": "Mozilla/5.0 (compatible; ResearchScanBot/0.2)",
"path": "/", "visits": 1, "last_seen": "2026-09-12 13:29:28"
}],
"meta": {
"page": 1, "per_page": 25, "total": 290, "total_pages": 12,
"domain": "example.com", "unique": true,
"summary": { "total_visits": 1945, "unique_visitors": 290, "humans": 35, "bots": 1910, "country_denied": 0 }
}
}