{"openapi":"3.1.0","info":{"title":"WebHotel.cloud API","version":"1.4.9","contact":{"name":"WebHotel.cloud API Support","email":"hello@webhotel.cloud","url":"https://webhotel.cloud/support"},"description":"Public API documentation for WebHotel.cloud.\n\nThis reference is written for real client developers, not just internal operators. Every live WebHotel feature documented here includes concrete workflow guidance, authentication notes, example bodies, and response shapes intended to be used directly during implementation.\n\nQuick start:\n1. Open the interactive docs at `https://api.webhotel.cloud/docs`, use Swagger at `https://api.webhotel.cloud/swagger`, or fetch the raw spec from `https://api.webhotel.cloud/openapi.json`.\n2. Create an API token from the WebHotel `/api` dashboard page for authenticated programmatic access.\n3. Send the token as `Authorization: Bearer <token>` on user/admin API calls you are authorized to use. Browser clients may still use the `connect.sid` session cookie.\n4. Use the public catalog endpoints for storefront/marketing integrations that do not require authentication.\n5. For long-running workflows such as compute provisioning, consume the documented stream endpoint so your UI can surface live progress.\n\nDocumentation conventions:\n- Auth supports API bearer tokens for programmatic calls and cookie sessions for browser calls.\n- Secret codes are treated as credentials: never embed them in public client code.\n- Admin endpoints are under `/api/admin/*`.\n- Public endpoints are safe to call without a session unless the endpoint description says otherwise.\n- Example payloads in these docs are written as copy-paste starting points for both technical and non-technical operators."},"tags":[{"name":"Documentation","description":"Public documentation and installer/feed endpoints that help integrators discover and consume the API."},{"name":"Auth","description":"Session-based authentication, current-user lookups, and client/device-abuse status."},{"name":"API Tokens","description":"Customer-managed API bearer tokens for programmatic WebHotel API access."},{"name":"Desktop App","description":"Windows desktop client bootstrap, release metadata, installers, and update-feed endpoints."},{"name":"Billing","description":"Wallet funding, Stripe portal flows, checkout confirmation, and billing activation."},{"name":"Rewards","description":"Reward point wallets, hourly earning status, redemptions, and Spin the Wheel campaigns."},{"name":"Services","description":"High-level service inventory for the signed-in customer."},{"name":"Transactions","description":"Wallet and billing transaction history."},{"name":"Tickets","description":"Support ticket creation and listing for customers."},{"name":"Search","description":"User and admin search surfaces for services, tickets, users, IPs, templates, and Pages/Workers apps."},{"name":"Compute","description":"Compute plan discovery, ordering, live provisioning streams, lifecycle actions, and console launch."},{"name":"Object Storage","description":"Ceph/NVMe and premium object storage plans, instances, credentials, S3 buckets, and access keys."},{"name":"Databases","description":"Managed PostgreSQL plans, service provisioning, customer databases, credentials, and admin support flows."},{"name":"Storage Box","description":"OpenWeb Infrastructure Storage Box plans, provisioning, credentials, usage sync, and upgrade/delete flows."},{"name":"Credentials","description":"Credential center and setup assistant endpoints for customer services."},{"name":"Backups","description":"Backup summaries and restore-oriented customer views."},{"name":"Marketing","description":"Site metadata, SEO/social generation, and marketing-related admin tooling."},{"name":"Blog","description":"Public blog content plus admin blog authoring and AI-assisted draft generation."},{"name":"DNS","description":"DNS reseller account setup, zone management, and record CRUD for customer domains."},{"name":"Pages & Workers","description":"Git-based Pages/Workers app deployment, redeploys, deployments, domains, and server management."},{"name":"Referrals","description":"Share-credit and referral bonus flows, including Facebook callback/claim handling."},{"name":"Secret Packages","description":"Secret-code package lookup, redemption, waitlist flows, and invite-only storefront access."},{"name":"Admin","description":"Cross-cutting admin actions for users, services, plans, abuse review, and pricing."},{"name":"Operations","description":"Admin operational queues, deployment locks, capacity views, smoke tests, and drift tooling."},{"name":"Provider Health","description":"Provider capacity, Proxmox health, orphan scanning, console health, and telemetry endpoints."},{"name":"Social Login","description":"Admin Google sign-in configuration and health-check endpoints."},{"name":"Email","description":"SMTP health and queued email retry endpoints."},{"name":"Proxmox Admin","description":"Administrative Proxmox inventory, node data, VM/container actions, templates, tasks, and proxy access."},{"name":"Console","description":"Browser console access for managed compute instances."},{"name":"SSO","description":"Single sign-on token exchange and redirect flow."}],"x-tagGroups":[{"name":"Public","tags":["Documentation","Auth","API Tokens","Secret Packages","Blog","Desktop App","SSO"]},{"name":"Customer API","tags":["Billing","Rewards","Services","Transactions","Tickets","Search","Compute","Object Storage","Databases","Storage Box","Credentials","Backups","DNS","Pages & Workers","Referrals"]},{"name":"Admin API","tags":["Admin","Rewards","Marketing","Operations","Provider Health","Social Login","Email","Proxmox Admin"]}],"components":{"securitySchemes":{"cookieAuth":{"type":"apiKey","in":"cookie","name":"connect.sid","description":"Session cookie created by `POST /api/auth/login` or `POST /api/auth/register`."},"bearerApiToken":{"type":"http","scheme":"bearer","bearerFormat":"WebHotel API token","description":"API token created from the WebHotel `/api` dashboard page. Send as `Authorization: Bearer <token>`."}}},"paths":{"/openapi.json":{"get":{"tags":["Documentation"],"summary":"Raw OpenAPI specification","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the machine-readable OpenAPI document used to power the public Redoc and Swagger documentation sites. Use this endpoint when generating SDKs, Postman collections, typed clients, or internal integration references.","security":[],"responses":{"200":{"description":"OpenAPI JSON","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/docs":{"get":{"tags":["Documentation"],"summary":"Public API documentation","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nOn the canonical API host, serves the public Redoc documentation site for WebHotel.cloud. This is the recommended human-readable documentation entry point for client developers and integration teams. The primary website host uses `/docs` for the user guide, so API integrations should prefer `https://api.webhotel.cloud/docs` or `/api-docs` when they need the developer reference.","security":[],"responses":{"200":{"description":"HTML documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api-docs":{"get":{"tags":["Documentation"],"summary":"Redoc API documentation","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nServes the Redoc API documentation from either the web app host or the canonical API host. This view includes quick-start guidance, authentication notes, raw OpenAPI links, Swagger navigation, and current control-panel screenshots that help developers map API payloads to the WebHotel UI.","security":[],"responses":{"200":{"description":"Redoc HTML documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/swagger":{"get":{"tags":["Documentation"],"summary":"Swagger API documentation","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nServes Swagger UI for the same latest OpenAPI specification. Use this option when you want a familiar try/explore interface with filtering, schema expansion, and endpoint discovery driven by `/openapi.json`.","security":[],"responses":{"200":{"description":"Swagger UI HTML documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/swagger-docs":{"get":{"tags":["Documentation"],"summary":"Swagger API documentation alias","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAlias for `/swagger` kept for users who search for Swagger Docs by name.","security":[],"responses":{"200":{"description":"Swagger UI HTML documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/docs/":{"get":{"tags":["Documentation"],"summary":"Public API documentation alias","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLegacy trailing-slash alias for the Redoc documentation site. Clients should prefer `/docs`.","security":[],"responses":{"301":{"description":"Redirect to /docs"}}}},"/api/auth/register":{"post":{"tags":["Auth"],"summary":"Register","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a user account and starts a session.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"company":{"type":"string"},"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"acceptTerms":{"type":"boolean"},"deviceFingerprint":{"type":"string","minLength":16},"deviceMacAddress":{"type":"string"}},"required":["firstName","lastName","email","password","acceptTerms","deviceFingerprint"],"additionalProperties":false},"example":{"firstName":"Ada","lastName":"Lovelace","company":"Analytical Engines Ltd","email":"ada@example.com","password":"CorrectHorseBatteryStaple","acceptTerms":true,"deviceFingerprint":"6f29a5b527cb4a6f96dd57c770695f22","deviceMacAddress":"c95a3c69392d4da6"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Login","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStarts a session and sets the connect.sid cookie.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}},"required":["email","password"],"additionalProperties":false},"example":{"email":"ceo@openweb.co.za","password":"********"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/auth/google/config":{"get":{"tags":["Auth"],"summary":"Google sign-in config","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns whether Google sign-in is enabled and the public Google OAuth client ID for the browser button.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"clientId":{"type":["string","null"]}},"required":["enabled","clientId"]}}}}}}},"/api/app/web-release":{"get":{"tags":["Documentation"],"summary":"Current web release","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current WebHotel web release metadata that the client uses to show user-facing changelog notes after a release.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"},"displayVersion":{"type":"string"},"summary":{"type":"string"},"bullets":{"type":"array","items":{"type":"string"}}},"required":["version","displayVersion","summary","bullets"]}}}}}}},"/api/auth/google":{"post":{"tags":["Auth"],"summary":"Login or register with Google","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAccepts a Google ID token from the browser sign-in flow. Login mode signs in an existing account. Register mode can create a new account when terms are accepted and the Google email is verified.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"credential":{"type":"string"},"intent":{"type":"string","enum":["login","register"]},"acceptTerms":{"type":"boolean"},"company":{"type":"string"},"deviceFingerprint":{"type":"string"},"deviceMacAddress":{"type":"string"}},"required":["credential","intent"],"additionalProperties":false},"example":{"credential":"google-id-token","intent":"register","acceptTerms":true,"company":"Example Ltd","deviceFingerprint":"6f29a5b527cb4a6f96dd57c770695f22"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/auth/logout":{"post":{"tags":["Auth"],"summary":"Logout","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nEnds the current session.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Current session user","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current user if logged in, otherwise null (shape may vary).","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":["object","null"],"additionalProperties":true}}}}}}},"/api/auth/recovery/request":{"post":{"tags":["Auth"],"summary":"Request password recovery email","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSends a one-click recovery email if the account exists. The response is intentionally generic so email addresses cannot be enumerated.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"additionalProperties":false},"example":{"email":"ada@example.com"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/auth/password":{"post":{"tags":["Auth"],"summary":"Set or change the current user's password","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLets an authenticated user set a direct WebHotel password. This is used by email/password users, Google-created accounts that need a direct password, and recovery-link flows after SSO signs the user in.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":8},"confirmPassword":{"type":"string","minLength":8}},"required":["password"],"additionalProperties":false},"example":{"password":"CorrectHorseBatteryStaple","confirmPassword":"CorrectHorseBatteryStaple"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/api-tokens":{"get":{"tags":["API Tokens"],"summary":"List API tokens","description":"**Authentication:** Interactive dashboard session cookie required (`connect.sid`). API bearer tokens cannot manage API tokens.\n**Content-Type:** Returns `application/json`.\n\nLists API tokens created by the current user. Token values are returned in clear text so users can refer back to them from the dashboard page; remind users not to share tokens with unauthorized people. Each token also includes scopes, optional IP allowlist entries, and lightweight usage analytics.","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token":{"type":"string"},"tokenPrefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"},"example":["compute:read","compute:write"]},"ipAllowlist":{"type":"array","items":{"type":"string"},"example":["203.0.113.10","198.51.100.0/24"]},"requestCount":{"type":"integer","example":42},"lastUsedIp":{"type":["string","null"],"example":"203.0.113.10"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","token","tokenPrefix","createdAt"]}}},"required":["tokens"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["API Tokens"],"summary":"Create API token","description":"**Authentication:** Interactive dashboard session cookie required (`connect.sid`). API bearer tokens cannot create more API tokens.\n**Content-Type:** Accepts and returns `application/json`.\n\nCreates a new API token for the current user. Use the returned token as `Authorization: Bearer <token>` for authenticated API requests. Set `scopes` for least-privilege access and `ipAllowlist` for exact IPv4/CIDR source restrictions.","security":[{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"scopes":{"type":"array","items":{"type":"string"},"description":"Use `*` for full access or values like `compute:read`, `compute:write`, `billing:read`, `webhooks:manage`, `debug:read`."},"ipAllowlist":{"type":"array","items":{"type":"string"},"description":"Optional exact IPv4 addresses or IPv4 CIDR ranges. Blank/empty allows any source IP."}},"additionalProperties":false},"example":{"name":"Production automation","scopes":["compute:read","compute:write","webhooks:manage"],"ipAllowlist":["203.0.113.10"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/api-tokens/{tokenId}":{"put":{"tags":["API Tokens"],"summary":"Update API token restrictions","description":"**Authentication:** Interactive dashboard session cookie required (`connect.sid`). API bearer tokens cannot update API tokens.\n**Content-Type:** Accepts and returns `application/json`.\n\nUpdates a token name, scopes, and/or IP allowlist. Token secret values remain visible in clear text to the token owner.","security":[{"cookieAuth":[]}],"parameters":[{"name":"tokenId","in":"path","required":true,"schema":{"type":"string"},"description":"API token id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"scopes":{"type":"array","items":{"type":"string"}},"ipAllowlist":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"example":{"scopes":["compute:read","compute:write","debug:read"],"ipAllowlist":["203.0.113.10"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"delete":{"tags":["API Tokens"],"summary":"Delete API token","description":"**Authentication:** Interactive dashboard session cookie required (`connect.sid`). API bearer tokens cannot delete API tokens.\n**Content-Type:** Returns `application/json`.\n\nPermanently deletes one API token owned by the current user. Deleted tokens immediately stop authenticating bearer-token requests.","security":[{"cookieAuth":[]}],"parameters":[{"name":"tokenId","in":"path","required":true,"schema":{"type":"string"},"description":"API token id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/abuse/me":{"get":{"tags":["Auth"],"summary":"Current abuse status","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns abuse/fraud signals for the current account/device fingerprint so clients can surface warnings consistently.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/app/bootstrap":{"get":{"tags":["Desktop App"],"summary":"Desktop bootstrap","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the Windows desktop client bootstrap payload: app metadata, current user, wallet summary, service counts, abuse status, route hints, and desktop release metadata.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"426":{"description":"Upgrade Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/app/releases/latest":{"get":{"tags":["Desktop App"],"summary":"Latest Windows desktop release","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the latest published version of WebHotel Windows, including installer URLs, the minimum supported desktop version, whether a legacy repair bridge is required for the calling client, and display metadata such as channel, summary, and changelog bullet points.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/webhotelwin.exe":{"get":{"tags":["Desktop App"],"summary":"Stable Windows desktop installer","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDownloads the current stable WebHotel Windows installer. This is the permanent URL you can place on marketing pages, onboarding emails, and in-app prompts without needing to hardcode a specific version number.","security":[],"responses":{"200":{"description":"Windows installer executable","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/desktop-updates/windows/{fileName}":{"get":{"tags":["Desktop App"],"summary":"Desktop update artifact","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDownloads a specific Windows desktop update artifact referenced by the release feed. This endpoint is primarily consumed by the WebHotel Windows client during update checks and install flows.","security":[],"parameters":[{"name":"fileName","in":"path","required":true,"schema":{"type":"string"},"description":"Installer or update-feed file name, for example `latest.yml` or `webhotelwin1.1.4.exe`."}],"responses":{"200":{"description":"Requested update artifact","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/add-funds":{"post":{"tags":["Billing"],"summary":"Add funds","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a Stripe checkout session for a wallet top-up.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","minimum":5}},"required":["amount"]},"example":{"amount":20}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/portal":{"post":{"tags":["Billing"],"summary":"Open billing portal","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a Stripe billing portal session so the user can manage their saved card and subscription.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/checkout/confirm":{"post":{"tags":["Billing"],"summary":"Confirm checkout","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nConfirms a checkout/payment intent after returning from a payment provider.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sessionId":{"type":"string"}},"required":["sessionId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/link-card":{"post":{"tags":["Billing"],"summary":"Link a card","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStarts a card-on-file setup flow.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/stripe/webhook":{"post":{"tags":["Billing"],"summary":"Stripe webhook receiver","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReceives signed Stripe webhook events for billing activation, subscription lifecycle updates, invoice failures, and top-up completion. This endpoint is intended for Stripe only; client developers normally do not call it directly.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/audit":{"get":{"tags":["Billing"],"summary":"Billing audit stream","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the user's billing audit trail, including Stripe setup events, portal returns, auto top-up outcomes, wallet debits, refunds, and admin wallet adjustments.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/status":{"get":{"tags":["Billing"],"summary":"Live billing status","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current live Stripe billing state, current month spend totals, auto-top-up settings, cap settings, and the active admin billing-cap policy.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/diff":{"get":{"tags":["Billing"],"summary":"Billing diff view","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns expected versus actual charges for the current billing month grouped by service so dashboards can explain spend drift clearly.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/settings":{"put":{"tags":["Billing"],"summary":"Update billing settings","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates auto-top-up and per-product monthly billing caps for the signed-in user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/portal/return":{"post":{"tags":["Billing"],"summary":"Record billing portal return","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRecords an explicit return from the Stripe billing portal so the billing audit trail updates immediately.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/services":{"get":{"tags":["Services"],"summary":"List services","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists compute and storage services belonging to the current user.\n\nEach service includes its current `billingMode`, legacy flat `monthlyPrice`/`hourlyPrice` fields where available, and a structured `pricing.options[]` list. Use `pricing.options[].mode` as the `billingMode` value when creating a new site/resource from a matching plan.\n\nCompute services that expose an application UI include `applicationAccess` with the relevant Hermes Agent GUI, OpenVPN Admin/Client UI, or OpenClaw UI links for API display. For Hermes Agent, display `applicationAccess.loginUrl` as the customer-facing GUI URL; it is the public `http://{hostname}/` URL, not the internal dashboard port. For OpenClaw, display the SSL-backed `https://{hostname}/` URL.\n\nAzure Windows compute services include `rdpDetails` with the public IPv4 address, port 3389, administrator username/password, and a copy-ready `mstsc` command for Remote Desktop clients.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"billingMode":{"type":"string","enum":["hourly","monthly","quarterly"]},"monthlyPrice":{"type":["string","null"]},"hourlyPrice":{"type":["string","null"]},"pricing":{"type":"object","additionalProperties":true,"properties":{"currency":{"type":"string","example":"USD"},"monthly":{"type":["string","null"],"example":"8.95"},"hourly":{"type":["string","null"],"example":"0.0311"},"options":{"type":"array","description":"Selectable billing rates. Send the chosen option's `mode` as `billingMode` when creating a service.","items":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string","enum":["monthly","hourly"]},"label":{"type":"string","example":"Monthly"},"interval":{"type":"string","enum":["month","hour"]},"price":{"type":"string","example":"8.95"},"minimumHours":{"type":"integer","minimum":1},"initialCharge":{"type":"string","example":"8.95"}},"required":["mode","label","interval","price","initialCharge"]}},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]},"note":{"type":"string"}},"required":["currency","monthly","hourly","options","billingModes","defaultBillingMode"]},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]},"applicationAccess":{"type":["object","null"],"additionalProperties":true,"properties":{"type":{"type":"string","enum":["hermes-agent","openvpn-as","openclaw"]},"label":{"type":"string"},"username":{"type":["string","null"]},"loginUrl":{"type":["string","null"]},"primaryUrl":{"type":["string","null"]},"urls":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"kind":{"type":"string"},"url":{"type":"string"}}}}}},"rdpDetails":{"type":["object","null"],"additionalProperties":true,"properties":{"label":{"type":["string","null"],"example":"Remote Desktop"},"host":{"type":["string","null"],"example":"20.87.211.87"},"ipAddress":{"type":["string","null"],"example":"20.87.211.87"},"hostname":{"type":["string","null"],"example":"win11-demo.webhotel.cloud"},"port":{"type":["number","null"],"example":3389},"connectionAddress":{"type":["string","null"],"example":"20.87.211.87:3389"},"username":{"type":["string","null"],"example":"webadmin"},"password":{"type":["string","null"],"example":"Returned in clear text to the signed-in owner"},"command":{"type":["string","null"],"example":"mstsc /v:20.87.211.87:3389"},"note":{"type":["string","null"]}}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/transactions":{"get":{"tags":["Transactions"],"summary":"Transaction log","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current user's wallet transaction log.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/rewards":{"get":{"tags":["Rewards"],"summary":"Reward wallet summary","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the signed-in user's reward point wallet, latest reward ledger entries, redemption options, qualification status, and active Spin the Wheel campaign if one is currently live.\n\nRewards are earned hourly from active paid services at 10 points per $1. Free-credit-only accounts do not earn points and cannot spin until they have loaded at least $5 of paid wallet credit, saved a Stripe card, and have an active paid service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"wallet":{"type":"object","properties":{"pointsBalance":{"type":"integer","example":2400},"lifetimeEarned":{"type":"integer","example":3200},"lifetimeRedeemed":{"type":"integer","example":800}}},"redemptionOptions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"wallet_credit_5"},"creditUsd":{"type":"number","example":5},"pointsCost":{"type":"integer","example":2000},"label":{"type":"string","example":"$5 wallet credit"}}}},"qualification":{"type":"object","additionalProperties":true},"spin":{"type":"object","additionalProperties":true},"ledger":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/rewards/ledger":{"get":{"tags":["Rewards"],"summary":"Reward ledger","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns reward point ledger entries for the signed-in user. Use the optional `limit` query parameter to request up to 500 entries.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ledger":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/rewards/redeem":{"post":{"tags":["Rewards"],"summary":"Redeem points into wallet credit","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nImmediately deducts reward points and credits the user's WebHotel wallet when the selected option is affordable. The wallet credit and a verbose transaction-log entry are written in the same database transaction.\n\nAvailable options are returned by `GET /api/rewards`. The `$5` redemption costs 2,000 points until the launch promo ends on July 31, 2026 and automatically changes to 3,000 points from August 1, 2026.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"optionId":{"type":"string","enum":["wallet_credit_5","wallet_credit_10","wallet_credit_20"]}},"required":["optionId"]},"example":{"optionId":"wallet_credit_5"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/rewards/spin":{"post":{"tags":["Rewards"],"summary":"Claim Spin the Wheel reward","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nClaims one spin from the active Spin the Wheel campaign for qualified clients. The endpoint validates that the user has loaded at least $5 of paid wallet credit, has a saved card, and has an active paid service before awarding points.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"campaignId":{"type":"string","description":"Optional active campaign id. If omitted, the newest active campaign is used."}}},"example":{"campaignId":"reward-campaign-id"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"409":{"description":"Already Claimed","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/tickets":{"get":{"tags":["Tickets"],"summary":"List tickets","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists the current user's support tickets.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["Tickets"],"summary":"Create ticket","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new support ticket.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string"},"message":{"type":"string"}},"required":["subject","message"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/public/compute/plans":{"get":{"tags":["Compute"],"summary":"Public compute plans","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists active compute plans visible to normal users. Secret-only plans are hidden from this catalog.\n\nLatest provider-aware fields:\n- `computeProvider`: `proxmox`, `google`, or `azure` for customer-facing catalogs. `azure` means Azure Spot-only provisioning.\n- `providerPlanId`: upstream provider size/profile id when the plan maps to a cloud provider.\n- `providerImageId`: upstream provider image/profile id when used by that provider.\n- `regionLabel`: human-readable location label for storefront display.\n- `pricing.options[]`: selectable monthly/hourly rates. Send the selected option's `mode` as `billingMode` to the authenticated order endpoint.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/public/object-storage/plans":{"get":{"tags":["Object Storage"],"summary":"Public object storage plans","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists active object storage plans visible to normal users (secret-only plans are hidden). Each plan includes `pricing.options[]`; authenticated clients should send the selected option's `mode` as `billingMode` when creating object storage.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/public/blog/posts":{"get":{"tags":["Blog"],"summary":"List published blog posts","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the published blog posts that should appear on the public WebHotel.cloud blog page.\n\nThis endpoint is designed for storefront use. It returns summary data only: title, slug, excerpt, cover image, and publish timestamps.\nUse it to build the blog landing page or to preview what content is currently live without exposing draft articles.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/public/blog/posts/{slug}":{"get":{"tags":["Blog"],"summary":"Get one published blog post","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the full published blog article for one public slug.\n\nUse this when rendering `/blog/:slug` pages. Draft or unpublished posts are not returned from this endpoint.\nThe response body includes the Markdown article content and all metadata needed for social previews and SEO rendering.","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Published blog slug"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/incidents":{"get":{"tags":["Services"],"summary":"List public active incidents","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns only incidents that are both public and still marked active.\n\nUse this for a public status banner, homepage status widget, or customer dashboard alert tray.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"status":{"type":"string"},"severity":{"type":"string"},"productScope":{"type":["string","null"]},"providerScope":{"type":["string","null"]},"publicVisible":{"type":"boolean"},"active":{"type":"boolean"},"startsAt":{"type":["string","null"],"format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"]},"updatedByUserId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","title","summary","status","severity","publicVisible","active","createdAt","updatedAt"],"additionalProperties":true}}}}}}}},"/api/deploy/eligibility":{"post":{"tags":["Services"],"summary":"Check deployment eligibility","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nEvaluates whether the current user can deploy a specific plan right now.\n\nThis endpoint consolidates wallet balance checks, trial restrictions, provider locks, billing-mode requirements, naming rules, and password policy checks before the actual order call.\n\nFor compute plans, send the same credential fields you intend to submit to `/api/compute/order` so the response can include credential-policy blockers and warnings.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productType":{"type":"string","enum":["compute","object_storage","storage_box","postgresql"]},"planId":{"type":"string"},"billingMode":{"type":"string","enum":["hourly","monthly"]},"name":{"type":"string"},"provider":{"type":"string","description":"Optional client-side provider hint for UI workflows."},"userChoiceUsername":{"type":"string"},"userChoicePassword":{"type":"string"},"rootPassword":{"type":"string"}},"required":["productType","planId"],"additionalProperties":false},"example":{"productType":"compute","planId":"plan_123","billingMode":"monthly","name":"snapdragon-prod-1","userChoiceUsername":"adminuser","userChoicePassword":"StrongPass!23","rootPassword":"RootPass!23"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"eligible":{"type":"boolean"},"planName":{"type":["string","null"]},"providerLabel":{"type":["string","null"]},"requiredNowUsd":{"type":"number"},"minimumRequiredUsd":{"type":"number"},"blockers":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"cardLinked":{"type":"boolean"},"creditBalanceUsd":{"type":"number"}},"required":["eligible","planName","providerLabel","requiredNowUsd","minimumRequiredUsd","blockers","warnings","cardLinked","creditBalanceUsd"],"additionalProperties":true}}}}}}},"/api/timeline":{"get":{"tags":["Services"],"summary":"Unified user timeline","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns a reverse-chronological activity stream for the signed-in user.\n\nThe timeline merges services, transactions, tickets, activity events, and billing audit events into a single feed for dashboard and account-history views.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":250,"default":80},"description":"Maximum number of timeline entries to return."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/service-templates":{"get":{"tags":["Services"],"summary":"List saved deployment blueprints","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns saved per-user deployment blueprints for supported product types.\n\nUse `productType` to filter when a UI only needs compute, object storage, Storage Box, or PostgreSQL templates.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"productType","in":"query","required":false,"schema":{"type":"string","enum":["compute","object_storage","storage_box","postgresql"]},"description":"Optional product-type filter."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Services"],"summary":"Save deployment blueprint","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStores a reusable deployment blueprint under the current user's account.\n\nThe `template` object is intentionally provider-agnostic: store the exact UI payload you want to reuse later.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productType":{"type":"string","enum":["compute","object_storage","storage_box","postgresql"]},"name":{"type":"string"},"template":{"type":"object","additionalProperties":true}},"required":["productType","name","template"],"additionalProperties":false},"example":{"productType":"compute","name":"Snapdragon Google Ubuntu","template":{"billingMode":"monthly","region":"jnb","userChoiceUsername":"adminuser"}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/service-templates/{templateId}":{"delete":{"tags":["Services"],"summary":"Delete deployment blueprint","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes one saved deployment blueprint owned by the current user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string"},"description":"Saved deployment blueprint id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/compute/available-instances":{"get":{"tags":["Compute"],"summary":"Available compute instance options","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the compute instance options the authenticated account can deploy right now.\n\nThis is the recommended endpoint for API clients that build a custom deploy screen. It is account-aware and hides choices that the user cannot currently use:\n- Accounts that have not saved a credit card and deposited at least `$5` of paid wallet credit see basic Linux Proxmox plans with `1 vCPU` and `1GB RAM` on Node A, Node B, or Johannesburg Node JHB, plus Azure Spot compute plans that can be ordered with `billingMode=hourly` while wallet credit or a saved card can cover the hourly charge. Admin accounts and accounts with admin-applied wallet credit are exempt from this restriction.\n- Free-account users only get one live Proxmox trial-limited compute slot. If that slot is already used, eligible Proxmox trial plans are hidden, but Azure Spot hourly plans can still be returned while normal wallet/card affordability checks apply.\n- Google provider plans, Azure Spot monthly/3-month billing, PostgreSQL, storage services, larger Proxmox plans, Windows Proxmox/Hermes/OpenClaw/OpenVPN plans, and capacity-hidden nodes require the paid unlock requirement or an admin/manual-credit exemption.\n- Secret-only plans and retired/internal provider plans are not returned.\n\nAzure items are returned in the same `instances[]` list as Proxmox/Google plans. Azure Spot plans include `computeProvider=azure`, Azure location in `node`, VM size in `providerPlanId`, optional marketplace/image reference in `providerImageId`, `osCategory`, and normal `pricing.options[]`. Windows 11 Azure plans require a customer administrator username/password at order time and later expose `rdpDetails`. Azure OpenClaw plans require a WebHotel subdomain service name, root password, and OpenClaw/Linux username/password; after provisioning, service details expose the SSL-backed `https://<hostname>.webhotel.cloud/` URL through `applicationAccess`.\n\nUse the `policy` block to explain the unlock rule in your UI, `usage` to show whether the free compute slot is already used, and `instances` to render deployable choices.\nEach item includes `pricing.options[]` with monthly/hourly rates. Send the selected option's `mode` as `billingMode` to `/api/compute/order`.\nA non-empty `instances` array does not bypass normal billing checks: deploy/order endpoints still verify wallet/card affordability before provisioning.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"generatedAt":{"type":"string","format":"date-time"},"message":{"type":"string"},"billingHref":{"type":"string"},"availableCount":{"type":"integer"},"policy":{"type":"object","additionalProperties":true,"properties":{"providerUnlocked":{"type":"boolean"},"paidTopupUsd":{"type":"number"},"adminWalletAdjustmentUsd":{"type":"number"},"requiredPaidTopupUsd":{"type":"number"},"walletBalanceUsd":{"type":"number"},"freeAccountAllowedProvider":{"type":"string","example":"proxmox"},"freeAccountMaxLiveComputeInstances":{"type":"integer","example":1},"cardLinked":{"type":"boolean"},"adminAccount":{"type":"boolean"},"adminCreditUnlocked":{"type":"boolean"},"freeAccountAllowedProviders":{"type":"array","items":{"type":"string"},"example":["proxmox","azure_hourly"]},"freeAccountAllowedNodes":{"type":"array","items":{"type":"string"},"example":["ns523475","ns522908","proxmoxza2"]},"freeAccountCpuSockets":{"type":"integer","example":1},"freeAccountRamMb":{"type":"integer","example":1024},"excludedProviderUntilUnlock":{"type":"array","items":{"type":"string"}}}},"usage":{"type":"object","additionalProperties":true,"properties":{"activeTrialLimitedServiceCount":{"type":"integer"},"remainingTrialLimitedServices":{"type":"integer"}}},"hiddenCounts":{"type":"object","additionalProperties":true,"properties":{"capacityUnavailable":{"type":"integer"},"accountLocked":{"type":"integer"}}},"instances":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"computeProvider":{"type":"string","enum":["proxmox","google","azure"]},"providerLabel":{"type":"string","example":"Proxmox"},"providerPlanId":{"type":["string","null"],"description":"Provider VM size/plan id. For Azure this is the Azure VM size, for example `Standard_B2ls_v2`."},"providerImageId":{"type":["string","null"],"description":"Optional provider image reference. For Azure Windows this can be a marketplace image such as `MicrosoftWindowsDesktop:windows-11:win11-25h2-pro:latest`."},"node":{"type":["string","null"],"description":"Provider location or Proxmox node. Azure uses the location slug, for example `southafricanorth`."},"osCategory":{"type":"string","enum":["linux","windows"]},"productFlavor":{"type":"string"},"productFlavorLabel":{"type":"string"},"regionCode":{"type":"string"},"regionName":{"type":"string"},"monthlyPrice":{"type":"string"},"hourlyPrice":{"type":["string","null"]},"pricing":{"type":"object","additionalProperties":true,"properties":{"currency":{"type":"string","example":"USD"},"monthly":{"type":["string","null"],"example":"8.95"},"hourly":{"type":["string","null"],"example":"0.0311"},"options":{"type":"array","description":"Selectable billing rates. Send the chosen option's `mode` as `billingMode` when creating a service.","items":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string","enum":["monthly","hourly"]},"label":{"type":"string","example":"Monthly"},"interval":{"type":"string","enum":["month","hour"]},"price":{"type":"string","example":"8.95"},"minimumHours":{"type":"integer","minimum":1},"initialCharge":{"type":"string","example":"8.95"}},"required":["mode","label","interval","price","initialCharge"]}},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]},"note":{"type":"string"}},"required":["currency","monthly","hourly","options","billingModes","defaultBillingMode"]},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]},"cpuSockets":{"type":"integer"},"ramMb":{"type":"integer"},"storageGb":{"type":"integer"},"capacityAvailable":{"type":"boolean"},"available":{"type":"boolean"},"availabilityReason":{"type":"string"},"providerRegionOptions":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}},"required":["generatedAt","message","availableCount","policy","usage","instances"]},"example":{"generatedAt":"2026-05-20T10:00:00.000Z","message":"This unfunded account can deploy one live basic 1 vCPU / 1GB RAM Proxmox Linux plan on Node A, Node B, or Johannesburg Node JHB, and can choose hourly Azure Spot while wallet credit or a saved card covers the hourly charge. Save a credit card and top up $5 to unlock the full catalog and Azure monthly billing.","billingHref":"/dashboard/billing?focus=topup","availableCount":2,"policy":{"providerUnlocked":false,"paidTopupUsd":0,"adminWalletAdjustmentUsd":0,"requiredPaidTopupUsd":5,"walletBalanceUsd":0,"cardLinked":false,"adminAccount":false,"adminCreditUnlocked":false,"freeAccountAllowedProvider":"proxmox_or_azure_hourly","freeAccountAllowedProviders":["proxmox","azure_hourly"],"freeAccountAllowedNodes":["ns523475","ns522908","proxmoxza2"],"freeAccountMaxLiveComputeInstances":1,"freeAccountCpuSockets":1,"freeAccountRamMb":1024,"excludedProviderUntilUnlock":["Google","Azure Spot monthly/3-month billing","Object Storage","Storage Box","PostgreSQL","Windows Proxmox","Hermes/OpenClaw/OpenVPN","larger Proxmox compute"]},"usage":{"activeTrialLimitedServiceCount":0,"remainingTrialLimitedServices":1},"hiddenCounts":{"capacityUnavailable":0,"accountLocked":24},"instances":[{"id":"plan_ubuntu_1gb_node_jhb","name":"Ubuntu 26.04 - 1GB Node JHB","computeProvider":"proxmox","providerLabel":"Proxmox","productFlavorLabel":"Ubuntu 26.04 LTS","regionCode":"jnb","regionName":"Johannesburg","monthlyPrice":"4.95","hourlyPrice":"0.0172","pricing":{"currency":"USD","monthly":"4.95","hourly":"0.0172","billingModes":["monthly","hourly"],"defaultBillingMode":"monthly","options":[{"mode":"monthly","label":"Monthly","interval":"month","price":"4.95","initialCharge":"4.95"},{"mode":"hourly","label":"Hourly","interval":"hour","price":"0.0172","minimumHours":1,"initialCharge":"0.02"}],"note":"Hourly billing charges the listed hourly rate while the service is active."},"billingModes":["monthly","hourly"],"defaultBillingMode":"monthly","cpuSockets":1,"ramMb":1024,"storageGb":40,"capacityAvailable":true,"available":true,"availabilityReason":"Available under the free-account limit: one live basic 1 vCPU / 1GB RAM Proxmox Linux plan on Node A, Node B, or Johannesburg Node JHB."},{"id":"plan_azure_openclaw_builder","name":"OpenClaw Azure Spot Cape Town - Builder 2vCPU / 4GB RAM / 80GB HDD","computeProvider":"azure","providerLabel":"Azure Spot","providerPlanId":"Standard_D2als_v6","providerImageId":"Canonical:ubuntu-24_04-lts:server:latest","node":"southafricanorth","osCategory":"linux","productFlavor":"openclaw","productFlavorLabel":"OpenClaw App Instances","regionCode":"ZA","regionName":"Cape Town","monthlyPrice":"14.95","hourlyPrice":"0.0519","pricing":{"currency":"USD","monthly":"14.95","hourly":"0.0519","billingModes":["monthly","hourly"],"defaultBillingMode":"monthly","options":[{"mode":"monthly","label":"Monthly","interval":"month","price":"14.95","initialCharge":"14.95"},{"mode":"hourly","label":"Hourly","interval":"hour","price":"0.0519","minimumHours":1,"initialCharge":"0.06"}]},"billingModes":["monthly","hourly"],"defaultBillingMode":"monthly","cpuSockets":2,"ramMb":4096,"storageGb":80,"capacityAvailable":true,"available":true,"availabilityReason":"Azure Spot compute is available to free-trial users on hourly billing. Normal wallet/card affordability checks still apply at deploy time."}]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/plans":{"get":{"tags":["Compute"],"summary":"Compute plans (logged-in)","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the logged-in compute plan catalog used by the WebHotel dashboard.\n\nFor a deployment picker or external API client, prefer `GET /api/compute/available-instances`. That endpoint applies the intelligent account restrictions for the `$5` paid wallet unlock, the one free Proxmox compute slot, plan size limits, and capacity-hidden nodes.\n\nThis catalog endpoint still includes provider-backed metadata such as `computeProvider`, `providerPlanId`, `providerImageId`, region fields, IP pool availability, OS lifecycle fields, and provisioning estimates.\nPlan responses include legacy `monthlyPrice`/`hourlyPrice` fields plus `pricing.options[]`; submit the chosen option's `mode` as `billingMode` when ordering.\nAzure Spot plan rows use `computeProvider=azure`, `node` as the Azure location slug, `providerPlanId` as the Azure VM size, `providerImageId` as an optional image reference, and `osCategory` to tell clients whether to render SSH/OpenClaw fields or Windows RDP fields.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"computeProvider":{"type":"string","enum":["proxmox","google","azure"]},"providerPlanId":{"type":["string","null"]},"providerImageId":{"type":["string","null"]},"productFlavor":{"type":"string"},"productFlavorLabel":{"type":"string"},"osCategory":{"type":"string","enum":["linux","windows"]},"node":{"type":["string","null"]},"regionCode":{"type":"string"},"regionName":{"type":"string"},"monthlyPrice":{"type":"string"},"hourlyPrice":{"type":["string","null"]},"pricing":{"type":"object","additionalProperties":true,"properties":{"currency":{"type":"string","example":"USD"},"monthly":{"type":["string","null"],"example":"8.95"},"hourly":{"type":["string","null"],"example":"0.0311"},"options":{"type":"array","description":"Selectable billing rates. Send the chosen option's `mode` as `billingMode` when creating a service.","items":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string","enum":["monthly","hourly"]},"label":{"type":"string","example":"Monthly"},"interval":{"type":"string","enum":["month","hour"]},"price":{"type":"string","example":"8.95"},"minimumHours":{"type":"integer","minimum":1},"initialCharge":{"type":"string","example":"8.95"}},"required":["mode","label","interval","price","initialCharge"]}},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]},"note":{"type":"string"}},"required":["currency","monthly","hourly","options","billingModes","defaultBillingMode"]},"billingModes":{"type":"array","items":{"type":"string","enum":["monthly","hourly"]}},"defaultBillingMode":{"type":["string","null"],"enum":["monthly","hourly",null]}}}}}}}}}},"/api/compute/order":{"post":{"tags":["Compute"],"summary":"Order compute instance","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a compute instance and performs an initial wallet charge.\n\nChoose the rate by sending `billingMode` as the `mode` from the selected plan's `pricing.options[]` list. For normal compute plans this is `monthly` or `hourly`; Hermes Agent plans expose only `hourly`.\n\n**Azure Spot:** Azure plans are provisioned as Spot VMs with Deallocate eviction. Send `userChoiceUsername` and `userChoicePassword` for every Azure order. For Windows 11 plans these become the Windows administrator/RDP credentials and later appear in `rdpDetails`. For Azure OpenClaw/Linux plans these become the Linux sudo user and OpenClaw GUI credentials; also send `rootPassword` so WebHotel can verify SSH/bootstrap and expose the SSL-backed OpenClaw URL.\n\n**OpenClaw:** Use a simple service name/hostname label such as `client-app-1`; WebHotel creates `<name>.webhotel.cloud`, provisions nginx/certbot, and returns `https://<name>.webhotel.cloud/` in `applicationAccess` after readiness checks pass.\n\n**Secret packages:** You may pass `secretCode` when ordering a secret-only plan, or to redeem secret pricing/capacity for a plan that has a secret code configured.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"planId":{"type":"string"},"name":{"type":"string"},"billingMode":{"type":"string","enum":["hourly","monthly"],"description":"Selected rate mode from the plan's `pricing.options[].mode` list."},"userChoiceUsername":{"type":"string","description":"Customer-chosen login name. Azure Windows uses this as the administrator/RDP username. Azure OpenClaw/Linux uses it as the sudo user and OpenClaw GUI username."},"userChoicePassword":{"type":"string","description":"Customer-chosen password. Azure Windows uses this for RDP. Azure OpenClaw/Linux uses this for the sudo user and OpenClaw GUI."},"rootPassword":{"type":"string","description":"Required for Linux app packages that need root bootstrap verification, including Azure OpenClaw."},"providerRegionId":{"type":"string","description":"Optional provider region/location override. Azure usually uses the plan's `node`/location, for example `southafricanorth`."},"providerImageId":{"type":"string","description":"Optional provider image override. Azure examples: `MicrosoftWindowsDesktop:windows-11:win11-25h2-pro:latest` or `Canonical:ubuntu-24_04-lts:server:latest`."},"provisionId":{"type":"string","description":"Optional provisioning stream id."},"secretCode":{"type":"string","description":"Optional secret code for corporate/secret packages."}},"required":["planId","name","billingMode"]},"example":{"planId":"plan_azure_openclaw_builder","name":"client-app-1","billingMode":"hourly","userChoiceUsername":"clawuser","userChoicePassword":"Use-a-strong-client-password","rootPassword":"Use-a-strong-root-password","providerRegionId":"southafricanorth","providerImageId":"Canonical:ubuntu-24_04-lts:server:latest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/provision/{provisionId}/stream":{"get":{"tags":["Compute"],"summary":"Provisioning stream (user)","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStreams provisioning logs/events (Server-Sent Events). Default `message` events contain timestamped human-readable log lines. `progress` events contain structured JSON with `phase`, `label`, `percent`, `message`, and `updatedAt` so API clients can keep users informed after clone completion during config, resize, boot, guest-agent, cloud-init, app readiness, DNS, cleanup, and finalization. `ping` events keep the connection alive and `done` closes the stream with success/error status.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"provisionId","in":"path","required":true,"schema":{"type":"string"},"description":"Provision stream id"}],"responses":{"200":{"description":"SSE stream"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/{serviceId}/{action}":{"post":{"tags":["Compute"],"summary":"Compute action","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPerforms an action on a compute service (examples: start/stop/reboot, depending on server configuration).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"},{"name":"action","in":"path","required":true,"schema":{"type":"string"},"description":"Action name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/credentials":{"get":{"tags":["Credentials"],"summary":"Compute login credentials","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns customer-visible login credentials captured for the signed-in user's compute services.\n\nCredentials are returned in clear text so signed-in dashboard/API clients can display them without forcing the customer to rotate or recreate a server. Show a reminder not to share credentials or API tokens with unauthorized people.\n\nFor Hermes Agent, OpenVPN Access Server, and OpenClaw services, the relevant GUI/admin URL is returned in `applicationAccess` and is also attached to the matching username/password item as `items[].loginUrl`. API clients should render that `items[].loginUrl` directly beside the returned `username` and `password`; for Hermes Agent this is the public `http://{hostname}/` GUI URL and for OpenClaw this is the SSL-backed `https://{hostname}/` GUI URL.\n\nFor Azure Windows services, render `rdpDetails` beside the username/password fields and offer `GET /api/compute/{serviceId}/rdp` as the primary login action. The RDP profile pre-fills the public IPv4/host, port, and administrator username while the clear-text password remains visible to the signed-in user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"credentials":{"type":"array","items":{"type":"object","properties":{"serviceId":{"type":"string"},"serviceName":{"type":"string"},"available":{"type":"boolean"},"message":{"type":"string"},"applicationAccess":{"type":["object","null"],"additionalProperties":true,"properties":{"type":{"type":"string","enum":["hermes-agent","openvpn-as","openclaw"]},"label":{"type":"string"},"username":{"type":["string","null"]},"loginUrl":{"type":["string","null"]},"primaryUrl":{"type":["string","null"]},"urls":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"kind":{"type":"string"},"url":{"type":"string"}}}}}},"rdpDetails":{"type":["object","null"],"additionalProperties":true,"properties":{"label":{"type":["string","null"],"example":"Remote Desktop"},"host":{"type":["string","null"],"example":"20.87.211.87"},"ipAddress":{"type":["string","null"],"example":"20.87.211.87"},"hostname":{"type":["string","null"],"example":"win11-demo.webhotel.cloud"},"port":{"type":["number","null"],"example":3389},"connectionAddress":{"type":["string","null"],"example":"20.87.211.87:3389"},"username":{"type":["string","null"],"example":"webadmin"},"password":{"type":["string","null"],"example":"Returned in clear text to the signed-in owner"},"command":{"type":["string","null"],"example":"mstsc /v:20.87.211.87:3389"},"note":{"type":["string","null"]}}},"items":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"username":{"type":"string"},"password":{"type":"string"},"note":{"type":["string","null"]},"loginUrl":{"type":["string","null"]},"applicationAccess":{"type":["object","null"],"additionalProperties":true}}}}}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/{serviceId}/console":{"post":{"tags":["Console"],"summary":"Open compute console (user)","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a console ticket and returns connection details.\n\nFor Proxmox services this returns the WebHotel console ticket/proxy payload. For Azure Windows services this returns an Azure Boot Diagnostics console payload plus `rdpDetails` and `rdpDownloadUrl`; clients should show the Boot Diagnostics screen and a Download RDP File action rather than an Azure Portal link. Azure Linux/OpenClaw services expose SSH/app access through credentials and service details rather than a Windows console.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/{serviceId}/rdp":{"get":{"tags":["Console"],"summary":"Download Azure Windows RDP profile","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDownloads a standard `.rdp` profile for an Azure Windows compute service. The file preconfigures the public host, RDP port, username, display settings, clipboard redirection, and reconnect behavior so the customer can open it directly with Microsoft Remote Desktop.\n\nWindows stores saved RDP passwords through the client machine credential manager, so API clients should continue displaying the returned clear-text administrator password from `/api/compute/credentials` or `/api/compute/{serviceId}/console` beside this download action.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"RDP profile","content":{"application/x-rdp":{"schema":{"type":"string"}}}},"400":{"description":"Not an Azure Windows service","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/config":{"get":{"tags":["Object Storage"],"summary":"Storage config","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns object storage integration configuration (endpoints, defaults).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/plans":{"get":{"tags":["Object Storage"],"summary":"Storage plans (logged-in)","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists active, non-secret object storage plans. Each plan includes `pricing.options[]`; send the selected option's `mode` as `billingMode` when creating object storage.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/storage/instances":{"get":{"tags":["Object Storage"],"summary":"List storage instances","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists the current user's object storage instances.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Object Storage"],"summary":"Provision storage instance","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nProvisions a Nextcloud-backed object storage account and returns credentials (Web, WebDAV, SMB, and S3 gateway).\n\n**Secret packages:** Pass `secretCode` to provision a secret-only storage plan or redeem secret pricing/capacity.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"planId":{"type":"string"},"name":{"type":"string"},"billingMode":{"type":"string","enum":["hourly","monthly"]},"secretCode":{"type":"string","description":"Optional secret code for corporate/secret packages."}},"required":["planId","name","billingMode"]},"example":{"planId":"plan_456","name":"corp-storage-1","billingMode":"monthly","secretCode":"WH-SECRET-CODE"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/instances/{serviceId}/credentials":{"get":{"tags":["Object Storage"],"summary":"Reveal storage credentials","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns stored credentials for a specific object storage service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/instances/{serviceId}/rotate-credentials":{"post":{"tags":["Object Storage"],"summary":"Rotate object storage credentials","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRotates the customer-facing credentials for one object storage instance owned by the current user.\n\nFor Nextcloud-backed storage this rotates the generated login/app-password material returned by the service layer. For premium S3-backed storage this rotates the access key set returned in the credential payload.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Object storage service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"credentials":{"type":"object","additionalProperties":true}},"required":["message","credentials"],"additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/instances/{serviceId}":{"delete":{"tags":["Object Storage"],"summary":"Delete storage instance","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes the object storage service and permanently deletes data on the Nextcloud backend.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/buckets":{"get":{"tags":["Object Storage"],"summary":"List buckets","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists S3 buckets linked to the current user's storage services.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Object Storage"],"summary":"Create bucket","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new S3 bucket and charges deposit/initial fees depending on billing mode.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Bucket label (will be sanitized)."},"billingMode":{"type":"string","enum":["hourly","monthly"]}},"required":["name","billingMode"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/buckets/{serviceId}":{"delete":{"tags":["Object Storage"],"summary":"Delete bucket","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a bucket (service) and revokes its access keys.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Bucket service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/buckets/{serviceId}/metrics":{"get":{"tags":["Object Storage"],"summary":"Bucket metrics","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns usage/metrics for a bucket (provider-dependent).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Bucket service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/buckets/{serviceId}/access-keys":{"post":{"tags":["Object Storage"],"summary":"Create access key","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new S3 access key for the bucket/service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Bucket service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/storage/access-keys/{keyId}":{"delete":{"tags":["Object Storage"],"summary":"Revoke access key","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRevokes an S3 access key.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"},"description":"Access key id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/access-keys/{keyId}/secret":{"get":{"tags":["Object Storage"],"summary":"Reveal access key secret","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReveals the secret access key for a key that belongs to the current user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"},"description":"Access key id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/dns/status":{"get":{"tags":["DNS"],"summary":"DNS status","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns DNS service/reseller status for the current account.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/reseller-account":{"get":{"tags":["DNS"],"summary":"Get reseller account","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current user's DNS reseller/sub-account details.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["DNS"],"summary":"Create reseller account","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates the current user's DNS reseller/sub-account.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/sub-account":{"get":{"tags":["DNS"],"summary":"Get sub-account alias","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLegacy alias of GET /api/dns/reseller-account kept for older clients.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["DNS"],"summary":"Create sub-account alias","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLegacy alias of POST /api/dns/reseller-account kept for older clients.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/reseller-account/migrate":{"post":{"tags":["DNS"],"summary":"Migrate reseller account","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nMigrates DNS ownership into the reseller model for the current account.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones":{"get":{"tags":["DNS"],"summary":"List zones","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists DNS zones for the current user's reseller account.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["DNS"],"summary":"Create zone","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new DNS zone for the current user's reseller account.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}":{"delete":{"tags":["DNS"],"summary":"Delete zone","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a DNS zone.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}/info":{"get":{"tags":["DNS"],"summary":"Zone info","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns DNS zone metadata and statistics.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}/propagation":{"get":{"tags":["DNS"],"summary":"Nameserver propagation check","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nChecks whether the domain is delegated to the WebHotel nameservers from multiple public resolvers.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}/record-types":{"get":{"tags":["DNS"],"summary":"Supported record types","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns allowed DNS record types for a zone.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}/records":{"get":{"tags":["DNS"],"summary":"List records","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists DNS records for a zone.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["DNS"],"summary":"Create record","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a DNS record inside a zone.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dns/zones/{domainName}/records/{recordId}":{"put":{"tags":["DNS"],"summary":"Update record","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates a DNS record.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"},{"name":"recordId","in":"path","required":true,"schema":{"type":"string"},"description":"Record id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["DNS"],"summary":"Delete record","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a DNS record.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"domainName","in":"path","required":true,"schema":{"type":"string"},"description":"Zone/domain name"},{"name":"recordId","in":"path","required":true,"schema":{"type":"string"},"description":"Record id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/public/packages/secret":{"post":{"tags":["Secret Packages"],"summary":"Lookup secret package","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nGiven a `secretCode`, returns the matching compute and/or object storage package details.\n\nThis endpoint is intentionally public (no session required). Treat the `secretCode` as the credential.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"secretCode":{"type":"string"},"code":{"type":"string","description":"Alias for `secretCode`."}}},"example":{"secretCode":"WH-SECRET-CODE"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"compute":{"type":["object","null"],"additionalProperties":true},"objectStorage":{"type":["object","null"],"additionalProperties":true}},"required":["compute","objectStorage"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/secret/lookup":{"post":{"tags":["Secret Packages"],"summary":"Legacy secret lookup (compute)","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLegacy endpoint for compute-only secret lookups. Prefer POST /api/public/packages/secret for new integrations.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/secret/waitlist":{"post":{"tags":["Secret Packages"],"summary":"Secret waitlist signup","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSubmits a waitlist signup for exhausted secret codes.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/dashboard/waitlist-interest":{"get":{"tags":["Services"],"summary":"List coming-soon waitlist interest","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current user's per-service waitlist registrations for upcoming dashboard products.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Services"],"summary":"Register coming-soon waitlist interest","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdds or updates the current user's waitlist registration for a coming-soon dashboard product.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/contact":{"post":{"tags":["Tickets"],"summary":"Contact form","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPublic contact form submission (creates a support message/ticket internally).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/referrals/share/start":{"post":{"tags":["Referrals"],"summary":"Start social share flow","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStarts the Facebook, X, or LinkedIn share flow and returns a signed share token for claiming the extra $5 credit.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["facebook","x","linkedin"]}},"required":["platform"],"additionalProperties":false},"example":{"platform":"linkedin"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/referrals/share/facebook/start":{"post":{"tags":["Referrals"],"summary":"Start Facebook share flow","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStarts the Facebook share flow (OAuth) for referral sharing.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/referrals/share/facebook/confirm":{"post":{"tags":["Referrals"],"summary":"Confirm Facebook share","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nConfirms a completed Facebook share and triggers any reward logic.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/referrals/share/claim":{"post":{"tags":["Referrals"],"summary":"Claim share bonus","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nClaims the extra $5 sharing reward using the signed token returned from the share-start endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["facebook","x","linkedin"]},"state":{"type":"string"}},"required":["platform","state"],"additionalProperties":false},"example":{"platform":"x","state":"signed-share-state"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/tickets":{"get":{"tags":["Admin"],"summary":"List all tickets","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists support tickets across users.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/services":{"get":{"tags":["Admin"],"summary":"List all services","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists services across users (compute + storage).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/services/{serviceId}":{"delete":{"tags":["Admin"],"summary":"Delete a service as admin","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a service from the admin side. For Proxmox compute, WebHotel first runs a safe-delete preflight, blocks deletion if the cluster is unreachable, streams provider task output when a destroyId is supplied, and verifies IP/vMAC release with a retry queue. For storage services it removes the provider-side account or subaccount and then removes the portal record.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"destroyId":{"type":"string","description":"Optional destroy stream id. When supplied, consume /api/admin/compute/destroy/{destroyId}/stream for live progress."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/services/{serviceId}/delete-preflight":{"get":{"tags":["Admin","Proxmox Admin"],"summary":"Safe delete preflight","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nChecks whether a service can be safely destroyed. For Proxmox compute it confirms the panel service, expected node/VMID, provider VM existence, node match, and IP/vMAC assignment before a destructive delete is allowed.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/services/{serviceId}/owner":{"put":{"tags":["Admin"],"summary":"Change service owner","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nTransfers a service to another user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string"}},"required":["userId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/services/{serviceId}/suspension":{"post":{"tags":["Admin"],"summary":"Suspend or resume a service","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSuspends or resumes an abuse-flagged or otherwise managed service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["suspend","resume"]}},"required":["action"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/site-metadata":{"get":{"tags":["Admin","Marketing"],"summary":"Get site SEO and social metadata","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the website-wide metadata used for the homepage and any route that does not override metadata with article-specific values.\n\nThis includes the search title, description, keywords, Open Graph fields used by WhatsApp/Facebook/LinkedIn, and Twitter/X preview fields.\nUse this endpoint to populate an admin SEO editor before making changes.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"put":{"tags":["Admin","Marketing"],"summary":"Save site SEO and social metadata","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates the website-wide SEO and social preview metadata.\n\nThis directly affects the HTML metadata injected into the homepage and other non-blog routes. Save only production-ready values because messaging apps and search engines will use them.\nOpen Graph fields control previews in WhatsApp, Facebook, and LinkedIn.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"siteTitle":{"type":"string"},"siteDescription":{"type":"string"},"siteKeywords":{"type":"string"},"ogTitle":{"type":"string"},"ogDescription":{"type":"string"},"ogImageUrl":{"type":"string"},"ogImageAlt":{"type":"string"},"twitterTitle":{"type":"string"},"twitterDescription":{"type":"string"},"twitterImageUrl":{"type":"string"},"twitterImageAlt":{"type":"string"}},"required":["siteTitle","siteDescription","siteKeywords","ogTitle","ogDescription","ogImageUrl","ogImageAlt","twitterTitle","twitterDescription","twitterImageUrl","twitterImageAlt"]},"example":{"siteTitle":"WebHotel.cloud - Compute, Object Storage, and Storage Box","siteDescription":"Affordable cloud hosting with live Compute Instances, Object Storage, and HDD-backed Storage Box plans.","siteKeywords":"cloud hosting, compute instances, object storage, storage box, webhotel","ogTitle":"WebHotel.cloud - Live Cloud Infrastructure","ogDescription":"Launch compute instances, object storage, and low-cost HDD-backed Storage Box plans from one control panel.","ogImageUrl":"https://webhotel.cloud/facebookshare.png","ogImageAlt":"WebHotel.cloud control panel preview","twitterTitle":"WebHotel.cloud - Live Cloud Infrastructure","twitterDescription":"Affordable cloud hosting with live Compute, Object Storage, and Storage Box plans.","twitterImageUrl":"https://webhotel.cloud/facebookshare.png","twitterImageAlt":"WebHotel.cloud control panel preview"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/site-metadata/generate":{"post":{"tags":["Admin","Marketing"],"summary":"Generate site SEO and social metadata with AI","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nGenerates a draft of the homepage SEO copy and social metadata with OpenAI.\n\nWorkflow:\n1. Send a plain-English brief describing the positioning you want.\n2. WebHotel sends the brief together with a live summary of actually purchasable services.\n3. The AI returns titles, descriptions, keywords, and image prompts.\n4. WebHotel generates a social image and returns the draft for admin review before saving.\n\nThis route only generates a draft. It does not save anything until you call `PUT /api/admin/site-metadata`.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brief":{"type":"string"}},"required":["brief"]},"example":{"brief":"Generate strong metadata for WebHotel.cloud using only live services: Compute Instances, Object Storage, and Storage Box."}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/site-metadata/generate-variants":{"post":{"tags":["Admin","Marketing"],"summary":"Generate 3 alternative SEO and social metadata variants","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nGenerates three distinct SEO/social variants for WebHotel.cloud from one plain-English brief.\n\nEach variant uses a different angle so a non-technical admin can compare options before publishing:\n1. affordability and free trial\n2. speed and control\n3. personal service and dependable operations\n\nFor speed, the variants reuse the current live social image while changing the copy and positioning. Admin can apply the chosen variant in one click and then save it live.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brief":{"type":"string"}},"required":["brief"]},"example":{"brief":"Generate three strong metadata options for WebHotel.cloud using only live services: Compute Instances, Object Storage, and Storage Box."}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/blog/posts":{"get":{"tags":["Admin","Blog"],"summary":"List all blog posts including drafts","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every blog post in the admin system, including unpublished drafts.\n\nUse this endpoint to populate the admin blog list, draft review screen, or internal editorial workflow.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin","Blog"],"summary":"Create a blog post","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new blog post record.\n\nYou can publish immediately or save a draft by setting `published` to `false`.\nIf the slug already exists, the request is rejected so every blog URL stays unique.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/blog/posts/{postId}":{"put":{"tags":["Admin","Blog"],"summary":"Update a blog post","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates an existing blog post by id.\n\nUse this to revise the article body, swap the cover image, change metadata, or move a draft to published status.\nIf you change the slug, WebHotel checks that the new slug is still unique.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"string"},"description":"Blog post id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"delete":{"tags":["Admin","Blog"],"summary":"Delete a blog post","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a blog post permanently by id.\n\nThis removes the post from the admin list and the public blog if it was published.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"string"},"description":"Blog post id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/blog/generate":{"post":{"tags":["Admin","Blog"],"summary":"Generate a blog draft with AI","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nGenerates a draft blog article, excerpt, SEO metadata, social metadata, slug, and cover image with OpenAI.\n\nWorkflow:\n1. Send a prompt describing the article you want.\n2. WebHotel includes a live summary of what is actually purchasable so the article does not falsely advertise unavailable services.\n3. The AI returns a Markdown draft plus an image prompt.\n4. WebHotel generates the cover image and returns everything for review.\n\nThis route only creates a draft in memory. Save the result with `POST /api/admin/blog/posts` after review.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"prompt":{"type":"string"}},"required":["prompt"]},"example":{"prompt":"Write a launch article for WebHotel.cloud focused on the alpha release and only the services customers can buy today."}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/order":{"post":{"tags":["Admin"],"summary":"Order compute instance (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nProvisions compute for a specified userId (or the admin's user if omitted).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/provision/{provisionId}/stream":{"get":{"tags":["Admin"],"summary":"Provisioning stream (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStreams provisioning logs/events (Server-Sent Events). Default `message` events contain timestamped human-readable log lines. `progress` events contain structured JSON with `phase`, `label`, `percent`, `message`, and `updatedAt` so admins/API clients can keep users informed after clone completion during config, resize, boot, guest-agent, cloud-init, app readiness, DNS, cleanup, and finalization. `ping` events keep the connection alive and `done` closes the stream with success/error status.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"provisionId","in":"path","required":true,"schema":{"type":"string"},"description":"Provision stream id"}],"responses":{"200":{"description":"SSE stream"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/destroy/{destroyId}/stream":{"get":{"tags":["Admin","Proxmox Admin"],"summary":"Destroy progress stream (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStreams destructive-operation progress for admin service deletion. For Proxmox compute this includes preflight checks, stop/destroy UPID task logs, and IP/vMAC release verification status.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"destroyId","in":"path","required":true,"schema":{"type":"string"},"description":"Destroy stream id"}],"responses":{"200":{"description":"SSE stream"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/{serviceId}/{action}":{"post":{"tags":["Admin"],"summary":"Compute action (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPerforms an action on any compute service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"},{"name":"action","in":"path","required":true,"schema":{"type":"string"},"description":"Action name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/{serviceId}/console":{"post":{"tags":["Admin"],"summary":"Open compute console (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a console ticket for a compute service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/ip-pools":{"get":{"tags":["Admin"],"summary":"List IP pools","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists IP pools used for compute provisioning.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create IP pool","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates an IP pool.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/ip-pools/{poolId}/ips":{"get":{"tags":["Admin"],"summary":"List IPs in pool","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists IP addresses managed in a pool.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"poolId","in":"path","required":true,"schema":{"type":"string"},"description":"Pool id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/ip-pools/{poolId}/sync":{"post":{"tags":["Admin"],"summary":"Sync IP pool","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSyncs pool IP statuses against provisioned services.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"poolId","in":"path","required":true,"schema":{"type":"string"},"description":"Pool id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/readiness":{"get":{"tags":["Storage Box","Admin"],"summary":"Get Storage Box launch readiness","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the current Hetzner Storage Box readiness check for the shared-master-box + subaccount model used by WebHotel.\n\nUse this before publishing Storage Box plans. The response explains whether at least one synced master box exists, whether a default master box has been selected for new customer signups, and what operational warnings still apply.\n\nImportant: in this model WebHotel advertises per-plan allocation and isolates each customer into a dedicated Hetzner subaccount + home directory, but Hetzner still reports shared master-box capacity at the protocol layer.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"configured":{"type":"boolean"},"launchReady":{"type":"boolean"},"summary":{"type":"string"},"blockers":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"recommendation":{"type":["string","null"]},"registeredServers":{"type":"array","items":{"type":"object","additionalProperties":true}},"defaultServerId":{"type":["string","null"]},"boxes":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["configured","launchReady","summary","blockers","boxes"]}}}}}}},"/api/admin/storage-box/servers":{"get":{"tags":["Storage Box","Admin"],"summary":"List synced master storage boxes","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the Hetzner master Storage Boxes that WebHotel knows about, merged with live Hetzner metadata where available.\n\nAdmin workflow:\n1. Run `POST /api/admin/storage-box/servers/sync` after adding or changing master boxes in Hetzner.\n2. Pick exactly one default server for new customer signups.\n3. Leave older servers active so existing customers continue to map to their original box.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/storage-box/servers/sync":{"post":{"tags":["Storage Box","Admin"],"summary":"Sync master storage boxes from Hetzner","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPulls the live master Storage Box inventory from Hetzner and upserts it into WebHotel's admin registry.\n\nThis is the entry point you use when you buy a new primary Storage Box from Hetzner and want it to appear in the admin panel.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/servers/{serverId}":{"put":{"tags":["Storage Box","Admin"],"summary":"Update synced master storage box","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates admin-facing metadata for a synced master Storage Box.\n\nUse this to rename the server in WebHotel, disable it for future signups, or mark it as the default provisioning target for new customer Storage Box orders.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Internal synced server id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Friendly admin label for the master box."},"active":{"type":"boolean","description":"Whether the server can still be used for provisioning."},"isDefault":{"type":"boolean","description":"Whether new customer subaccounts should be created on this server."}}},"example":{"name":"Storage Box EU-1","active":true,"isDefault":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Storage Box","Admin"],"summary":"Delete synced master storage box from WebHotel","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRemoves a synced master Storage Box from the WebHotel admin registry.\n\nThis does not delete the box from Hetzner. WebHotel blocks this action if live customer services are still pinned to that master box.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Internal synced server id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/plans":{"get":{"tags":["Storage Box","Admin"],"summary":"List storage box plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every commercial Storage Box plan saved in WebHotel.\n\nThese plans define advertised customer allocation and sell pricing. Provisioning later creates a Hetzner subaccount on the current default master Storage Box and assigns the customer a dedicated home directory.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Storage Box","Admin"],"summary":"Create storage box plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a Storage Box pricing plan for the admin panel.\n\nSet at least one of `hourlyPrice` or `monthlyPrice`.\nOptional overage fields let you auto-bill excess storage above the plan allocation:\n- `hourlyOveragePricePerTb`: USD per started 1TB increment per hour for hourly-billed services\n- `monthlyOveragePricePerTb`: USD per started 1TB increment per 30 days for monthly-billed services (WebHotel bills this daily pro-rata)\n\nAdmin workflow:\n1. Create or sync at least one master Storage Box first.\n2. Create the commercial plan here.\n3. Customers later pick the plan and a storage box name; WebHotel provisions a subaccount on the current default master box.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Admin-facing plan name."},"description":{"type":["string","null"],"description":"Optional admin/customer note for the plan."},"storageTb":{"type":"integer","minimum":1,"description":"Advertised storage capacity in TB."},"hourlyPrice":{"type":["string","null"],"description":"Optional hourly sell price in USD."},"monthlyPrice":{"type":["string","null"],"description":"Optional monthly sell price in USD."},"hourlyOveragePricePerTb":{"type":["string","null"],"description":"Optional hourly overage price in USD per TB per hour."},"monthlyOveragePricePerTb":{"type":["string","null"],"description":"Optional monthly overage price in USD per TB per month. WebHotel bills this daily pro-rata while the service is over limit."},"active":{"type":"boolean","description":"Whether the plan is available for internal use."}},"required":["name","storageTb"]},"example":{"name":"Storage Box 1TB","description":"Soft-allocated 1TB account on shared OpenWeb Infrastructure storage. Actual usage is measured in the WebHotel control panel, not Windows Explorer.","storageTb":1,"hourlyPrice":"0.0055","monthlyPrice":"3.95","hourlyOveragePricePerTb":"0.03","monthlyOveragePricePerTb":"6.00","active":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/plans/seed":{"post":{"tags":["Storage Box","Admin"],"summary":"Seed storage box plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates the default internal Storage Box pricing plans if none exist yet.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/plans/{planId}":{"put":{"tags":["Storage Box","Admin"],"summary":"Update storage box plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates a Storage Box pricing plan.\n\nYou can send a partial payload. Leave `hourlyPrice` or `monthlyPrice` null to clear that billing mode, but at least one billing mode must remain configured after the update.\nYou can also set or clear the overage prices that WebHotel uses to auto-bill measured excess usage.\nOverage is billed in started 1TB increments. For example, 1.01TB over the plan limit bills as 2 x 1TB increments.\nCurrent retail defaults are $0.03 per started 1TB per hour for hourly-billed services, or $6.00 per started 1TB per 30 days for monthly-billed services.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"description":{"type":["string","null"]},"storageTb":{"type":"integer","minimum":1},"hourlyPrice":{"type":["string","null"]},"monthlyPrice":{"type":["string","null"]},"hourlyOveragePricePerTb":{"type":["string","null"]},"monthlyOveragePricePerTb":{"type":["string","null"]},"active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Storage Box","Admin"],"summary":"Delete storage box plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a saved Storage Box pricing plan from the admin panel.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/storage-box/instances":{"get":{"tags":["Storage Box","Admin"],"summary":"List live Storage Box instances with measured usage","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every live customer Storage Box service together with the latest measured folder usage.\n\nMeasurement model:\n- WebHotel connects to each Hetzner subaccount over the restricted SSH shell on port 23.\n- It runs `du` against the subaccount root to measure the customer's real folder usage.\n- It stores the result as `usageBytes`, compares it to the plan allocation, and reports any `overageBytes`.\n\nUse this endpoint for the admin Storage Box dashboard, over-limit reviews, and manual overage billing workflows.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/storage-box/instances/sync-usage":{"post":{"tags":["Storage Box","Admin"],"summary":"Force a Storage Box usage sync now","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nImmediately re-measures every live Storage Box service instead of waiting for the background sync interval.\n\nUse this after a customer finishes a large upload and you want the admin panel to reflect the latest actual usage right away.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/public/storage-box/plans":{"get":{"tags":["Storage Box"],"summary":"List public Storage Box plans","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the customer-visible Storage Box plans that are active.\n\nThis endpoint is safe for storefronts, landing pages, desktop apps, and other unauthenticated product listings. It does not expose provider-only metadata such as the Hetzner master box in use.\nIt does include any configured overage fields so the storefront can explain how excess storage is billed.\nPlan responses include `pricing.options[]`; authenticated clients should send the selected option's `mode` as `billingMode` when creating a Storage Box.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/storage-box/plans":{"get":{"tags":["Storage Box"],"summary":"List customer Storage Box plans","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the active Storage Box plans available to the logged-in customer.\n\nUse this right before showing the deploy modal so the user sees the latest hourly/monthly pricing that admin configured.\nEach plan includes `pricing.options[]`; send the selected option's `mode` as `billingMode` when creating the Storage Box.\nThe response also includes any overage rate fields that apply when measured folder usage exceeds the advertised allocation.\nCommercial usage is measured by WebHotel from the Hetzner folder itself. Do not trust Windows Explorer or mapped-drive free-space to represent the plan limit.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/storage-box/instances":{"get":{"tags":["Storage Box","Services"],"summary":"List my Storage Box instances","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the logged-in customer's active Storage Box services.\n\nEach result includes the commercial billing mode, the advertised storage allocation, the mapped host, connection hints such as the WebDAV URL and SMB path, and the latest measured usage fields:\n- `usageBytes`: actual bytes in the customer's isolated Storage Box folder\n- `planLimitBytes`: the commercial WebHotel allocation for the plan\n- `overageBytes`: bytes above the advertised allocation\n- `billableOverageTb`: overage rounded up into started 1TB billing increments\n- `usageMeasuredAt`: when WebHotel last measured usage over SSH\n- `hourlyOveragePricePerTb` / `monthlyOveragePricePerTb`: the overage rates that apply to the service snapshot\n\nThis is the endpoint your client panel should use to show real Storage Box consumption instead of relying on SMB/Explorer free-space figures.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Storage Box","Services"],"summary":"Create a Storage Box instance","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new customer Storage Box service.\n\nProvisioning flow:\n1. Validate the requested storage box name.\n2. Charge the initial hourly or monthly amount from the customer's wallet.\n3. Create a Hetzner subaccount on the current default master Storage Box.\n4. Enable access settings (SMB, SSH/SFTP, WebDAV, external access).\n5. Assign a dedicated home directory so customers cannot browse each other's files.\n\nImportant usage note: the commercial plan size is tracked inside WebHotel. Windows, SMB, and other client tools do not accurately show the included allocation.\n\nName rules: only lowercase letters, numbers, and hyphens are allowed after normalization. No spaces or special characters.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"planId":{"type":"string","description":"Storage Box plan id returned by the plan listing endpoint."},"name":{"type":"string","description":"Requested Storage Box name. WebHotel normalizes and validates it."},"billingMode":{"type":"string","enum":["hourly","monthly"],"description":"Customer-selected billing mode. It must match a billing mode that the plan actually offers."}},"required":["planId","name","billingMode"]},"example":{"planId":"plan_123","name":"media-archive","billingMode":"monthly"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage-box/instances/{serviceId}/credentials":{"get":{"tags":["Storage Box","Services"],"summary":"Reveal Storage Box credentials","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the decrypted customer credentials for a specific Storage Box service owned by the logged-in user.\n\nUse this when the customer presses a 'Show credentials' or 'Connect' button inside the portal or desktop app.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage Box service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/storage-box/instances/{serviceId}/rotate-credentials":{"post":{"tags":["Storage Box","Services"],"summary":"Rotate Storage Box credentials","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRotates the subaccount password for one Storage Box service owned by the logged-in user.\n\nUse this when the customer wants to invalidate previously shared SMB, WebDAV, SFTP, or rsync credentials without deleting the service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage Box service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"credentials":{"type":"object","additionalProperties":true}},"required":["message","credentials"],"additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage-box/instances/{serviceId}/sync-usage":{"post":{"tags":["Storage Box","Services"],"summary":"Re-measure one Storage Box usage now","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nForces an immediate usage measurement for one Storage Box service owned by the logged-in user.\n\nUse this after a large SMB, WebDAV, SFTP, or rsync upload when you want the client panel to show the latest actual folder usage right away instead of waiting for the background usage sync interval.\n\nThe measurement source is the same restricted Hetzner SSH shell used by the background job. WebHotel runs `du` inside the customer's isolated home directory and updates the stored `usageBytes`, `planLimitBytes`, `overageBytes`, and `usageMeasuredAt` fields.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage Box service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/storage-box/instances/{serviceId}/upgrade":{"post":{"tags":["Storage Box","Services"],"summary":"Upgrade a Storage Box to a larger plan","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nMoves an existing Storage Box service to a larger commercial plan without recreating the Hetzner subaccount.\n\nUpgrade rules:\n- The target plan must be active.\n- The target plan must be larger than the current plan.\n- The target plan must support the service's current billing mode.\n- WebHotel immediately charges the price difference for the current billing mode if the target plan is more expensive.\n- If the larger plan covers the customer's current measured usage, new overage charges stop on the next billing pass.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage Box service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"planId":{"type":"string","description":"Larger target Storage Box plan id."}},"required":["planId"]},"example":{"planId":"plan_5tb"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage-box/instances/{serviceId}":{"delete":{"tags":["Storage Box","Services"],"summary":"Delete a Storage Box instance","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nImmediately deletes the customer's Hetzner subaccount and removes the matching WebHotel service record.\n\nThis is destructive. Data inside the Storage Box home directory is expected to become inaccessible after deletion.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage Box service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/public/databases/plans":{"get":{"tags":["Databases"],"summary":"List public PostgreSQL plans","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the customer-visible managed PostgreSQL plans that are currently active.\n\nUse this on marketing pages, landing pages, pricing widgets, or partner integrations that need to show live database pricing without requiring a session.\nEach plan includes how many databases the customer can create under one managed PostgreSQL service.\nPlan responses include `pricing.options[]`; authenticated clients should send the selected option's `mode` as `billingMode` when creating a PostgreSQL service.\nTrial metadata is also returned so the frontend can explain that a free 30-day trial requires Stripe billing to be active on the customer account.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/databases/plans":{"get":{"tags":["Databases"],"summary":"List customer PostgreSQL plans","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the active PostgreSQL plans available to the logged-in customer.\n\nUse this right before showing a database checkout flow so the customer sees the current plan pricing and included database count.\nEach plan includes `pricing.options[]`; send the selected option's `mode` as `billingMode` when creating the PostgreSQL service.\nThe authenticated response also includes whether the current user is still eligible for the free 30-day trial.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/databases/services":{"get":{"tags":["Databases","Services"],"summary":"List my PostgreSQL services","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every active PostgreSQL service owned by the logged-in user.\n\nEach service includes the plan snapshot, billing mode, host/port/SSL settings, current service status, and the child databases currently provisioned under that service.\nStarter plans include 1 database. Pro plans include up to 10 databases.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Databases","Services"],"summary":"Create a managed PostgreSQL service","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new managed PostgreSQL service and provisions the first database immediately.\n\nProvisioning workflow:\n1. Validate the requested plan, billing mode, database name, username, and password.\n2. If the customer still qualifies for the PostgreSQL free trial and has completed the saved-card plus `$5` paid wallet unlock, skip the initial charge and start a 30-day trial instead.\n3. Otherwise debit the initial hourly or monthly charge from the customer's wallet.\n4. SSH into the managed PostgreSQL server and run the provisioning script.\n5. Store the resulting database details in WebHotel, including the admin password encrypted at rest.\n6. Return the connection details and full connection URI to the client panel.\n\nIdentifier rules: database names and admin usernames must start with a letter or underscore and then use only letters, numbers, and underscores.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"planId":{"type":"string","description":"PostgreSQL plan id returned by the plan listing endpoint."},"serviceName":{"type":"string","description":"Human-friendly label for the PostgreSQL service in the WebHotel panel."},"databaseName":{"type":"string","description":"Initial PostgreSQL database name to create on the server."},"adminUsername":{"type":"string","description":"Initial non-superuser admin username for that database."},"adminPassword":{"type":"string","description":"Initial admin password. Minimum 12 characters."},"billingMode":{"type":"string","enum":["hourly","monthly"],"description":"Billing mode to use for the service. It must be supported by the selected plan."}},"required":["planId","serviceName","databaseName","adminUsername","adminPassword","billingMode"]},"example":{"planId":"postgresql-starter","serviceName":"Production PostgreSQL","databaseName":"app_main","adminUsername":"app_admin","adminPassword":"ChangeThisPasswordNow!","billingMode":"monthly"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/databases/services/{serviceId}/databases":{"post":{"tags":["Databases","Services"],"summary":"Create another database under an existing PostgreSQL service","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nProvisions an additional PostgreSQL database under an existing managed PostgreSQL service owned by the logged-in customer.\n\nUse this for Pro plans or any future plans that allow more than one database under the same paid service.\nThe service must not be suspended, and the new database must still fit inside the plan's `databaseLimit`.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"databaseName":{"type":"string"},"adminUsername":{"type":"string"},"adminPassword":{"type":"string"}},"required":["databaseName","adminUsername","adminPassword"]},"example":{"databaseName":"analytics_db","adminUsername":"analytics_admin","adminPassword":"ChangeThisPasswordNow!"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/databases/services/{serviceId}/databases/{databaseId}/credentials":{"get":{"tags":["Databases","Services"],"summary":"Reveal PostgreSQL credentials for one customer database","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the decrypted password and connection URI for one PostgreSQL database owned by the logged-in customer.\n\nUse this when the customer clicks 'Reveal credentials' in the control panel after provisioning or during later recovery work.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"},{"name":"databaseId","in":"path","required":true,"schema":{"type":"string"},"description":"Child PostgreSQL database record id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/databases/services/{serviceId}/databases/{databaseId}/password":{"put":{"tags":["Databases","Services"],"summary":"Rotate the password for one customer PostgreSQL database","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates the login password for one PostgreSQL database admin role owned by the logged-in customer.\n\nThe new password is applied on the PostgreSQL server immediately and the encrypted copy stored in WebHotel is updated at the same time.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"},{"name":"databaseId","in":"path","required":true,"schema":{"type":"string"},"description":"Child PostgreSQL database record id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"adminPassword":{"type":"string","description":"New password. Letters and numbers only, minimum 12 characters."}},"required":["adminPassword"]},"example":{"adminPassword":"NewPassword1234"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/databases/services/{serviceId}/databases/{databaseId}":{"delete":{"tags":["Databases","Services"],"summary":"Delete one PostgreSQL database under a managed service","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDrops one managed PostgreSQL database and its matching admin role from the server, then removes the child database record from WebHotel.\n\nThis is destructive and cannot be undone.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"},{"name":"databaseId","in":"path","required":true,"schema":{"type":"string"},"description":"Child PostgreSQL database record id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/databases/services/{serviceId}":{"delete":{"tags":["Databases","Services"],"summary":"Delete a managed PostgreSQL service","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a managed PostgreSQL service and every child database under it.\n\nThe server-side workflow drops each database, drops the matching database roles, and finally removes the parent service from WebHotel.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/databases/plans":{"get":{"tags":["Databases","Admin"],"summary":"List admin PostgreSQL plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every PostgreSQL plan, including inactive plans hidden from customers.\n\nUse this for the admin pricing editor and operational plan management views.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Databases","Admin"],"summary":"Create a PostgreSQL plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new managed PostgreSQL plan for customer purchase flows.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/databases/plans/{planId}":{"put":{"tags":["Databases","Admin"],"summary":"Update a PostgreSQL plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates the pricing, included database count, description, or active status for one PostgreSQL plan.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"PostgreSQL plan id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Databases","Admin"],"summary":"Delete a PostgreSQL plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes one PostgreSQL plan definition.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"PostgreSQL plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/databases/services":{"get":{"tags":["Databases","Admin"],"summary":"List all live managed PostgreSQL services","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns every non-destroyed PostgreSQL service together with its owner summary and child database records.\n\nUse this for support tooling, operational reviews, password-recovery workflows, and manual suspension/deletion decisions.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/databases/services/{serviceId}/databases/{databaseId}/credentials":{"get":{"tags":["Databases","Admin"],"summary":"Reveal PostgreSQL credentials as admin","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the exact decrypted password and connection URI for one managed PostgreSQL database.\n\nThis exists for support and recovery work when an admin explicitly needs to see the live customer credentials.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Managed PostgreSQL service id"},{"name":"databaseId","in":"path","required":true,"schema":{"type":"string"},"description":"Child PostgreSQL database record id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/pricing/object-storage":{"get":{"tags":["Admin"],"summary":"Get object storage pricing config","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the object storage pricing configuration (deposit/base rates, etc).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"put":{"tags":["Admin"],"summary":"Update object storage pricing config","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates the object storage pricing configuration.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/users":{"get":{"tags":["Admin"],"summary":"List users","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists users for administrative management.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create user","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a user account (admin action).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/users/{userId}":{"put":{"tags":["Admin"],"summary":"Update user","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates user fields (admin action).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Admin"],"summary":"Delete user","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a user (admin action).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/users/{userId}/password":{"put":{"tags":["Admin"],"summary":"Reset user password","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSets a new password for a user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string"}},"required":["password"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/users/{userId}/simulate":{"post":{"tags":["Admin"],"summary":"Simulate user session","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSwitches the current admin session into the selected customer account for support troubleshooting. The response includes impersonation metadata, and the session can be restored with POST /api/admin/impersonation/stop.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"Target user id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/impersonation/stop":{"post":{"tags":["Admin"],"summary":"Return from simulated user session","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRestores the original admin identity after an admin has simulated a user. Use this endpoint for the prominent Return to Admin control shown during simulation.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/users/{userId}/transactions":{"get":{"tags":["Admin"],"summary":"User transactions","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns transaction log for a specific user.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/users/{userId}/timeline":{"get":{"tags":["Admin"],"summary":"User unified timeline","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the same unified timeline used by the customer dashboard, but for a specific target user.\n\nThis is useful when support or billing staff need one chronological view that combines services, wallet events, tickets, audit events, and automated billing actions.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":300,"default":120},"description":"Maximum number of timeline entries to return."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/users/{userId}/subscription-timeline":{"get":{"tags":["Admin"],"summary":"User Stripe lifecycle timeline","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns Stripe lifecycle and automatic top-up events for one user profile so admins can review setup, renewal, failure, and recovery history.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/billing-health":{"get":{"tags":["Admin"],"summary":"Billing health dashboard","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns Stripe-linked users with inconsistent local billing flags, failing subscriptions, cap-policy risk, or detected billing anomalies.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/provider-margins":{"get":{"tags":["Admin"],"summary":"Provider margin report","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns computed sell-price versus provider-cost margins for provider-backed compute plans.\n\nUse this for plan review, underpricing detection, and profitability monitoring across Proxmox, Google, Azure Spot, and DanubeData-backed offerings.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/billing-policy":{"get":{"tags":["Admin"],"summary":"Get billing cap policy","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the active global cap policy: suspend, warn_only, or auto_topup_first.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"put":{"tags":["Admin"],"summary":"Update billing cap policy","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates the global billing-cap action policy used when a user reaches a monthly per-product spend cap.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"capPolicy":{"type":"string","enum":["suspend","warn_only","auto_topup_first"]}},"required":["capPolicy"]},"example":{"capPolicy":"suspend"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/users/{userId}/credit-adjust":{"post":{"tags":["Admin"],"summary":"Adjust credit balance","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdds or deducts wallet credit for a user and records the note in the transaction/activity trail.\n\nImportant behavior:\n- `direction` controls whether the amount is credited or debited.\n- `amountUsd` must always be a positive USD amount.\n- `note` is required and is written into the admin-visible history.\n- `idempotencyKey` is optional but recommended for external admin tooling to prevent duplicate adjustments.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"User id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"direction":{"type":"string","enum":["credit","debit"]},"amountUsd":{"type":"number","description":"Positive USD amount to apply in the chosen direction."},"note":{"type":"string","description":"Required operator note. Max 500 characters."},"idempotencyKey":{"type":"string","description":"Optional client-supplied idempotency key."}},"required":["direction","amountUsd","note"],"additionalProperties":false},"example":{"direction":"credit","amountUsd":25,"note":"Promotional goodwill credit for March billing issue","idempotencyKey":"admin-credit-2026-03-29-001"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"applied":{"type":"boolean"},"creditBalance":{"type":"string"}},"required":["ok","applied","creditBalance"],"additionalProperties":true}}}}}}},"/api/admin/product-plans":{"get":{"tags":["Admin"],"summary":"List compute plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists compute plans including secret-only configuration (secret hashes are never returned).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create compute plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a compute plan for any supported provider.\n\nProvider-specific behavior:\n- `computeProvider=proxmox`: `node` is the Proxmox node and `templateVmid` is the template VMID.\n- `computeProvider=vultr`: legacy/internal Google-backed plans. `node` is the provider region id, `providerPlanId` is the instance size id, and `templateVmid` is the provider `os_id`.\n- `computeProvider=azure`: Azure Spot-only plans. `node` is the Azure location, `providerPlanId` is the Azure VM size, and `providerImageId` is an optional Azure image reference. If no existing subnet is configured, WebHotel auto-creates the required open Azure VNet/subnet/NSG.\n- `computeProvider=danubedata`: `node` is the datacenter key, `providerPlanId` is the pricing profile id, and `providerImageId` is the provider image id.\n\nSecret-package controls are also accepted here: `secretOnly`, `secretCode`, `secretMonthlyPrice`, `secretHourlyPrice`, and `secretMaxInstances`.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"computeProvider":{"type":"string","enum":["proxmox","vultr","azure","danubedata"]},"providerPlanId":{"type":["string","null"]},"providerImageId":{"type":["string","null"]},"osCategory":{"type":"string","enum":["linux","windows"]},"monthlyPrice":{"type":"string"},"hourlyPrice":{"type":["string","null"]},"node":{"type":"string","description":"Proxmox node or provider region/datacenter key."},"regionLabel":{"type":["string","null"]},"templateVmid":{"type":"integer"},"cpuSockets":{"type":"integer"},"ramMb":{"type":"integer"},"storageGb":{"type":"integer"},"trafficUnlimited":{"type":"boolean"},"trafficTb":{"type":["integer","null"]},"networkRateMbps":{"type":["integer","null"]},"cloudInitName":{"type":["string","null"]},"cloudInitScript":{"type":["string","null"]},"secretOnly":{"type":"boolean"},"secretCode":{"type":["string","null"]},"secretMonthlyPrice":{"type":["string","null"]},"secretHourlyPrice":{"type":["string","null"]},"secretMaxInstances":{"type":["integer","null"]},"active":{"type":"boolean"}},"required":["name","computeProvider","monthlyPrice","node","templateVmid","cpuSockets","ramMb","storageGb","trafficUnlimited"],"additionalProperties":true},"example":{"name":"Snapdragon ZA 2GB","description":"Johannesburg cloud instance on Google","computeProvider":"vultr","providerPlanId":"vc2-1c-2gb","osCategory":"linux","monthlyPrice":"12.00","hourlyPrice":"0.0170","node":"jnb","regionLabel":"Johannesburg, ZA","templateVmid":387,"cpuSockets":1,"ramMb":2048,"storageGb":55,"trafficUnlimited":false,"trafficTb":2,"cloudInitName":"Ubuntu 24.04 Google Provisioning Script","active":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/product-plans/{planId}":{"put":{"tags":["Admin"],"summary":"Update compute plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates an existing compute plan.\n\nYou may patch only the fields you want to change. Provider-specific validation still applies, and secret-code changes update the stored hash without ever returning the hash itself.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Admin"],"summary":"Delete compute plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a compute plan.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/product-plans/{planId}/duplicate":{"post":{"tags":["Admin"],"summary":"Duplicate compute plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDuplicates a compute plan (copy is not secret by default).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/plans":{"get":{"tags":["Admin"],"summary":"List object storage plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists object storage plans. Secret hashes are never returned; use the secretCodeSet boolean and rotate via update.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create object storage plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates an object storage plan. Supports secret-only plans via secretOnly + secretCode or generateSecretCode.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/plans/{planId}":{"put":{"tags":["Admin"],"summary":"Update object storage plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates an object storage plan (may generate/rotate secret code).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Admin"],"summary":"Delete object storage plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes an object storage plan.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/plans/{planId}/duplicate":{"post":{"tags":["Admin"],"summary":"Duplicate object storage plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDuplicates an object storage plan (copy is not secret by default).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/nextcloud-servers":{"get":{"tags":["Admin"],"summary":"List Nextcloud servers","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists Nextcloud servers used for object storage provisioning.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create Nextcloud server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdds a Nextcloud server configuration.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/nextcloud-servers/{serverId}":{"put":{"tags":["Admin"],"summary":"Update Nextcloud server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates a Nextcloud server configuration.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Nextcloud server id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Admin"],"summary":"Delete Nextcloud server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a Nextcloud server configuration.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Nextcloud server id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/object-storage/bridge-health":{"get":{"tags":["Admin"],"summary":"Object storage SMB bridge health","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns live mount state, last successful mount timestamp, last bridge error, diagnostics summary, and suspension metadata for each Nextcloud-backed object storage instance.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/object-storage/instances/{serviceId}/diagnostics":{"post":{"tags":["Admin"],"summary":"Run object storage diagnostics","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns a live SMB, WebDAV, S3 gateway, and provider-admin diagnostic for one Nextcloud-backed object storage instance, then stores the latest result on the service record.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Object storage service id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/pages-workers/apps":{"get":{"tags":["Pages & Workers"],"summary":"List apps","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists the current user's Pages & Workers apps.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Pages & Workers"],"summary":"Create app","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a Pages or Worker app with explicit settings.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/pages-workers/apps/wizard":{"post":{"tags":["Pages & Workers"],"summary":"Wizard deploy","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAnalyzes a GitHub repo and creates a Pages/Worker app automatically.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/pages-workers/apps/{appId}/deployments":{"get":{"tags":["Pages & Workers"],"summary":"List deployments","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists recent deployments for a Pages & Workers app.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"appId","in":"path","required":true,"schema":{"type":"string"},"description":"App id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/pages-workers/apps/{appId}/redeploy":{"post":{"tags":["Pages & Workers"],"summary":"Redeploy app","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nTriggers a new deployment for an existing Pages/Worker app.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"appId","in":"path","required":true,"schema":{"type":"string"},"description":"App id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/pages-workers/apps/{appId}/custom-domain":{"put":{"tags":["Pages & Workers"],"summary":"Set custom domain","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSets or clears the custom domain for a Pages/Worker app.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"appId","in":"path","required":true,"schema":{"type":"string"},"description":"App id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/pages-workers/apps/{appId}":{"delete":{"tags":["Pages & Workers"],"summary":"Delete app","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDestroys a Pages/Worker app.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"appId","in":"path","required":true,"schema":{"type":"string"},"description":"App id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/pages-workers/deploy-hook/{appId}/{token}":{"post":{"tags":["Pages & Workers"],"summary":"Trigger deploy hook","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nTriggers a Pages & Workers deployment using the app's deploy-hook token. Intended for Git provider webhooks and manual CI triggers.","security":[],"parameters":[{"name":"appId","in":"path","required":true,"schema":{"type":"string"},"description":"App id"},{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"Deploy hook token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"202":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/pages-workers/servers":{"get":{"tags":["Admin"],"summary":"List Pages & Workers servers","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists infrastructure servers available for Pages & Workers deployments.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create Pages & Workers server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new infrastructure server entry for Pages & Workers.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/pages-workers/servers/{serverId}":{"put":{"tags":["Admin"],"summary":"Update Pages & Workers server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates a Pages & Workers infrastructure server.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Server id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Admin"],"summary":"Delete Pages & Workers server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a Pages & Workers infrastructure server.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Server id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/pages-workers/servers/{serverId}/test":{"post":{"tags":["Admin"],"summary":"Test Pages & Workers server","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the connectivity test for a Pages & Workers infrastructure server.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serverId","in":"path","required":true,"schema":{"type":"string"},"description":"Server id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/incidents":{"get":{"tags":["Admin"],"summary":"List all incidents","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns all incidents, including private and inactive ones, for admin review and editing.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"post":{"tags":["Admin"],"summary":"Create incident","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a new incident record for public/private operational status tracking.\n\nIf `startsAt` is omitted, the server will default it to the current time.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"summary":{"type":"string"},"status":{"type":"string"},"severity":{"type":"string"},"productScope":{"type":["string","null"]},"providerScope":{"type":["string","null"]},"publicVisible":{"type":"boolean"},"active":{"type":"boolean"},"startsAt":{"type":["string","null"],"format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time"}},"required":["title","summary"],"additionalProperties":false},"example":{"title":"Johannesburg Google compute degraded","summary":"New compute deployments in JNB are slower than normal while the provider investigates.","status":"investigating","severity":"warning","productScope":"compute","providerScope":"vultr","publicVisible":true,"active":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/incidents/{incidentId}":{"put":{"tags":["Admin"],"summary":"Update incident","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates an existing incident record.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"incidentId","in":"path","required":true,"schema":{"type":"string"},"description":"Incident id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"delete":{"tags":["Admin"],"summary":"Delete incident","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes an incident record permanently.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"incidentId","in":"path","required":true,"schema":{"type":"string"},"description":"Incident id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/abuse":{"get":{"tags":["Admin"],"summary":"Abuse report","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns flagged accounts, linked device fingerprints, and attached services so admins can review or destroy abusive resources.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["users"],"additionalProperties":false}}}}}}},"/api/admin/provider-credentials":{"get":{"tags":["Admin"],"summary":"Get provider credential settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the editable provider credential groups shown in the admin panel.\n\nEach group contains field metadata plus the current value loaded from `.env`/process environment.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"put":{"tags":["Admin"],"summary":"Save provider credential settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates editable provider credentials in the server `.env` file and current process environment.\n\nSend only the keys you want to manage inside the `values` object. Validation errors are returned when required formats fail, such as Stripe webhook secret checks.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"values":{"type":"object","additionalProperties":true,"description":"Map of environment variable keys to the new values to persist."}},"required":["values"],"additionalProperties":false},"example":{"values":{"VULTR_API_BASE_URL":"https://api.vultr.com/v2","VULTR_API_TOKEN":"token-value"}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/provider-credentials/audit":{"get":{"tags":["Admin"],"summary":"Provider credential audit log","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the most recent provider credential save/restart audit events.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/provider-credentials/test-history":{"get":{"tags":["Admin"],"summary":"Provider credential test history","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns historical connectivity test results for provider integrations.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/provider-credentials/stripe/webhook-status":{"get":{"tags":["Admin"],"summary":"Stripe webhook status summary","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current Stripe webhook verification/processing health summary.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/provider-credentials/stripe/webhook-events":{"get":{"tags":["Admin"],"summary":"Recent Stripe webhook events","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns recently processed Stripe webhook events with summarized payload details.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Maximum number of webhook events to return."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/provider-credentials/stripe/webhook-test":{"post":{"tags":["Admin"],"summary":"Run Stripe webhook signing test","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nBuilds and verifies a locally signed Stripe webhook test payload using the configured webhook secret.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/provider-credentials/test/{groupId}":{"post":{"tags":["Admin"],"summary":"Run one provider connectivity test","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the live connectivity test for one configured provider group and stores the result in test history.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string","enum":["proxmox","vultr","danubedata","hetzner","cloudflare","cpanel","cloudns","ovh","postgresql","supportoasis","openai","stripe"]},"description":"Provider group id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/provider-credentials/restart":{"post":{"tags":["Admin"],"summary":"Queue WebHotel restart","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nQueues a `webhotel` service restart after provider credential changes.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/vultr/health":{"get":{"tags":["Admin"],"summary":"Google provider API health","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns whether the Google provider API is configured on this server and whether a live catalog call succeeded.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/vultr/catalog":{"get":{"tags":["Admin"],"summary":"Google live product catalog summary","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns live Google provider catalog and inventory data for a non-technical admin view, including product-family summaries, regions, compute plans, operating systems, one-click applications, startup scripts, reserved IPs, current instances, and selected live inventories.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/vultr/regions":{"get":{"tags":["Admin"],"summary":"List Google regions","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns available Google provider regions for compute plan creation.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/vultr/plans":{"get":{"tags":["Admin"],"summary":"List Google plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns available Google provider instance plans. Optional query param: `type` (defaults to `vc2`).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string"},"description":"Google provider plan type (for example vc2, vhf, vdc)"},{"name":"region","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Google provider region id (for example jnb, lhr) to return only plans available in that region."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/vultr/os":{"get":{"tags":["Admin"],"summary":"List Google operating systems","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns available Google provider OS images (os_id values).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/vultr/plans-metal":{"get":{"tags":["Admin"],"summary":"List Google bare metal plans","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns live Google provider bare metal plan sizes that can later be turned into WebHotel packages.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"region","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Google provider region id to return only bare metal sizes available in that region."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"/api/admin/azure/health":{"get":{"tags":["Admin","Provider Health"],"summary":"Azure Spot API health","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nChecks Azure service principal credentials, prepares the WebHotel-managed open network when no existing subnet is configured, verifies live VM-size access, and confirms the Spot-only policy. Azure provisioning is locked to Spot priority with Deallocate eviction, Standard HDD OS disks, public IPv4, and open inbound/outbound NSG rules for customer-accessible packages.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"configured":{"type":"boolean"},"connected":{"type":"boolean"},"checkedAt":{"type":"string","format":"date-time"},"latencyMs":{"type":"number"},"subscriptionId":{"type":"string"},"resourceGroup":{"type":"string"},"location":{"type":"string","example":"southafricanorth"},"managedNetwork":{"type":"boolean"},"subnetId":{"type":["string","null"]},"networkSecurityGroupId":{"type":["string","null"]},"spotOnly":{"type":"boolean","example":true},"priority":{"type":"string","example":"Spot"},"evictionPolicy":{"type":"string","example":"Deallocate"},"spotMaxPrice":{"type":["number","string","null"]},"vmSizeCount":{"type":"integer"},"message":{"type":"string"}}}}}}}}},"/api/admin/azure/vm-sizes":{"get":{"tags":["Admin","Provider Health"],"summary":"List Azure VM sizes","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns Azure VM sizes for a location. Use the selected size as product plan `providerPlanId`; WebHotel will provision it as Spot only. For the customer panel, display Cape Town while storing/requesting Azure location `southafricanorth`.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"location","in":"query","required":false,"schema":{"type":"string"},"description":"Azure location, for example southafricanorth, westeurope, eastus, or uksouth."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","example":"Standard_D2als_v6"},"numberOfCores":{"type":"integer","example":2},"memoryInMB":{"type":"integer","example":4096},"osDiskSizeInMB":{"type":"integer"},"resourceDiskSizeInMB":{"type":"integer"},"maxDataDiskCount":{"type":"integer"}}}}}}}}}},"/api/admin/azure/spot-services":{"get":{"tags":["Admin","Provider Health"],"summary":"Azure Spot service monitor status","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists WebHotel Azure Spot services with last observed power state, monitor errors, and automatic restart count. Use this to confirm whether Azure deallocated a Spot VM and whether the configured retry policy has requested restarts.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"configured":{"type":"boolean"},"spotOnly":{"type":"boolean","example":true},"checkedAt":{"type":"string","format":"date-time"},"services":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"serviceId":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"ipAddress":{"type":["string","null"]},"resourceGroup":{"type":["string","null"]},"vmName":{"type":["string","null"]},"location":{"type":["string","null"],"example":"southafricanorth"},"vmSize":{"type":["string","null"],"example":"Standard_D2als_v6"},"priority":{"type":"string","example":"Spot"},"evictionPolicy":{"type":"string","example":"Deallocate"},"spotMaxPrice":{"type":["number","string","null"]},"powerState":{"type":["string","null"],"example":"PowerState/running"},"lastCheckedAt":{"type":["string","null"],"format":"date-time"},"autoRestartCount":{"type":"integer"},"monitorError":{"type":["string","null"]}}}}}}}}}}}},"/api/admin/danubedata/health":{"get":{"tags":["Admin"],"summary":"DanubeData API health","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns whether DanubeData is configured on this server and whether live catalog access succeeds.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/danubedata/catalog":{"get":{"tags":["Admin"],"summary":"DanubeData live catalog summary","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns DanubeData datacenters, images, pricing profiles, and currently visible VPS instances.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/health":{"get":{"tags":["Proxmox Admin"],"summary":"Proxmox health and circuit breaker state","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns Proxmox token/config status, API latency, node count, version, TLS certificate expiry warning, destructive-action circuit-breaker state, and pending IP/vMAC release retries. Admin UI uses this before enabling destructive operations.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/drift":{"get":{"tags":["Proxmox Admin"],"summary":"Proxmox drift audit","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCompares WebHotel panel compute services, live Proxmox QEMU inventory, and IP/vMAC assignments. Use it to find panel services missing from Proxmox, unmanaged provider VMs, stale assigned IPs, and queued release-verification retries.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/nodes","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/clusters/nodes":{"get":{"tags":["Proxmox Admin"],"summary":"List Proxmox nodes across configured clusters","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns grouped live node lists from the primary Proxmox cluster and any read-only additional Proxmox clusters configured for the Admin inventory page. Node rows are enriched from Proxmox cluster resources, cluster status, per-node status, and datastore status when the token has the required Proxmox audit permissions.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/vms":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/vms","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/vms/managed":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/vms/managed","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/templates":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/templates","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/cluster/nextid":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/cluster/nextid","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/containers":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/containers","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/pools":{"get":{"tags":["Proxmox Admin"],"summary":"Admin Proxmox: GET /api/admin/proxmox/pools","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdministrative Proxmox integration endpoint.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/proxy":{"post":{"tags":["Proxmox Admin"],"summary":"Proxmox API proxy","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nProxies an arbitrary Proxmox API call. Intended for admin UI tooling.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/tasks":{"get":{"tags":["Proxmox Admin"],"summary":"Node tasks","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists tasks for a Proxmox node.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/vms":{"get":{"tags":["Proxmox Admin"],"summary":"Node VMs","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists VMs for a Proxmox node.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/storage":{"get":{"tags":["Proxmox Admin"],"summary":"Node storage","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists storage for a Proxmox node.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/network":{"get":{"tags":["Proxmox Admin"],"summary":"Node network","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists network configuration for a Proxmox node.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/qemu/{vmid}/config":{"get":{"tags":["Proxmox Admin"],"summary":"VM config","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nFetches QEMU VM config.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"},{"name":"vmid","in":"path","required":true,"schema":{"type":"string"},"description":"VM id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/nodes/{node}/qemu/{vmid}/clone":{"post":{"tags":["Proxmox Admin"],"summary":"Clone VM","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nClones a VM/template on Proxmox.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"},{"name":"vmid","in":"path","required":true,"schema":{"type":"string"},"description":"VM id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/vms/{node}/{vmid}/{action}":{"post":{"tags":["Proxmox Admin"],"summary":"VM action","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPerforms an action on a VM (start/stop/reboot/etc).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"},{"name":"vmid","in":"path","required":true,"schema":{"type":"string"},"description":"VM id"},{"name":"action","in":"path","required":true,"schema":{"type":"string"},"description":"Action"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/admin/proxmox/containers/{node}/{vmid}/{action}":{"post":{"tags":["Proxmox Admin"],"summary":"Container action","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPerforms an action on a container.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"node","in":"path","required":true,"schema":{"type":"string"},"description":"Proxmox node name"},{"name":"vmid","in":"path","required":true,"schema":{"type":"string"},"description":"Container id"},{"name":"action","in":"path","required":true,"schema":{"type":"string"},"description":"Action"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/api-tokens/usage":{"get":{"tags":["API Tokens"],"summary":"API token usage analytics","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns per-token request counts, last used IP, last used time, scopes, IP allowlists, logged request counts, and error counts for the signed-in dashboard user. The dashboard uses this to audit API integrations.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/api-logs":{"get":{"tags":["API Debug"],"summary":"Last 100 API requests, responses, and provisioning events","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns replay/debug records for API clients: recent API request summaries, webhook deliveries, and provisioning-related events. Bearer tokens need `debug:read` or `debug:*` scope. Use `limit` up to 100.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/api-webhooks":{"get":{"tags":["Webhooks"],"summary":"List provisioning webhooks","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists webhook endpoints that receive callbacks when services become ready, fail, suspend, or are destroyed. Delivery counts are included for debugging.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["Webhooks"],"summary":"Create provisioning webhook","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a provisioning webhook. Events include `service.ready`, `service.failed`, `service.suspended`, `service.destroyed`, and `webhook.test`. The response includes the signing secret once; verify `X-WebHotel-Signature` as HMAC-SHA256 over the raw JSON body.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"HTTPS callback URL."},"events":{"type":"array","items":{"type":"string"}}},"required":["url"],"additionalProperties":false},"example":{"name":"Portal callbacks","url":"https://portal.example.com/webhotel/callback","events":["service.ready","service.failed","service.destroyed"]}}}}}},"/api/api-webhooks/{webhookId}":{"put":{"tags":["Webhooks"],"summary":"Update provisioning webhook","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates webhook name, URL, active state, or subscribed events.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"active":true,"events":["service.ready","service.failed"]}}}}},"delete":{"tags":["Webhooks"],"summary":"Delete provisioning webhook","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeletes a webhook endpoint and stops future callback deliveries.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id."}]}},"/api/api-webhooks/{webhookId}/test":{"post":{"tags":["Webhooks"],"summary":"Queue webhook test delivery","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nQueues a `webhook.test` delivery so API clients can verify callback authentication and parsing.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id."}]}},"/api/launch-recipes":{"get":{"tags":["Launch Recipes"],"summary":"List Launch Recipes","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists saved recipes and recent runs. Recipes describe a bundle of Compute, PostgreSQL, Object Storage, and DNS work for one API-driven launch workflow.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["Launch Recipes"],"summary":"Create Launch Recipe","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSaves a reusable Launch Recipe definition. A recipe can include `compute`, `postgresql`, `objectStorage`, and `dns` blocks.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"name":"SaaS starter","definition":{"compute":{"planId":"plan_compute","name":"app1","billingMode":"monthly","username":"admin","password":"StrongPass123!"},"postgresql":{"planId":"plan_pg","name":"app1-db"},"objectStorage":{"planId":"plan_s3","name":"app1-assets"},"dns":{"hostname":"app1.example.com","ipAddress":"203.0.113.10"}}}}}}}},"/api/launch-recipes/run":{"post":{"tags":["Launch Recipes"],"summary":"Run Launch Recipe","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nStarts a tracked recipe run from a saved `recipeId` or inline `definition`. DNS is applied immediately when hostname and IP are supplied; provisioning steps return exact follow-up endpoint/body pairs so API clients can run the full bundle without guessing.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"recipeId":"recipe_123"}}}}}},"/api/service-widgets":{"get":{"tags":["Widgets"],"summary":"List reseller service-card widgets","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists embeddable service-card widget tokens for third-party reseller portals.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["Widgets"],"summary":"Create reseller service-card widget","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates an embeddable service card token that can show status, billing, public IP, app GUI URL, RDP details, and optionally clear-text credentials inside a trusted third-party portal.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serviceId":{"type":"string"},"label":{"type":"string"},"allowedOrigins":{"type":"array","items":{"type":"string"}},"showCredentials":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"}},"required":["serviceId"],"additionalProperties":false},"example":{"serviceId":"svc_123","label":"Client portal card","allowedOrigins":["https://portal.example.com"],"showCredentials":true}}}}}},"/api/service-widgets/{widgetId}":{"delete":{"tags":["Widgets"],"summary":"Delete reseller service-card widget","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRevokes an embeddable service-card widget token.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"widgetId","in":"path","required":true,"schema":{"type":"string"},"description":"Widget id."}]}},"/api/embed/service-card":{"get":{"tags":["Widgets"],"summary":"Fetch embeddable service-card data","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nPublic token-based endpoint used by the reseller widget script. Pass `token=<widget token>` and embed only on allowed origins.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/embed/service-card.js":{"get":{"tags":["Widgets"],"summary":"Embeddable reseller service-card script","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nJavaScript widget bundle. Add `<script src=\"https://webhotel.cloud/embed/service-card.js\" data-webhotel-widget-token=\"...\" ></script>` to a trusted portal.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/service-health":{"get":{"tags":["Service Health"],"summary":"Customer uptime and SSL health cards","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns latest health card data per service, including HTTP status, latency, SSL validity, certificate expiry, last error, and check timestamp.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/service-health/{serviceId}/check":{"post":{"tags":["Service Health"],"summary":"Run service health check now","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns a fresh HTTP/SSL probe for one service owned by the signed-in user and records the result.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id."}]}},"/api/compute/region-recommendations":{"get":{"tags":["Compute"],"summary":"Best region now recommender","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nScores the currently deployable compute catalog by capacity, price, canary/failure signals, and provisioning speed. Returns the best region/provider now plus ranked alternatives.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/provider-margin-sentinel":{"get":{"tags":["Provider Health"],"summary":"Provider margin sentinel events","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists recent provider-margin sentinel warnings/disable events and active thresholds. Admins use this to identify cloud-cost drift before plans become unprofitable.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/provider-margin-sentinel/run":{"post":{"tags":["Provider Health"],"summary":"Run provider margin sentinel now","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the margin sentinel immediately. It compares provider costs to sell prices, records warnings, and can disable plans automatically when the configured disable threshold is reached.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/trial/status":{"get":{"tags":["Billing"],"summary":"Trial and provider-unlock status","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the signed-in user's card-linked state, paid top-up amount, admin-credit exemption, wallet balance, trial-limited compute allowance, and a plain-language message explaining whether the basic 1 vCPU / 1GB Proxmox Linux free-account deployment is still available or whether a saved card plus paid $5 top-up is required to unlock paid providers, storage, PostgreSQL, app packages, and larger compute products. Admin accounts and accounts with admin-applied wallet credit are exempt.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/unlock-diagnostics":{"get":{"tags":["Billing"],"summary":"Why am I locked diagnostics","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the same structured unlock/blocker payload used by the customer dashboard. Client apps should display this when a user cannot deploy a larger compute plan, Google/Azure Spot resource, Object Storage, Storage Box, or PostgreSQL because the saved-card plus $5 paid wallet unlock has not been completed yet.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/unfunded-account-simulator":{"get":{"tags":["Admin"],"summary":"Preview unfunded account restrictions","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nBuilds an admin-only simulation of what a brand-new or unfunded customer can deploy. This helps support staff confirm that trial restrictions allow one eligible basic Proxmox Linux 1 vCPU / 1GB RAM compute resource on Node A, Node B, or Johannesburg Node JHB plus Azure Spot hourly billing while wallet/card affordability checks pass. Monthly Azure billing and the rest of the paid catalog require a saved card plus paid $5 wallet top-up, unless the account is admin or has admin-applied wallet credit.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/rewards/overview":{"get":{"tags":["Rewards"],"summary":"Admin rewards overview","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns reward wallet balances, qualification signals, Spin the Wheel campaigns, redemption rates, and recent reward ledger entries for the Reward Points admin page.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/rewards/users/{userId}/adjust":{"post":{"tags":["Rewards"],"summary":"Admin adjust reward points","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAdds or deducts reward points for a client and writes the action to the reward ledger and the client's master transaction log.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"Target user id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"direction":{"type":"string","enum":["credit","debit"]},"points":{"type":"integer","minimum":1},"note":{"type":"string","maxLength":500},"idempotencyKey":{"type":"string"}},"required":["direction","points","note"]},"example":{"direction":"credit","points":2000,"note":"Launch goodwill adjustment"}}}}}},"/api/admin/rewards/campaigns":{"post":{"tags":["Rewards"],"summary":"Create Spin the Wheel campaign","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCreates a Spin the Wheel campaign. Only clients with active paid services, a saved card, and at least $5 paid wallet top-up can see and claim active campaigns.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string"},"description":{"type":"string"},"active":{"type":"boolean"},"startsAt":{"type":["string","null"],"format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time"},"maxSpinsPerUser":{"type":"integer","minimum":1},"slices":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["name","slices"]},"example":{"name":"Launch Spin","active":true,"maxSpinsPerUser":1,"slices":[{"label":"Starter Spark","points":100,"weight":32,"color":"#22c55e"},{"label":"Launch Jackpot","points":1000,"weight":6,"color":"#111827"}]}}}}}},"/api/admin/rewards/campaigns/{campaignId}":{"put":{"tags":["Rewards"],"summary":"Update Spin the Wheel campaign","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates campaign metadata, active state, schedule, max spins, and point slices.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"},"description":"Reward campaign id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}},"delete":{"tags":["Rewards"],"summary":"Deactivate Spin the Wheel campaign","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nDeactivates a Spin the Wheel campaign without deleting historical claims.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"},"description":"Reward campaign id"}]}},"/api/admin/rewards/email/preview":{"get":{"tags":["Rewards"],"summary":"Preview rewards launch email","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRenders the formatted rewards launch email subject, HTML, and text body before sending.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/rewards/email/send":{"post":{"tags":["Rewards"],"summary":"Send rewards launch email","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSends the rewards launch email to non-admin client accounts. Failed immediate deliveries are queued through the normal email delivery queue.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"confirmSend":{"type":"boolean"},"limit":{"type":"integer","minimum":1,"maximum":5000}},"required":["confirmSend"]},"example":{"confirmSend":true}}}}}},"/api/search":{"get":{"tags":["Search"],"summary":"Customer command-palette search","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSearches the signed-in customer's services, support tickets, Pages/Workers apps, and saved deployment templates. Use the `q` query parameter with at least two characters; the response includes typed result cards and dashboard hrefs.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2},"description":"Search text."}]}},"/api/admin/search":{"get":{"tags":["Search"],"summary":"Admin global search","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSearches across users, services, support tickets, IP/vMAC assignments, and Pages/Workers apps. Admin tools use this to jump from an instance name, IP address, VMID-adjacent metadata, email address, domain, or ticket text to the affected customer profile.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2},"description":"Admin search text."}]}},"/api/service-command-center":{"get":{"tags":["Services"],"summary":"Unified service command center","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns a normalized command-center view of the customer's active services across Compute, Object Storage, Storage Box, PostgreSQL, DNS, Pages/Workers, and backup-related surfaces, including resource details, pricing options, and action availability.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/credential-center":{"get":{"tags":["Credentials"],"summary":"Credential center","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists customer-visible credentials and setup bundles that can be safely copied or rotated where supported. Passwords and secrets remain hidden unless the associated service workflow exposes them to the signed-in owner.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/forecast":{"get":{"tags":["Billing"],"summary":"Live billing forecast","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns estimated spend over upcoming windows for active services based on wallet balance, billing mode, hourly rates, monthly renewals, three-month commitments, and configured overage rules.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/runway":{"get":{"tags":["Billing"],"summary":"Wallet runway by service","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCalculates how long the customer's current wallet balance is expected to cover their active services. Client apps use this for runway meters and low-balance warnings.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/recommended-topup":{"get":{"tags":["Billing"],"summary":"Recommended top-up amount","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns a suggested wallet top-up based on active services, billing risk, upcoming renewals, and desired cover window so the UI can present a single practical top-up button.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/service-spend-history":{"get":{"tags":["Billing"],"summary":"Per-service spend graph data","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns spend-history series grouped by service for customer graphs and billing explanations. Use this to show where costs changed over time rather than only listing wallet transactions.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/hourly-savings-report":{"get":{"tags":["Admin"],"summary":"Hourly users who could save most","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRanks customers and services where converting from hourly to monthly or three-month billing would save the most money. Useful for proactive support and account-management campaigns.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/billing-risk-dashboard":{"get":{"tags":["Admin"],"summary":"Billing-risk dashboard","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns accounts likely to run out of wallet credit soon, including low-runway services and renewal risk signals. Admin dashboards use this to intervene before services are suspended.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/billing/convert-services":{"post":{"tags":["Billing"],"summary":"Convert hourly services to monthly or 3-month billing","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nConverts one or more eligible services to monthly or quarterly billing. The server calculates the required upfront charge, uses wallet funds first, and can charge a saved Stripe card for any permitted shortfall.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serviceId":{"type":"string","description":"Single service id to convert."},"serviceIds":{"type":"array","items":{"type":"string"},"description":"Multiple service ids to convert in one request."},"billingMode":{"type":"string","enum":["monthly","quarterly"],"description":"`quarterly` represents the 3-month prepaid option."}},"required":["billingMode"],"additionalProperties":false},"example":{"serviceIds":["svc_123"],"billingMode":"monthly"}}}}}},"/api/setup-assistant/{serviceId}":{"get":{"tags":["Credentials"],"summary":"Product setup assistant","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns a service-specific setup guide with copy-ready connection details, environment variables, examples, and troubleshooting hints for the selected service.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Customer service id."}]}},"/api/backups/summary":{"get":{"tags":["Backups"],"summary":"Backup summary","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the customer's backup/snapshot overview for dashboard presentation. This endpoint is intentionally summarized so product pages can show backup posture without exposing provider internals.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/deploy/preflight":{"post":{"tags":["Services"],"summary":"Deployment preflight","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the same structured eligibility checks as the deployment dialog before a customer submits an order. Use it to explain missing fields, billing restrictions, provider unavailability, trial locks, region limits, and password-policy failures.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productType":{"type":"string","description":"Product type, for example `compute`, `object_storage`, `storage_box`, or `postgresql`."},"planId":{"type":"string"},"billingMode":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"userChoiceUsername":{"type":"string"},"userChoicePassword":{"type":"string"},"rootPassword":{"type":"string"}},"required":["productType","planId"],"additionalProperties":true},"example":{"productType":"compute","planId":"plan_123","billingMode":"monthly","name":"app1"}}}}}},"/api/admin/operations-queue":{"get":{"tags":["Operations"],"summary":"Admin operations queue","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns stuck or failed operational work such as provisioning failures, cleanup retries, IP/vMAC releases, storage sync issues, Stripe webhook anomalies, and provider errors so admins can retry or investigate from one screen.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/deploy-lock":{"get":{"tags":["Operations"],"summary":"Active deployment lock snapshot","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns active long-running deployment locks so admins can see when compute clone/provisioning work is in progress and avoid accidental restarts or duplicate destructive actions.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/services/{serviceId}/recover-provisioning":{"post":{"tags":["Operations"],"summary":"Recover stuck compute provisioning","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nAttempts deterministic cleanup/recovery for a compute service stuck in pending/provisioning state, including backend-restart-aware failure messaging, billing cleanup, and provider resource cleanup where available.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Compute service id."}]}},"/api/admin/provider-capacity":{"get":{"tags":["Provider Health"],"summary":"Provider capacity dashboard","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns capacity signals across configured providers, including Proxmox node/IP pool availability, template/node readiness, storage default capacity, and other provider-health indicators used before customers hit deployment errors.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/users/{userId}/support-bundle":{"get":{"tags":["Admin"],"summary":"One-click support bundle","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nBuilds a support bundle for one customer with timeline entries, billing state, active services, recent provider errors, deployment logs, and health signals so support can diagnose an issue from one payload.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"},"description":"Customer user id."}]}},"/api/admin/compute/canary-dashboard":{"get":{"tags":["Operations"],"summary":"Canary smoke-test dashboard","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the latest pass/fail canary smoke-test status by plan and node, including repeated failures and auto-disable signals for Proxmox template readiness.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/product-plans/audit":{"get":{"tags":["Admin"],"summary":"Compute plan audit log","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists recent compute-plan create, update, activation, repair, checksum, canary, and delete audit events with before/after snapshots and changed keys.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":250},"description":"Maximum audit rows to return."},{"name":"planId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional product plan id filter."}]}},"/api/admin/product-plans/bulk-category-order":{"post":{"tags":["Admin"],"summary":"Bulk update compute plan categories and order","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates product flavor/category and sort order for multiple compute plans at once so the public catalog can be grouped into clearer families and node-priority ordering.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"productFlavor":{"type":"string"},"sortOrder":{"type":"number"}},"required":["id"],"additionalProperties":true}}},"required":["plans"]}}}}}},"/api/admin/product-plans/{planId}/canary":{"post":{"tags":["Operations"],"summary":"Enable or disable nightly canary for a plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nMarks one Proxmox compute plan as the selected nightly smoke-test canary for its node. Enabling one plan automatically disables other canaries on the same node.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"example":{"enabled":true}}}}}},"/api/admin/product-plans/{planId}/launch-checklist":{"get":{"tags":["Operations"],"summary":"Compute plan launch checklist","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the activation checklist for a compute plan, including pricing validity, Proxmox IP capacity, template smoke status, checksum drift, canary state, Windows readiness, and Node A/Node B label drift.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}]}},"/api/admin/product-plans/{planId}/smoke-tests":{"get":{"tags":["Operations"],"summary":"Smoke-test history for a plan","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists clone, boot, QGA, cloud-init, and cleanup history for a compute plan smoke test. Use `limit` to control how much history to return.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100},"description":"Number of rows to return."}]}},"/api/admin/product-plans/{planId}/refresh-checksum":{"post":{"tags":["Operations"],"summary":"Refresh template checksum","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCalculates and records the current template disk checksum for a Proxmox-backed plan. If the checksum differs from the approved checksum, the admin workflow can flag drift before customers deploy.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}]}},"/api/admin/product-plans/{planId}/approve-checksum":{"post":{"tags":["Operations"],"summary":"Approve template checksum drift","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nApproves the current Proxmox template checksum as intentional after an admin validates a template update. The optional note records the reason for the approval.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":500}},"additionalProperties":false},"example":{"note":"Approved after rebuilding the Ubuntu template."}}}}}},"/api/admin/product-plans/{planId}/smoke-test":{"post":{"tags":["Operations"],"summary":"Run template smoke test now","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nClones a temporary VM from the plan template, boots it, checks QGA/cloud-init readiness, records logs, then destroys the temporary VM automatically. Designed for admin verification before exposing a plan to customers.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}]}},"/api/admin/product-plans/{planId}/repair-template":{"post":{"tags":["Operations"],"summary":"One-click template repair validation","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the safe repair workflow for a Proxmox plan: refresh checksum, clone a temporary VM, validate QGA and cloud-init or Cloudbase/RDP readiness, update smoke status, and hide only the affected plan if validation fails.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Product plan id."}]}},"/api/admin/object-storage/instances/{serviceId}/repair-mount":{"post":{"tags":["Object Storage"],"summary":"Repair SMB bridge mount","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the admin repair action for a specific object-storage SMB bridge mount, including cache/drain/mount checks and supervised remount logic where available.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Object Storage service id."}]}},"/api/admin/storage-pricing/bulk":{"get":{"tags":["Admin"],"summary":"Bulk storage pricing editor data","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns Object Storage plans, Storage Box plans, scheduled price changes, and pricing audit logs so admins can review and adjust storage pricing in one place.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"post":{"tags":["Admin"],"summary":"Bulk update storage pricing","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nApplies or schedules storage pricing changes for Object Storage and Storage Box plans, optionally applying the new price to existing services and writing audit records/customer notices.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"changes":{"type":"array","items":{"type":"object","additionalProperties":true}},"effectiveAt":{"type":"string","format":"date-time"},"applyToExistingServices":{"type":"boolean"},"note":{"type":"string"}},"required":["changes"],"additionalProperties":true}}}}}},"/api/admin/storage-pricing/scheduled/{changeId}":{"delete":{"tags":["Admin"],"summary":"Cancel scheduled storage price change","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nCancels a pending scheduled storage pricing change before it becomes effective.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"changeId","in":"path","required":true,"schema":{"type":"string"},"description":"Scheduled price change id."}]}},"/api/storage/price-notices":{"get":{"tags":["Billing"],"summary":"Customer storage price notices","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nLists customer-facing notices generated when existing storage service rates change. The UI should show unseen notices prominently so customers understand future or applied pricing changes.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/storage/price-notices/{noticeId}/seen":{"post":{"tags":["Billing"],"summary":"Mark storage price notice seen","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nMarks one storage price-change notice as seen for the signed-in customer.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string"},"description":"Storage price notice id."}]}},"/api/admin/social-login-settings":{"get":{"tags":["Social Login"],"summary":"Google sign-in settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current Google sign-in configuration, public origin, expected authorized origins, enabled state, and warning text used by the admin social-login settings page.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"put":{"tags":["Social Login"],"summary":"Update Google sign-in settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nEnables or disables Google sign-in without changing OAuth credentials in the environment.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"googleEnabled":{"type":"boolean"}},"required":["googleEnabled"],"additionalProperties":false},"example":{"googleEnabled":true}}}}}},"/api/admin/social-login-settings/google/health":{"post":{"tags":["Social Login"],"summary":"Google sign-in health check","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nChecks whether the configured Google Client ID is present, whether Google sign-in is enabled, and what public origin must be registered in the Google Cloud console.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/compute/{serviceId}/console/health":{"get":{"tags":["Console"],"summary":"Test compute console connection","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nChecks whether the selected compute instance has a ready SSH or direct VM console target. Successful and failed checks are recorded in the service support timeline.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Compute service id."}]}},"/api/compute/{serviceId}/openvpn/reset-password":{"post":{"tags":["Compute"],"summary":"Reset OpenVPN admin password","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nResets the default `openvpn` account password inside an OpenVPN Access Server compute instance. The password must be 8-128 characters and contain no spaces.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"OpenVPN compute service id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":8,"maxLength":128},"openvpnPassword":{"type":"string","minLength":8,"maxLength":128}},"additionalProperties":false}}}}}},"/api/admin/proxmox/orphans":{"get":{"tags":["Provider Health"],"summary":"List orphan Proxmox VMs","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nScans Proxmox for WebHotel-named VMs that do not map cleanly to panel services, without sending notifications. Use this before cleanup or support investigation.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/proxmox/orphans/scan":{"post":{"tags":["Provider Health"],"summary":"Scan orphan Proxmox VMs and notify","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nRuns the orphan Proxmox VM scanner and allows configured notification paths to be triggered for newly detected unmanaged WebHotel VMs.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/email/health":{"get":{"tags":["Email"],"summary":"SMTP and email queue health","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns SMTP connectivity status and queued email-delivery counts so admins can confirm whether alerts, top-up notices, and service emails are being delivered.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/email/settings":{"get":{"tags":["Email"],"summary":"Get SMTP outgoing mail settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns the current outgoing SMTP settings with the password masked, plus SMTP health and email queue status for the Admin Outgoing Mail page.","responses":{"200":{"description":"SMTP settings, health, and queue status."}}},"put":{"tags":["Email"],"summary":"Update SMTP outgoing mail settings","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nUpdates SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_SECURE, and EMAIL_FROM in the WebHotel environment file and applies them to the running process. Leave password blank to keep the existing password or set clearPassword to true to remove it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"port":{"oneOf":[{"type":"string"},{"type":"number"}]},"username":{"type":"string"},"password":{"type":"string","description":"Optional new SMTP password. Blank keeps the current password."},"clearPassword":{"type":"boolean"},"secure":{"type":"boolean"},"from":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated SMTP settings with health and queue status."}}}},"/api/admin/email/test":{"post":{"tags":["Email"],"summary":"Send SMTP test email","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nSends a direct SMTP test email using the configured outgoing mail settings. Failed tests return an error immediately and are not hidden in the retry queue.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["toEmail"],"properties":{"toEmail":{"type":"string","format":"email"},"subject":{"type":"string"},"message":{"type":"string"}}}}}}}},"/api/admin/email/queue/process":{"post":{"tags":["Email"],"summary":"Process queued email deliveries","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nManually processes a batch of queued email deliveries. Use this after SMTP recovery or when testing retry behavior.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/admin/compute/clone-telemetry":{"get":{"tags":["Operations"],"summary":"Compute clone-duration telemetry","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns aggregate and recent clone telemetry for compute provisioning, including duration, template VMID, node, recovered-after-timeout counts, failures, and associated service/task identifiers.","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/console/{serviceId}":{"get":{"tags":["Console"],"summary":"Compute console page","description":"**Authentication:** Session cookie (`connect.sid`) or API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns an HTML console page for a compute instance (requires session).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"HTML"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/admin/console/{serviceId}":{"get":{"tags":["Console"],"summary":"Compute console page (admin)","description":"**Authentication:** Admin session cookie (`connect.sid`) or an admin user's API bearer token required.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nReturns an HTML console page for a compute instance (admin).","security":[{"bearerApiToken":[]},{"cookieAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"schema":{"type":"string"},"description":"Service id"}],"responses":{"200":{"description":"HTML"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/sso":{"get":{"tags":["SSO"],"summary":"One-click SSO","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nConsumes an emailed SSO token and creates a session, then redirects to a page.","security":[],"responses":{"302":{"description":"Redirect"},"400":{"description":"Invalid token"}}}},"/share/facebook/callback":{"get":{"tags":["Referrals"],"summary":"Facebook share callback","description":"**Authentication:** None.\n**API token flow:** Create a token from the `/api` dashboard page, optionally restrict it with scopes and IP allowlists, then send it as `Authorization: Bearer <token>` on authenticated API requests.\n**Session flow:** Browser clients can still register or log in once, persist the `connect.sid` cookie, and send it back on authenticated requests.\n**Content-Type:** Most endpoints accept and return `application/json`. Stream endpoints use `text/event-stream`.\n**Money values:** Pricing, balance, and usage charges are usually returned as USD decimal strings. Keep them as strings if you need exact accounting instead of floating-point math.\n**Async operations:** Provisioning endpoints can return quickly and continue work in the background. Use the related progress/stream endpoint when a workflow exposes one.\n**Errors:** Non-2xx responses include `{ \"message\": string }` and may include extra fields that explain the failure in more detail.\n**Retry guidance:** Safe `GET` requests can be retried. For create/order/delete actions, inspect the response first before retrying so you do not double-provision or double-charge.\n**Workflow:** Submit the request body exactly as shown in the example, keep the session cookie for follow-up calls, and inspect both `message` and endpoint-specific fields on error responses.\n\nFor programmatic API access, prefer API tokens from the `/api` dashboard page and the canonical docs host at `https://api.webhotel.cloud/docs`.\n\nOAuth callback for the Facebook share flow (used by referral sharing).","security":[],"responses":{"302":{"description":"Redirect"},"400":{"description":"Invalid request"}}}}},"servers":[{"url":"https://api.webhotel.cloud","description":"Canonical public API host"},{"url":"https://webhotel.cloud","description":"Primary web application host (same API behind the panel)"}]}