{"status": "success", "data": {"name": "VoltHost Developer API", "version": "v1", "domain": "volthost.pro", "base": "https://api.volthost.pro", "auth": "Authorization: Bearer vh_live_<secret>", "scope": "developer", "docs": {"catalog": "https://api.volthost.pro/v1", "openapi": "https://api.volthost.pro/v1/openapi.json", "website": "https://docs.volthost.pro", "markdown": "https://docs.volthost.pro/"}, "notes": ["Это API для разработчиков: каталог, баланс, свои серверы и заказы.", "Токен привязан к аккаунту; чужие ресурсы недоступны (404).", "Создание и продление серверов списывают средства с баланса по цене каталога VoltHost.", "Недостаточно средств → 402 insufficient_funds; просроченный сервер → 402 expired.", "Провайдер железа скрыт — снаружи это API VoltHost.", "Versioning: все пути под /v1/… (ломающие изменения → /v2).", "Envelope: {status:success|error, data, error, request_id} (кроме /health и openapi.json).", "Idempotency-Key на POST /v1/servers, /renew, /topups (must-have).", "Async create: POST /v1/servers {\"async\":true} → 202 + job_id; GET /v1/jobs/{id}.", "Rate limit: per-user + per-IP → 429 rate_limited (см. API_RATE_LIMIT_RPM).", "Webhooks: HMAC-SHA256, exponential retry, deliveries log, POST …/deliveries/{id}/replay.", "Billing: reserve(=charge) → provision → confirm; rollback(=refund) on fail.", "Idempotency-Key: stored response + TTL (see reliability.idempotency.ttl_sec).", "Audit: GET /v1/audit/logs — кто создал/удалил сервер, rotate token, topup."], "roles": {"user": "владелец prepaid-аккаунта (Telegram + API)", "api-client": "Bearer-токен с scopes на аккаунте user"}, "scopes": ["*", "account:read", "audit:read", "billing:read", "billing:write", "catalog:read", "servers:read", "servers:write", "tokens:write", "webhooks:write"], "webhook_events": ["balance.low", "balance.topup", "billing.success", "server.created", "server.deleted", "server.expired", "server.failed", "server.ready", "server.renewed"], "billing": {"model": "prepaid_balance", "currency": "RUB", "states": ["active", "suspended", "overdue"], "create_flow": "reserve(=charge) → create → confirm(=server/job); refund on provider fail", "create_charges": true, "renew_charges": true, "price_source": "catalog_quote", "atomic_charge": true, "freeze_on_expire": true, "auto_renew": true, "auto_resume_on_topup": true, "transactions": {"endpoint": "GET /v1/account/transactions", "fields": ["transaction_id", "kind", "type", "status", "amount_rub"], "ledger_status": "success (posted)", "pending_status_on": "topups.status = pending|paid|failed"}}, "reliability": {"idempotency_header": "Idempotency-Key", "idempotency": {"header": "Idempotency-Key", "stores_response": true, "ttl_sec": 86400, "replay_header": "Idempotent-Replayed", "endpoints": ["POST /v1/servers", "POST /v1/servers/{id}/renew", "POST /v1/topups"], "same_key_same_body": "replay cached response", "same_key_different_body": "409 idempotency_conflict"}, "job_queue": true, "async_create": "body.async=true | ?async=true | Prefer: respond-async", "ownership": "strict — чужой id → 404 (anti-IDOR/BOLA)", "response_envelope": true, "api_version": "v1", "rate_limit": {"per_user_rpm": 120, "per_ip_rpm": 360, "error_code": "rate_limited", "error_code_alias": "RATE_LIMIT_EXCEEDED", "http": 429, "headers": ["X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset", "Retry-After"]}, "audit_log": {"endpoints": ["GET /v1/audit", "GET /v1/audit/logs", "GET /v1/logs"], "tracks": ["server.create|delete|renew", "token.*", "webhook.*", "topup.create"]}, "webhooks": {"hmac": "X-VoltHost-Signature", "retry": "exponential backoff, up to 8 attempts", "logs": "GET /v1/webhooks/{id}/deliveries", "replay": "POST /v1/webhooks/{id}/deliveries/{delivery_id}/replay", "disable": "DELETE /v1/webhooks/{id}"}, "quotas": {"max_servers_per_user": true}, "billing_reserve": "reserve(=charge) → provision → confirm; rollback(=refund) on fail"}, "guarantees": {"async_jobs": "POST /v1/servers async → 202 + job; GET /v1/jobs/{id}", "idempotency": "Idempotency-Key stored+replay, TTL 86400s", "billing_atomic": "reserve → provision → confirm|rollback", "webhooks": "HMAC + exponential retry + delivery log + replay", "rate_limits": "429 rate_limited (=RATE_LIMIT_EXCEEDED) + X-RateLimit-*", "audit_logs": "GET /v1/audit/logs", "versioning": "/v1/*", "anti_idor": "owned_server / get_user_* → 404 cross-account"}, "maturity": {"level": "stripe_lite_ready", "score": "9.5/10", "must_have": {"async_jobs": "done", "idempotency_ttl": "done", "billing_reserve_confirm": "done", "webhook_retry_replay": "done", "rate_limits_contract": "done", "audit_logs": "done"}, "nice_to_have": {"scopes_rotate_revoke": "done", "quotas": "done", "invoices": "done", "sdk_js_python": "planned", "sandbox_test_keys": "planned", "templates": "planned", "snapshots_backup": "planned", "soft_delete_restore": "planned", "reseller_white_label": "planned"}}, "access": {"developer_api": ["account", "catalog", "servers", "jobs", "orders", "topups", "tokens", "webhooks", "audit"]}, "endpoints": {"meta": {"GET /health": "healthcheck", "GET /v1": "этот каталог", "GET /v1/openapi.json": "OpenAPI 3.0"}, "account": {"GET /v1/account": "профиль", "GET /v1/account/balance": "баланс", "GET /v1/account/transactions": "транзакции"}, "catalog": {"GET /v1/catalog": "regions+plans+os", "GET /v1/catalog/regions": "локации", "GET /v1/catalog/regions/{id}": "локация", "GET /v1/catalog/plans": "тарифы (?region_id=)", "GET /v1/catalog/plans/{id}": "тариф", "GET /v1/catalog/os": "ОС", "GET /v1/catalog/os/{id}": "ОС", "POST /v1/catalog/quote": "цена {plan_id,period_months?}"}, "servers": {"GET /v1/servers": "список (?page&limit&status&region_id&lifecycle)", "POST /v1/servers": "создать {plan_id,region_id,os_id,period_months?,async?}", "POST /v1/servers/bulk-delete": "массовое удаление {ids:[]}", "GET /v1/servers/{id}": "сервер", "PATCH /v1/servers/{id}": "label / auto_renew", "DELETE /v1/servers/{id}": "удалить", "POST /v1/servers/{id}/actions": "lifecycle {action}", "POST /v1/servers/{id}/start": "запуск", "POST /v1/servers/{id}/stop": "стоп", "POST /v1/servers/{id}/reboot": "reboot", "POST /v1/servers/{id}/reinstall": "reinstall {os_id?}", "POST /v1/servers/{id}/renew": "продление", "POST /v1/servers/{id}/sync": "синхронизация IP/статуса", "GET /v1/servers/{id}/credentials": "SSH root/password"}, "jobs": {"GET /v1/jobs": "очередь задач", "GET /v1/jobs/{id}": "статус job (queued|running|succeeded|failed|retry)"}, "orders": {"GET /v1/orders": "заказы", "GET /v1/orders/{id}": "заказ"}, "billing": {"GET /v1/topups": "пополнения", "POST /v1/topups": "crypto invoice {amount_rub}", "GET /v1/topups/{id}": "пополнение", "GET /v1/billing/invoices": "invoices (из ledger)"}, "tokens": {"GET /v1/tokens": "API-токены", "POST /v1/tokens": "создать {name?,scopes?,allowed_ips?}", "POST /v1/tokens/{id}/rotate": "ротация секрета", "DELETE /v1/tokens/{id}": "отозвать"}, "webhooks": {"GET /v1/webhooks": "подписки", "POST /v1/webhooks": "создать {url,events?}", "DELETE /v1/webhooks/{id}": "отключить", "GET /v1/webhooks/{id}/deliveries": "лог доставки", "GET /v1/webhooks/{id}/logs": "alias → deliveries", "POST /v1/webhooks/{id}/deliveries/{delivery_id}/replay": "replay delivery", "POST /v1/webhooks/deliveries/{delivery_id}/replay": "replay by delivery id"}, "audit": {"GET /v1/audit": "журнал действий", "GET /v1/audit/logs": "alias → /v1/audit", "GET /v1/logs": "alias → /v1/audit"}}, "edge_cases": {"provider_timeout_on_create": "charge refunded → provider_error", "duplicate_create": "send Idempotency-Key", "payment_ok_service_pending": "topup claimed once; server.ready via webhook", "partial_success": "use GET /v1/servers/{id} + /sync; check request_id", "api_spam": "429 rate_limited (user + IP)", "invalid_state": "402 expired / 400 invalid_*"}}, "error": null, "request_id": "301dc22f621042e4"}