Generate white pages programmatically — create an order, poll its status, download the ZIP. Same engine, same prices as the website. Billed from your prepaid balance.
Keys are created from your account. You must top up your balance to at least $10 to create a key. Each generation is then charged from that balance (1 credit = $1) — no balance, nothing is generated.
Send your key as a Bearer token on every /api/v1 request:
Authorization: Bearer wl_live_xxxxxxxxxxxxxxxxxxxx
| Field | Type | Default | Notes |
|---|---|---|---|
page_type | string | landing | landing · corporate · blog |
pages | int | 3 | 1–50 pages per land |
count | int | 1 | 1–100 lands (volume pricing applies) |
niche | string | random | e.g. "solar panels". Empty = auto |
target_lang | string | en | ISO code, e.g. es, de |
geo | string | — | ISO-2 country, e.g. US, AR (real local address) |
react | bool | false | +$1/land — React source included |
curl -X POST https://white-lands.com/api/v1/generate \
-H "Authorization: Bearer $WL_KEY" \
-H "Content-Type: application/json" \
-d '{"page_type":"landing","pages":3,"count":5,"niche":"solar","geo":"US","target_lang":"en"}'
Response:
{
"ok": true,
"order_id": 412,
"cost_usd": 23,
"balance_after_usd": 77,
"count": 5,
"status": "queued",
"poll": "/api/v1/orders/412"
}
Poll every ~20–30s. When status is done, downloads holds signed ZIP links (valid 30 days).
curl https://white-lands.com/api/v1/orders/412 \
-H "Authorization: Bearer $WL_KEY"
{
"order_id": 412,
"status": "done", // queued | generating | done | failed
"downloads": [
{"slug":"solar-grid-x9", "url":"https://white-lands.com/api/delivery/solar-grid-x9?t=..."}
]
}
curl https://white-lands.com/api/v1/balance -H "Authorization: Bearer $WL_KEY"
{ "balance_usd": 77 }
import requests, time
H = {"Authorization": "Bearer " + WL_KEY}
B = "https://white-lands.com"
r = requests.post(f"{B}/api/v1/generate",
headers=H, json={"page_type":"landing","pages":3,"count":1,"geo":"US"}).json()
oid = r["order_id"]
print("order", oid, "cost $", r["cost_usd"])
while True:
s = requests.get(f"{B}/api/v1/orders/{oid}", headers=H).json()
print(s["status"])
if s["status"] in ("done","failed"): break
time.sleep(30)
for d in s.get("downloads", []):
print("download:", d["url"])
count). A 3-page landing starts at a few dollars; blogs cost more. Check the live cost in the cost_usd field — it's deducted at order time, before generation.
| Code | Meaning |
|---|---|
401 | Missing / invalid / revoked key |
402 | Insufficient balance for this order |
400 | Bad parameters (type/size/count) |
404 | Order not found (or not yours) |
429 | Rate limit (60 generations / hour / key) |