Docs
Trading domain-core API

PlanetDomains API

A calm, predictable API for domain trading: search, registration, renewals, DNS, nameservers, Cloudflare, and webhook events. Public docs stay open, while working methods are protected by token and whitelist IP.

Base URL

https://planet-project.click/api/v1

Auth

Bearer token from the bot + whitelist IP. Token creation and rotation require at least $40 balance.

Mutations

Idempotency-Key is required for register, renew, DNS, NS, bind, and batch.

Limits

10 RPS per token. If the spike is too hard, the token is temporarily blocked for 5 minutes.

Quick start

Token first, whitelist second, requests third
  1. Create a token in the bot: Profile -> API.
  2. Add the server IP that will call the API into Whitelist.
  3. Send Authorization: Bearer <token> with every protected request.
  4. Attach a unique Idempotency-Key to every mutating request.

Token and whitelist

Bearer + whitelist
Token creation, whitelist, and webhook are managed from the bot. New token issuance and rotation require at least $40 balance. An empty whitelist means the API is fully closed even with a valid token.
GET
/api/v1/account

Balance, API status, whitelist, webhook, and default config summary.

Reference
AuthBearer + whitelist
Paramsnone
Responseaccount summary
Idempotencynot required
Effectread-only
Show detailsparams / body / response / notes

Response shape

{
  "status": true,
  "result": {
    "user_id": 7,
    "balance_usd": 1.25,
    "api_enabled": true,
    "webhook_enabled": false
  }
}

Zones and pricing

GET /api/v1/zones
GET
/api/v1/zones

List available zones with register pricing, renewal pricing, and premium flags.

Reference
AuthBearer + whitelist
Paramsnone
Responsezones[]
Idempotencynot required
Effectread-only
Show detailsparams / body / response / notes

Response shape

{
  "status": true,
  "result": {
    "zones": [
      {"zone": ".click", "register_price_usd": 3.20, "renew_price_usd": 27.47, "premium": false}
    ]
  }
}

Operational notes

  • Use this method as the base for storefront pricing and calculators.

Registration

POST /api/v1/domains/register
POST
/api/v1/domains/register

Register a single domain. If config is omitted, configurator defaults are used.

Tradingconfig
AuthBearer + whitelist
Bodydomain, years?, config?
Responseorder summary
Idempotencyrequired
Effectcreates an order
Show detailsparams / body / response / notes

Request body

{
  "domain": "planet-project.click",
  "years": 1,
  "client_ref": "deal-42",
  "external_ref": "invoice-77"
}

Response shape

{
  "status": true,
  "result": {
    "domain": "planet-project.click",
    "status": "registered",
    "client_ref": "deal-42",
    "external_ref": "invoice-77"
  }
}

Errors

404 domain_not_found
The domain is missing or already taken.
422 validation_error
The payload or config is invalid.

Operational notes

  • Always attach Idempotency-Key for mutating operations.
  • client_ref and external_ref are returned in detail, list, and webhook payloads.
POST
/api/v1/domains/register/batch

Batch registration with partial success and item-level statuses.

BatchTrading
AuthBearer + whitelist
Bodyitems[]
Responsecount / success / failed / items[]
Idempotencyrequired
Effectcreates orders
Show detailsparams / body / response / notes

Request body

{
  "items": [
    {"domain": "planet-project.click", "years": 1, "client_ref": "deal-1"},
    {"domain": "planet-trade.click", "years": 1, "client_ref": "deal-2"}
  ]
}

Response shape

{
  "status": true,
  "result": {
    "count": 2,
    "success": 1,
    "failed": 1,
    "items": []
  }
}

Operational notes

  • Batch allows partial success. Read every item independently.

Batch operations

Partial success is the expected contract
Batch flows always return a result for every item. Do not rely on one top-level status and do not infer the whole request outcome from the first failure.

Batch item errors

Read per item, not by instinct
invalid_domain
The domain failed local validation.
not_available
The domain is already taken or unavailable for registration.
validation_error
The payload item contains an incompatible configuration.
request_in_progress
A request with the same Idempotency-Key is still running.

Renewals

POST /renew
POST
/api/v1/domains/{domain}/renew

Renew a single domain.

Trading
AuthBearer + whitelist
Bodyyears, client_ref?, external_ref?
Responserenewal summary
Idempotencyrequired
Effectrenews the domain
Show detailsparams / body / response / notes

Params

domain
A domain from your account.

Request body

{
  "years": 1,
  "client_ref": "renew-42"
}

Response shape

{
  "status": true,
  "result": {
    "domain": "planet-project.click",
    "status": "renewed"
  }
}

Operational notes

  • The renew path uses the same pricing logic as the bot.
POST
/api/v1/domains/renew/batch

Batch domain renewals.

BatchTrading
AuthBearer + whitelist
Bodyitems[]
Responsecount / success / failed / items[]
Idempotencyrequired
Effectrenews a domain batch
Show detailsparams / body / response / notes

Request body

{
  "items": [
    {"domain": "planet-project.click", "years": 1},
    {"domain": "planet-trade.click", "years": 1}
  ]
}

Response shape

{
  "status": true,
  "result": {
    "count": 2,
    "success": 2,
    "failed": 0,
    "items": []
  }
}

Operational notes

  • Use batch renew for reseller cycles and overnight jobs.

client_ref / external_ref

Mapping back to your system
client_ref and external_ref help map deals, invoices, and internal orders back to our response. They are stored on the order and returned in list, detail, and webhook payloads.

SDK examples

Fast integrator start
Python
import requests

r = requests.get(
    f"{BASE_URL}/account",
    headers={"Authorization": f"Bearer {TOKEN}"},
    timeout=20,
)
print(r.json())
Node.js
const response = await fetch(`${BASE_URL}/domains/search?query=planet-project.click`, {
  headers: { Authorization: `Bearer ${TOKEN}` },
});
console.log(await response.json());
PHP
$ch = curl_init(BASE_URL . "/account");
curl_setopt_array($ch, [
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . TOKEN],
  CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);

Response samples

JSON
Account
{
  "status": true,
  "result": {
    "user_id": 7,
    "balance_usd": 1.25,
    "api_enabled": true
  }
}
Domain search
{
  "status": true,
  "result": {
    "query": "planet-project.click",
    "available": false,
    "register_price_usd": 3.20
  }
}
Webhook delivery
{
  "status": true,
  "result": {
    "limit": 10,
    "count": 1,
    "items": [
      {"event_type": "domain.renewed", "attempt_number": 1, "status": "delivered", "status_code": 200}
    ]
  }
}

DNS and NS

Read and full replace
GET
/api/v1/domains/{domain}/dns

Current DNS records, nameservers, and domain mode.

Infrastructure
AuthBearer + whitelist
Pathdomain
Responserecords / nameservers / mode
Idempotencynot required
Effectread-only
Show detailsparams / body / response / notes

Params

domain
A domain from your account.

Response shape

{
  "status": true,
  "result": {
    "mode": "cloudflare",
    "records": [],
    "nameservers": ["elaine.ns.cloudflare.com", "thomas.ns.cloudflare.com"]
  }
}
PUT
/api/v1/domains/{domain}/dns

Fully replace the DNS record set through the same validator used by the bot.

Infrastructure
AuthBearer + whitelist
Bodyrecords[]
Responseupdated dns
Idempotencyrequired
Effectreplaces DNS
Show detailsparams / body / response / notes

Params

domain
A domain from your account.

Request body

{
  "records": [
    {"type": "A", "name": "@", "content": "2.26.84.230", "ttl": 300}
  ]
}

Response shape

{
  "status": true,
  "result": {
    "updated": true,
    "records": []
  }
}
PATCH
/api/v1/domains/{domain}/nameservers

Fully replace nameservers via preset_key or explicit nameservers.

Infrastructure
AuthBearer + whitelist
Bodypreset_key or nameservers
Responseupdated nameservers
Idempotencyrequired
Effectreplaces NS
Show detailsparams / body / response / notes

Params

domain
A domain from your account.

Request body

{
  "nameservers": ["ns1.example.net", "ns2.example.net"]
}

Response shape

{
  "status": true,
  "result": {
    "updated": true,
    "nameservers": ["ns1.example.net", "ns2.example.net"]
  }
}

Cloudflare bind

POST /api/v1/domains/{domain}/cloudflare/bind
POST
/api/v1/domains/{domain}/cloudflare/bind

Bind a domain to a Cloudflare profile managed in the bot.

Cloudflare
AuthBearer + whitelist
Bodycloudflare_profile_key
Responsecloudflare bind summary
Idempotencyrequired
Effectbinds Cloudflare
Show detailsparams / body / response / notes

Params

domain
A domain from your account.

Request body

{
  "cloudflare_profile_key": "default"
}

Response shape

{
  "status": true,
  "result": {
    "bound": true,
    "cloudflare_profile_key": "default"
  }
}

Errors

409 cloudflare_not_configured
The Cloudflare profile is missing or disabled.

Webhook

Webhook + delivery log
Webhook is configured from the bot and sends all supported domain events for the user. For payloads, signatures, and retries, open the dedicated webhook guide.

Errors and limits

401 / 403 / 404 / 409 / 422 / 429
The most useful model is simple: 401/403 are access issues, 404/422 are payload or ownership issues, 409 is state or config mismatch, and 429 is pacing plus backoff.

Endpoints

Compact v1 map
GET /account
Balance, whitelist, webhook, and account summary.
GET /zones
Zones and register/renew pricing.
GET /domains/search
Exact domain lookup.
POST /domains/search/batch
Batch domain search.
POST /domains/register
Single-domain registration.
POST /domains/register/batch
Batch domain registration.
POST /domains/{domain}/renew
Single-domain renew.
POST /domains/renew/batch
Batch domain renew.
GET/PUT /domains/{domain}/dns
Read and fully replace DNS.
PATCH /domains/{domain}/nameservers
Fully replace nameservers.
POST /domains/{domain}/cloudflare/bind
Bind to a Cloudflare profile.

OpenAPI

/api/v1/openapi.json

Use OpenAPI JSON for client generation, contract checks, and schema navigation.