# BlazingFast documentation

> Public guides for VPS, dedicated servers, hosting, domains, DNS, Website Protection, TCP Proxy, billing, API, CLI and MCP.

Use current documented scopes and account-owned resource IDs. Draft orders require separate invoice payment; the atomic deploy endpoint charges the full final order amount to the account balance and queues provisioning in one request. Never include private keys, passwords or bearer tokens in prompts or logs. Product availability and prices must be obtained from the authenticated API, not inferred from examples.

## API and automation

SDK/CLI 0.1.17. Check GET /v1/version and GET /v1/capabilities before using optional workflow features. Strict response validation is enforced.

- [Customer OpenAPI schema](https://docs.blazingfast.io/api/public/openapi/userapi-v1): All public endpoint contracts, permissions and documented response examples.
- [Full public documentation](https://docs.blazingfast.io/llms-full.txt): Published guides and the complete customer API reference in plain Markdown.
- [SDK checksums](https://docs.blazingfast.io/sdk/SHA256SUMS): Published PHP, Node.js, Python and Go SDK archives.

## Guides

- [Create your account](https://docs.blazingfast.io/howto/registration-login/account-registration-and-secure-access.md): Set up your account with email, Google, GitHub, or a passkey.
- [Sign in and recover access](https://docs.blazingfast.io/howto/registration-login/login-sessions-and-access-recovery.md): Use verification, trusted devices, and recovery options to regain access safely.
- [Manage your profile](https://docs.blazingfast.io/howto/account/customer-portal-and-profile-management.md): Keep your contact, company, and billing details accurate.
- [Secure your account](https://docs.blazingfast.io/howto/account/service-credentials-console-and-vm-operations.md): Protect your account and keep portal, API, and service credentials separate.
- [Choose how to manage your services](https://docs.blazingfast.io/howto/api/api-overview-related-guides-and-next-steps.md): Connect an AI assistant, use the command line, or build an integration with an SDK.
- [What you can automate by product](https://docs.blazingfast.io/howto/api/product-automation-coverage.md): Compare public API, CLI, hosted MCP and local MCP coverage before building an integration.
- [Create an API key and connect securely](https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security.md): Create a key, select its permissions, configure credentials and make a first read.
- [Connect ChatGPT or another AI assistant](https://docs.blazingfast.io/howto/api/connect-ai-assistant.md): Sign in, choose what the assistant can access, and manage approvals in your dashboard.
- [Install an SDK or the command-line tool](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns.md): Download Python, Node.js, PHP or Go, configure an API key and list your services.
- [Machine-readable purchase and operation recovery](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery.md): Discover purchase requirements, request canonical receipts and recover a lost write response safely.
- [Use the CLI on Windows, macOS and Linux](https://docs.blazingfast.io/howto/api/cli-workflows.md): Install the Python CLI, configure credentials and follow read-first product workflows.
- [Connect a local MCP client](https://docs.blazingfast.io/howto/api/local-mcp.md): Run the Python MCP server locally with an API key and understand its tool and credential limits.
- [Create an order and pay from account balance](https://docs.blazingfast.io/howto/api/order-and-pay-from-balance.md): Discover valid locations and OS choices, review the price, create an unpaid order and pay separately.
- [Create DNS zones and manage Website Protection](https://docs.blazingfast.io/howto/api/dns-and-protection-automation.md): Start with an empty zone, template, JSON or zone file, then inspect records and protection.
- [API integration guide](https://docs.blazingfast.io/api/integration-guide.md): Use SDKs, authenticate requests, paginate results and handle retries, idempotency and webhooks.
- [Troubleshoot API and AI connections](https://docs.blazingfast.io/howto/api/automation-troubleshooting.md): Resolve missing tools, denied access, expired keys and uncertain changes without repeating actions.
- [API endpoint reference](https://docs.blazingfast.io/api/reference.md): Find each public endpoint's parameters, required permissions and responses.
- [Orders, invoices, and payments](https://docs.blazingfast.io/howto/billing/orders-invoices-and-payment-methods.md): Review orders and invoices, then pay with an available payment method.
- [Renewals, upgrades, and overdue invoices](https://docs.blazingfast.io/howto/billing/renewals-upgrades-refunds-and-overdue-lifecycle.md): Keep services active and understand renewals, upgrades, refunds, and overdue invoices.
- [Manage your services](https://docs.blazingfast.io/howto/services/service-operations-overview.md): Find the right place to manage each product in your customer portal.
- [Manage a VPS](https://docs.blazingfast.io/howto/services/vps-lifecycle-network-access-and-backups.md): Control power, access, reinstall, snapshots, backups, and firewall settings.
- [Manage a dedicated server](https://docs.blazingfast.io/howto/services/manage-dedicated-server.md): Check installation progress, IP addresses, power, operating systems and task history.
- [Use cPanel web hosting](https://docs.blazingfast.io/howto/services/manage-web-hosting.md): Find hosting access, manage websites and email in cPanel, and understand automation limits.
- [Manage DNS and website protection](https://docs.blazingfast.io/howto/services/dns-waf-and-proxy-management.md): Manage DNS records, proxying, website protection, origins, and SSL settings.
- [Manage TCP Proxy](https://docs.blazingfast.io/howto/services/manage-tcp-proxy.md): Configure your backend and ports, review traffic, and change access rules safely.
- [Domains and nameservers](https://docs.blazingfast.io/howto/services/domains-and-dns-zone-operations.md): Register or transfer domains and manage contacts, nameservers, and DNS zones.
- [Storage volumes and backups](https://docs.blazingfast.io/howto/services/storage-volumes-backups-and-object-roadmap.md): Attach storage, manage backup capacity, and understand what each storage type is for.
- [Affiliate links and rewards](https://docs.blazingfast.io/howto/affiliate-program/referrals-rewards-and-earned-balance.md): Share your link and track visits, customers, purchases, and rewards.

## Product briefs

- [00-index.txt](https://docs.blazingfast.io/docs/products/00-index.txt)
- [01-vps.txt](https://docs.blazingfast.io/docs/products/01-vps.txt)
- [02-dedicated-servers.txt](https://docs.blazingfast.io/docs/products/02-dedicated-servers.txt)
- [03-web-hosting.txt](https://docs.blazingfast.io/docs/products/03-web-hosting.txt)
- [04-domains.txt](https://docs.blazingfast.io/docs/products/04-domains.txt)
- [05-dns.txt](https://docs.blazingfast.io/docs/products/05-dns.txt)
- [06-website-protection.txt](https://docs.blazingfast.io/docs/products/06-website-protection.txt)
- [07-tcp-proxy.txt](https://docs.blazingfast.io/docs/products/07-tcp-proxy.txt)
- [08-storage.txt](https://docs.blazingfast.io/docs/products/08-storage.txt)
- [09-backups-snapshots.txt](https://docs.blazingfast.io/docs/products/09-backups-snapshots.txt)
- [10-ssh-firewall.txt](https://docs.blazingfast.io/docs/products/10-ssh-firewall.txt)
- [11-billing-orders.txt](https://docs.blazingfast.io/docs/products/11-billing-orders.txt)
- [12-affiliates-partnerships.txt](https://docs.blazingfast.io/docs/products/12-affiliates-partnerships.txt)
- [13-catalog-discovery.txt](https://docs.blazingfast.io/docs/products/13-catalog-discovery.txt)
- [14-integration-workflows.txt](https://docs.blazingfast.io/docs/products/14-integration-workflows.txt)

---

# Create your account



Source: https://docs.blazingfast.io/howto/registration-login/account-registration-and-secure-access



Set up your account with email, Google, GitHub, or a passkey.



## Choose the sign-in method that fits how you work

You can create your account with email, Google, GitHub, or a passkey on supported devices. Your portal login is used for billing, services, and support. API keys and service passwords are managed separately.

[Verification and recovery](https://docs.blazingfast.io/howto/registration-login/login-sessions-and-access-recovery)
[Account security settings](https://docs.blazingfast.io/howto/account/service-credentials-console-and-vm-operations)

## Good first step

Use one clearly owned account for your business or team. After the first login, add stronger protection such as passkeys or TOTP. Keep API keys and service credentials separate from portal login.

# Create your account and choose a sign-in method

The customer portal supports several sign-in methods, so you are not limited to email and password. Your portal account owns billing, services, and support access. Automation keys and service credentials are separate and should be managed separately.

## Before you start

- Decide which account should own billing, services, and support for your business or team.
- Choose one primary sign-in method first.
- Add stronger login options after your first successful sign-in.
- Do not use API keys or service passwords as a replacement for portal login.

## Recommended order

1. create or claim the main customer account for the business
2. complete email verification or finish the chosen OAuth or passkey signup flow
3. land in the portal and confirm the profile and billing identity
4. add stronger login protection such as TOTP or passkeys
5. create API keys separately only if you need automation

## Supported signup and sign-in paths

- Sign up with email and complete the verification step that follows.
- Continue with Google when that provider flow is available.
- Continue with GitHub when that provider flow is available.
- Use passkeys on supported devices for passwordless account creation or sign-in.

## What happens during email signup

When you register with email, the platform creates the customer identity and starts a verification step. That matters because the same account later owns invoices, wallet balance, services, settings, support context, and optional API access.

In practice, the flow looks like this:

1. Enter your email address and accept the terms shown in the signup form.
2. Complete the verification code step sent to your email.
3. Finish the first sign-in and land in the customer portal.
4. Add profile and billing details before placing production orders.

If the email is already taken, the platform does not create a duplicate account. Instead, it points you back to sign in.

## OAuth and passkeys

Google and GitHub OAuth are supported sign-in paths. They are useful when the team already manages access through those providers and wants less password handling.

Passkeys are also part of the customer login experience. On compatible devices they provide a passwordless option that is faster to use and more resistant to phishing than a password-only flow.

## What this account is for

Your portal account is the identity used for billing, services, and support. It is used for things like:

- viewing and paying invoices
- managing profile and billing details
- tracking services and service status
- using referral features
- configuring login security such as password, TOTP, passkeys, and linked OAuth accounts

It is not the same thing as an API key, and it should not be confused with any service-specific credential you may receive later for a provisioned product.

---

# Sign in and recover access



Source: https://docs.blazingfast.io/howto/registration-login/login-sessions-and-access-recovery



Use verification, trusted devices, and recovery options to regain access safely.



## Sign in securely without making daily access difficult

You can sign in with a password, magic link, Google, GitHub, or passkeys. Some accounts may also ask for an email code or authenticator-app code before opening the portal.

[Security settings](https://docs.blazingfast.io/howto/account/service-credentials-console-and-vm-operations)

# Login, verification, trusted devices, and recovery

The login system supports several sign-in methods and more than one verification option. Choose the method that gives your team the right balance of speed and security.

## Before you start

- normal sign-in is self-service
- stronger account recovery may require support review
- TOTP can replace email codes when it is enabled on the account
- trusted devices can reduce repeat prompts when policy allows it
- recovery codes should be stored somewhere secure and reachable

## Recommended order when signing in

1. start with the normal sign-in method your team uses most often
2. complete email OTP or TOTP when the login flow requests it
3. if the portal still looks logged out, check browser cookies, environment, and email delivery basics
4. if normal sign-in no longer works, contact support for recovery instead of trying unsafe workarounds

## Available sign-in methods

- email and password
- Google sign-in
- GitHub sign-in
- magic link sent to your email
- passkey sign-in on supported devices

## Verification after login

Some sign-ins continue with an extra verification step. The portal currently supports:

- email OTP codes
- authenticator-app based TOTP
- trusted device handling so you do not have to repeat the same step on every login when policy allows it

If TOTP is enabled on the account, the login flow can go directly to authenticator-app verification instead of email OTP.

## Magic links

Magic links are useful when you want to sign in quickly without typing a password. You enter your email address, request the link, and complete the login from your mailbox.

The flow is deliberately cautious about account discovery. It does not use the magic-link response to reveal whether an address exists.

## Sessions and browsers

Customer access is session-based in the browser. That means a successful login gives the portal an active session used for dashboard, services, invoices, settings, and other customer pages.

If sign-in seems to succeed but the portal still behaves as logged out, check these things first:

1. browser cookies are allowed
2. you completed the full OTP or TOTP step when prompted
3. you are signing in on the correct environment
4. your email provider is not delaying OTP or magic-link delivery

## Recovery today

Some recovery cases need support review instead of an instant self-service reset. This protects the account from takeover attempts and gives support a chance to verify ownership correctly.

That means the right expectation today is:

- normal login is self-service
- stronger account recovery is handled with support review

## Recommended team practice

- keep at least one well-controlled owner account for the business
- enroll passkeys for regular users where possible
- enable TOTP if you need stronger login protection
- keep recovery codes somewhere the team can reach during an incident
- do not treat API keys or service passwords as a workaround for portal recovery

---

# Manage your profile



Source: https://docs.blazingfast.io/howto/account/customer-portal-and-profile-management



Keep your contact, company, and billing details accurate.



## Keep your account details accurate

Your account connects services, invoices, wallet balance, support history, and login security. Keeping it current makes billing, support, and recovery much easier.

[Invoices and payments](https://docs.blazingfast.io/howto/billing/orders-invoices-and-payment-methods)
[Service overview](https://docs.blazingfast.io/howto/services/service-operations-overview)

# Portal profile, ownership, and account details

Your customer account is the main record for your services and billing. It connects profile details, billing identity, service visibility, wallet balance, invoices, and support history.

## Before you start

- the customer account is used for invoices, ownership checks, and service visibility
- one business, brand, or team should have a clear account owner
- your team should know who approves billing, recovery, and day-to-day service changes

## Recommended review order

1. confirm the primary email address and owner contact
2. confirm the company or legal name that should appear on invoices
3. confirm the billing country, address, and other identity details used for invoicing
4. confirm which people inside the team own billing, recovery, and service decisions

## What you manage here

- contact and owner details
- company or business identity details when the account is used for a business
- billing-related identity data used for invoices
- account-level visibility into services, invoices, and wallet state
- customer profile and language settings

## Why this matters

If account ownership, billing ownership, and service ownership become unclear, even simple requests can take longer. Support may need to ask more questions, invoices may use the wrong details, and your team may lose time during renewals or recovery.

Keeping profile data current helps with:

- cleaner invoice issuance
- faster ownership checks
- clearer service history
- less confusion during renewals, disputes, or recovery cases

## A sensible operating model

For most teams, the best setup is one clearly owned customer account per company, brand, or internal tenant. Use that account as the source of truth for the services and invoices that belong together.

If several people work inside the same environment, document internally who is responsible for:

- billing approvals
- day-to-day service operations
- API automation
- account recovery decisions

---

# Secure your account



Source: https://docs.blazingfast.io/howto/account/service-credentials-console-and-vm-operations



Protect your account and keep portal, API, and service credentials separate.



## Keep portal identity separate from workload credentials

Portal login controls account access, billing actions, and settings. Service consoles, API keys, SSH access, and workload credentials are separate and should be handled separately.

[VPS operations](https://docs.blazingfast.io/howto/services/vps-lifecycle-network-access-and-backups)

## Important boundary

Changing your portal password does not replace API keys or service credentials. Each access type exists for a different job and should be managed separately.

# Security settings and service access

After your first sign-in, decide how the account should be protected and how your team should access services without mixing portal login with workload credentials.

## Important boundary

- portal login controls account access, billing actions, and account settings
- API keys are for automation and should be managed like integration secrets
- service consoles, SSH access, and workload credentials belong to the individual service they operate
- rotating one access type does not automatically replace the others

## Recommended security order

1. keep one strong owner account for the organization
2. add passkeys for frequent portal users on supported devices
3. enable TOTP for accounts with billing or production impact
4. store recovery codes somewhere secure and reachable during incidents
5. keep API secrets and service credentials in separate secrets storage

## Security features available in account settings

Account settings currently support these security controls:

- set or change a password
- enable passkeys and manage saved passkeys
- link or unlink supported OAuth accounts such as Google and GitHub
- enable or disable TOTP-based two-factor authentication
- download and retain recovery codes when TOTP is enabled

## What recovery codes are for

When you enable TOTP, the setup flow provides one-time recovery codes. Save them somewhere safe. They are meant for the moment when you lose access to the authenticator app, not for everyday login.

## Service access is different from portal login

Some services expose their own actions, consoles, or credentials after provisioning. That access is about operating the service itself. Your portal account is still the customer identity that owns the invoices, settings, and account-level permissions.

That separation is useful because it lets you:

- keep ownership tied to the customer account
- limit who can operate a workload directly
- rotate service access without changing the core customer identity

## A simple rule to follow

Use the portal account for customer administration. Use service-specific access only for the service it belongs to.

---

# Choose how to manage your services



Source: https://docs.blazingfast.io/howto/api/api-overview-related-guides-and-next-steps



Connect an AI assistant, use the command line, or build an integration with an SDK.



Use the portal, an AI assistant, or API tools for scripts and applications.

## Current API, CLI and MCP release

SDK/CLI 0.1.17 and contract 2026-10-07.1 document 182 customer API operations. Download the immutable Python, Node.js, PHP or Go archives and verify SHA256SUMS. The Python archive includes both `bf` and `bf-api`, plus the local `bf-api-mcp` server.

Start with `bf version`, `bf capabilities` and `bf regions`. Production uses `https://api.blazingfast.io` and download links in the [installation guide](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns). Configure the origin without /v1.

CLI lifecycle commands generally make write keys optional; DNSSEC enable/disable require an explicit --request-key. Where optional: the CLI saves and prints a generated key before sending when omitted. Preserve that key for explicit retries; inspect an unknown outcome before retrying. Read requests do not create write receipts.

Hosted MCP uses `https://mcp.blazingfast.io/mcp` and OAuth with your selected scopes and connection policy. Local MCP uses your API key and exposes read-only tools by default. Existing OAuth connections need fresh consent for additional scopes.

Read the [full endpoint map](https://docs.blazingfast.io/docs/api-endpoints.html) and use `GET /v1/version` plus `GET /v1/capabilities` to check deployed availability. Check GET /v1/version and GET /v1/capabilities before using optional workflow features. Strict response validation is enforced. Use capability discovery and your account permissions to check which workflows are available.

## Current purchase and operation workflows

SDK/CLI 0.1.17 supports contract 2026-10-07.1. Read GET /v1/version and GET /v1/capabilities, then discover product purchase policies and requirements before configuring a purchase. A quote is optional: discovery can lead directly to an authorized deployment. Quotes do not reserve stock or lock prices; send an authorized max_total ceiling for the full final order amount.

Draft order creation does not charge the account. Atomic deployment is the documented exception: it combines order creation, payment of the full final order amount from account balance and queued provisioning. Paid is not ready; accepted is not completed. Service lifecycle status is separate from runtime power state.

Supported tracked deployment, VPS and dedicated writes can return a canonical operation receipt and be recovered using their original idempotency key. This does not extend recovery to every write or historical request. See [HTTP, SDK, CLI and MCP examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery). DNSSEC uses its separate endpoint and state contract.

## Choose a starting point

| What you want to do | Start here | What you need |
| --- | --- | --- |
| Ask ChatGPT about your services | [Connect an AI assistant](https://docs.blazingfast.io/howto/api/connect-ai-assistant) | Your BlazingFast account |
| Run commands from a terminal | [Install an SDK or the CLI](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns) | Python 3.10+ and an API key |
| Call the API from your application | [Install an SDK](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns) | Python, Node.js, PHP or Go and an API key |
| Build a custom HTTP client | [API reference](https://docs.blazingfast.io/howto/api/api-workflows-sdks-and-integration-patterns) | API authentication and HTTP experience |

MCP is the connection protocol that lets an AI assistant use BlazingFast tools. The hosted connection uses your BlazingFast sign-in. The local MCP server is installed on your computer and uses an API key.

## CLI names

Use bf for new integrations. bf-api is an actively supported compatibility alias of the same CLI, not a separate lower-level interface. Both are included in the Python SDK package and use the same commands, authentication and version.

## Make your first read

For an AI connection, ask: “Show my services, their status, IP addresses and paid-through dates.”

For the CLI, run `bf service list` after following the installation guide. This lists services without changing them. Select the returned service ID when a command needs one; do not guess an ID.

## What you can manage

Available actions depend on the services you own and the permissions you grant. They include billing and invoices, VPS and dedicated servers, DNS and Website Protection, domains, TCP Proxy, public SSH keys, firewall policies, and storage volumes.

Start with viewing permissions. Add the specific change permissions your workflow needs in [API keys](https://my.blazingfast.io/settings/api) or [AI connections](https://my.blazingfast.io/settings/connections).

## Continue with a task

- [Compare API, CLI and MCP support by product](https://docs.blazingfast.io/howto/api/product-automation-coverage).
- [Use the CLI on Windows, macOS and Linux](https://docs.blazingfast.io/howto/api/cli-workflows).
- [Connect a local MCP client](https://docs.blazingfast.io/howto/api/local-mcp).
- [Browse products, create an order and pay an invoice](https://docs.blazingfast.io/howto/api/order-and-pay-from-balance).
- [Create a DNS zone and manage protection](https://docs.blazingfast.io/howto/api/dns-and-protection-automation).
- [Resolve connection and API errors](https://docs.blazingfast.io/howto/api/automation-troubleshooting).

---

# What you can automate by product



Source: https://docs.blazingfast.io/howto/api/product-automation-coverage



Compare public API, CLI, hosted MCP and local MCP coverage before building an integration.



Choose the product first, then the interface. The public API, Python CLI, hosted MCP and local MCP are separate interfaces: an endpoint being available does not mean every client exposes it.

Contract 2026-10-07.1 describes 182 public operations, SDK/CLI 0.1.17 and hosted MCP. Check [all endpoint contracts](https://docs.blazingfast.io/docs/api-endpoints.html), `GET /v1/version` and `GET /v1/capabilities` for deployed availability. Supported actions also depend on provider availability. Product availability, stock, prices, operating systems and permissions remain account-specific; discover them at request time.

## CLI names

Use bf for new integrations. bf-api is an actively supported compatibility alias of the same CLI, not a separate lower-level interface. Both are included in the Python SDK package and use the same commands, authentication and version.

## Current purchase and operation workflows

SDK/CLI 0.1.17 supports contract 2026-10-07.1. Read GET /v1/version and GET /v1/capabilities, then discover product purchase policies and requirements before configuring a purchase. A quote is optional: discovery can lead directly to an authorized deployment. Quotes do not reserve stock or lock prices; send an authorized max_total ceiling for the full final order amount.

Draft order creation does not charge the account. Atomic deployment is the documented exception: it combines order creation, payment of the full final order amount from account balance and queued provisioning. Paid is not ready; accepted is not completed. Service lifecycle status is separate from runtime power state.

Supported tracked deployment, VPS and dedicated writes can return a canonical operation receipt and be recovered using their original idempotency key. This does not extend recovery to every write or historical request. See [HTTP, SDK, CLI and MCP examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery). DNSSEC uses its separate endpoint and state contract.

## Product coverage

| Product | Public API | Python CLI | Hosted MCP | Local MCP |
| --- | --- | --- | --- | --- |
| VPS | Status, scoped recorded credentials, browser-console link, power, reinstall, password reset, SSH keys, firewall, snapshots and backups | `bf vps` | Status, browser-console link, power, reinstall, firewall, snapshots and backups; no passwords | Status, console link, snapshots/backup reads, opt-in credentials and power writes; no full management parity |
| Dedicated servers | Catalog, unpaid deployment, status, credentials, browser-console link, power, reinstall, rescue, password reset, tasks and statistics | `bf dedicated` | Status, console link, power, reinstall, rescue, tasks and statistics; no dedicated deployment or password/credential tool | Dedicated catalog/deployment/status/console/tasks/options/statistics; credentials and writes are separately opt-in |
| DNS | Zones, records, imports/previews and templates | `bf dns` | Zones, records, templates, import preview and creation | Zone/record reads and basic opt-in zone/record writes; no template/import-preview tools |
| Website Protection | Record protection, proxy/origin settings, SSL/custom loading page and country policy | `bf dns protection`, `dns country-policy`, `service dns waf` | Safe settings, record protection, proxy/origin and country changes | No dedicated Website Protection tools |
| TCP Proxy | Backend, ports, limits, source/country rules and traffic statistics | `bf tcp-proxy` | Configuration/statistics and backend, port and access-policy changes | No dedicated TCP Proxy tools |
| Domains | Availability, catalog, owned domains, contacts, nameservers, transfer status, lock, privacy, authorization code and DNSSEC | `bf domain` | Owned domain/status/transfer reads; nameserver, lock and privacy changes | Availability/catalog/contact/status/DNSSEC reads; DNSSEC update is separately opt-in |
| Storage volumes | List, eligible attach targets, attach, detach and rename | `bf storage` list/attach-options/attach/detach/rename | List, attach options and attach/detach/rename | Volume listing only |
| cPanel hosting | Generic service/catalog/billing operations, not cPanel website/mail/file administration | `bf service` and `billing` | Generic service and billing tools | Generic service and billing reads |
| Billing | Catalog/options, quotes, orders, invoices, balance payments and transactions | `bf billing`; selected service settings | Products, VPS order options, unpaid orders, balance payment, invoices and transactions | Balance/invoice reads; no generic order/payment tools |
| SSH keys and firewall | Key and policy management; applying supported settings to VPS | `bf ssh`, `firewall`, `vps` | Public key and firewall policy reads/changes | Key/policy listing only |

Local MCP viewing tools are enabled by default. Its write tools require `BF_API_MCP_ENABLE_MUTATIONS=1` and the corresponding API-key permissions. Hosted MCP uses OAuth and the selected connection policy instead. Tool names also differ: hosted `get_vps_status` versus local `bf_vps_status`.

## Important boundaries

- Draft orders and invoice payment are separate requests. The atomic `POST /v1/deploy/...` workflow pays the full amount from wallet credit and queues provisioning in one request. Quote optionally; inspect the final invoice before authorizing balance payment. Catalog options do not reserve capacity.
- Dedicated installation may require administrator approval. Service lifecycle (active/suspended/terminated), server power and installation tasks are different states.
- DNS zone creation does not register a domain or switch its registrar nameservers. Website Protection is not the same as proxy routing.
- Registered-domain DNSSEC is available through the public HTTP API: read/refresh with domains.read; enable/disable with domains.write, acknowledgement and a stable retry key. HTTP 202 is asynchronous; poll the same domain’s DNSSEC status. See the [DNSSEC workflow](https://docs.blazingfast.io/api/integration-guide#dnssec). SDK/CLI 0.1.17 includes DNSSEC commands and local MCP tools; hosted MCP has none.
- API/CLI/MCP console tools return login-protected browser links, not raw VNC connections. The browser checks account ownership before connecting. cPanel administration remains dashboard-specific. Hosted MCP never returns passwords or private keys.
- Connectivity and extra-IP options depend on the selected dedicated product and provisioning support. A recorded bandwidth entitlement is not proof that a network rate limit has been applied.
- Do not assume customer S3/object-storage, license-management, affiliate or reseller administration APIs. Only the advertised catalog and documented customer routes are supported. Snabb is a separate platform and does not use these tools.

## Service filters and access

Use `GET /v1/services?status=suspended&type=vps,dedicated` to list suspended VPS and dedicated services. Filters are applied before pagination; `status=all` includes all lifecycle states. Safe summaries include recorded hostname and service type, never passwords.

VPS `GET /v1/vps/{serviceId}/credentials` requires `vps.credentials.read`; dedicated credential reads require `dedicated.credentials.read`. A VPS password is the platform record, not a live guest verification, and can become stale after a manual OS change. Handle credential responses privately.

## Download a brief

Each plain-text brief includes purpose, API routes, working CLI examples, hosted/local MCP coverage and limits. Start with the [brief index](https://docs.blazingfast.io/docs/products/00-index.txt), then download the product you need:

- [VPS](https://docs.blazingfast.io/docs/products/01-vps.txt) · [Dedicated servers](https://docs.blazingfast.io/docs/products/02-dedicated-servers.txt)
- [cPanel hosting](https://docs.blazingfast.io/docs/products/03-web-hosting.txt) · [Domains](https://docs.blazingfast.io/docs/products/04-domains.txt)
- [DNS](https://docs.blazingfast.io/docs/products/05-dns.txt) · [Website Protection](https://docs.blazingfast.io/docs/products/06-website-protection.txt)
- [TCP Proxy](https://docs.blazingfast.io/docs/products/07-tcp-proxy.txt) · [Storage volumes](https://docs.blazingfast.io/docs/products/08-storage.txt)
- [Backups and snapshots](https://docs.blazingfast.io/docs/products/09-backups-snapshots.txt)
- [SSH keys and firewall](https://docs.blazingfast.io/docs/products/10-ssh-firewall.txt) · [Billing and orders](https://docs.blazingfast.io/docs/products/11-billing-orders.txt)
- [Affiliate rewards and partnerships](https://docs.blazingfast.io/docs/products/12-affiliates-partnerships.txt)
- [Catalog discovery](https://docs.blazingfast.io/docs/products/13-catalog-discovery.txt) · [Integration workflows](https://docs.blazingfast.io/docs/products/14-integration-workflows.txt)

Current briefs: [Catalog discovery](https://docs.blazingfast.io/docs/products/13-catalog-discovery.txt) and [Integration workflows](https://docs.blazingfast.io/docs/products/14-integration-workflows.txt).

Read [authentication](https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security), [CLI workflows](https://docs.blazingfast.io/howto/api/cli-workflows) and [local MCP](https://docs.blazingfast.io/howto/api/local-mcp) before making changes.

---

# Create an API key and connect securely



Source: https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security



Create a key, select its permissions, configure credentials and make a first read.



API keys let your scripts and applications access your account. Your portal password is not an API key. Hosted AI connections use a separate sign-in and permission flow.

## Create a key

1. Open [Settings → API](https://my.blazingfast.io/settings/api) and choose **Create API key**.
2. Give the key a recognizable name, such as “Invoice reports”.
3. Choose signed authentication for an SDK or the CLI, and select the viewing permissions you need.
4. Set an expiry date and create the key.
5. Save the key prefix and the one-time secret in your application's private configuration.

The secret is shown once. If you lose it, create a replacement key. API keys inherit account and project access rules and do not grant access to another customer's services.

## Configure the SDK or CLI

Copy the API origin displayed in [Settings → API](https://my.blazingfast.io/settings/api) for the portal you are using. The public production origin is `https://api.blazingfast.io`, used in the example below. Do not append `/v1`; SDK methods add the route.

Set these environment variables using your terminal or application's private settings:

```dotenv
BF_API_BASE_URL=https://api.blazingfast.io
BF_API_KEY=YOUR_KEY_PREFIX
BF_API_SECRET=YOUR_ONE_TIME_SECRET
```

Use the actual key values only in your private configuration. Do not paste them into chat or commit them to a repository. Environment files are not loaded automatically by the SDK; your shell or application must load them.

For a bearer-mode key, set `BF_API_BEARER` to the complete token issued for that key. Use that instead of signed-key credentials.

## Choose permissions for a task

| Task | Required permissions |
| --- | --- |
| List services and their billing status | `billing.services.read` |
| Read VPS status and backups | `vps.read` |
| Read dedicated server status | `dedicated.read` |
| Browse products, prices and order options | `billing.products.read` |
| Create a new unpaid order | `billing.order.create` |
| Read invoices and account balance | `billing.invoices.read`, `billing.balance.read` |
| Pay your invoice from account balance | `billing.invoice.pay` |
| Read or change DNS and Website Protection | `dns.read` / `dns.write` |
| Read or change TCP Proxy | `tcp_proxy.read` / `tcp_proxy.write` |

The endpoint reference lists permissions for other tasks. Viewing and changing are separate permissions; selecting a write permission does not imply every read permission.

## API keys and AI connection policies

API-key calls run directly when the key and your account have the required access. They do not wait for AI dashboard approval.

Hosted AI connections have their own permission checkboxes and policy: **Read only**, **Write with approval**, or **Full access**. Manage those in [AI connections](https://my.blazingfast.io/settings/connections). Changing an API key does not change an AI connection.

## Keep access current

Use one key per integration so you can identify and revoke it independently. If you add an IP restriction, allow the public outgoing address of the computer running the integration. Review expiry and permissions when a team or application changes. Usage logs in Settings → API show request outcomes.

## Building signed HTTP requests yourself

SDKs sign requests for you. A custom client sends `x-api-key`, `x-ts` (Unix seconds), `x-nonce`, `x-content-sha256` and `x-signature`.

Hash the exact request body with SHA-256 and encode the digest in Base64. For an empty body, hash zero bytes. Build the following canonical string with newline separators and no final newline:

```text
UPPERCASE_HTTP_METHOD
/path?exact_query_string
unix_timestamp
unique_nonce
body_sha256_base64
```

Compute HMAC-SHA256 over that string using the issued secret, then encode the signature in Base64. Keep the original body and query string unchanged after signing, and use a fresh timestamp and nonce for each HTTP attempt. Send Unix seconds within 120 seconds of the server clock. A nonce is 8–200 characters; use a cryptographically random value and never reuse it for the same credential. Reuse is rejected for at least the 300-second replay window. Malformed headers return HTTP 401 with error.code=unauthorized; stale timestamps, replayed nonces, body-hash mismatches and invalid signatures return HTTP 401 with error.code=invalid_signature. Resynchronize your clock and sign a fresh attempt; preserve the original idempotency key for a write. A retry key identifies the action separately from the nonce.

---

# Connect ChatGPT or another AI assistant



Source: https://docs.blazingfast.io/howto/api/connect-ai-assistant



Sign in, choose what the assistant can access, and manage approvals in your dashboard.



The hosted connection lets a compatible AI assistant inspect and manage your BlazingFast services. You do not need to install an SDK or create a personal API key.

## Connect your account

1. Open [Settings → API → MCP](https://my.blazingfast.io/settings/api) and copy the hosted MCP endpoint.
2. Add BlazingFast to your AI client. If you are creating a custom ChatGPT connection, use its MCP connection flow and paste the endpoint you copied from Settings → API.
3. Select OAuth authentication and complete the BlazingFast sign-in and consent screen.
4. Select the permissions you want to grant.
5. Open a new conversation, select the BlazingFast app, and ask it to list your services.

Custom ChatGPT connections depend on your plan and workspace settings. OpenAI's [connection instructions](https://developers.openai.com/plugins/build/app-quickstart#connect-your-mcp-server-in-chatgpt) describe the current setup. If a client requires an OAuth client ID and secret, use the credentials registered for that client; contact support if they have not been issued. A personal API key or your account password will not work in those fields.

## Choose an access policy

Open [Settings → AI connections](https://my.blazingfast.io/settings/connections), select the connection, and use the on/off checkboxes to choose permissions.

| Policy | Viewing | Changes |
| --- | --- | --- |
| Read only | Selected viewing permissions | Blocked |
| Write with approval | Selected viewing permissions | Wait for your dashboard approval |
| Full access | Selected viewing permissions | Execute automatically when permitted |

Full access requires acknowledgement because selected actions can spend balance, interrupt a server, reinstall it, or terminate a service. Your AI client may also ask for confirmation.

Older connections keep their previous rules until you save a new policy. In **Write with approval**, even starting a server, creating an order and paying an invoice require approval. Check the policy shown on your connection when an action is blocked.

## Try a first request

- “Show my VPS status, installed OS and IP addresses.”
- “List unpaid invoices and my account balance.”
- “Show the DNS records for example.com.”
- “Find VPS plans available in the Netherlands with Ubuntu, and show the monthly price.”

The assistant can resolve a service from your list using its hostname or IP. If several services match, select the intended one. IP addresses, installed OS and usage may be unavailable for some services; missing values are not zero.

## Approve and track a change

Under Write with approval, review the target and requested change in AI connections. Approve or reject the pending request there. The assistant should track the returned operation request rather than submitting the same action again.

Draft order creation produces an unpaid invoice, followed by a separate payment request. Atomic `POST /v1/deploy/...` instead authorizes payment of the full final order amount from account balance and queued provisioning in the same request. A balance payment can activate provisioning and may be partial if the available balance does not cover the outstanding amount.

## Purchase discovery and execution recovery

Hosted MCP uses https://mcp.blazingfast.io/mcp and your OAuth connection policy. Local MCP uses the installed SDK/CLI 0.1.17 and your API credentials. Discover the tools actually exposed by the client; their names differ:

- Optional quote: hosted quote_product_variant; local bf_product_variant_quote.
- Execution receipt: hosted get_operation; local bf_operation_get.
- Original-key recovery: hosted recover_operation; local bf_operation_recover.

For both recovery tools, the argument is idempotency_key, even though hosted write tools use request_key. This example recovers an existing VPS reboot; substitute the exact original key and owned service UUID:

```json
{
  "idempotency_key": "ORIGINAL_KEY",
  "method": "POST",
  "path": "/v1/vps/SERVICE_UUID/reboot"
}
```

Recovery is read-only and does not repeat a mutation. Supply method and path together when needed and credential_id only to select the original credential. Reads require current account access and the matching operation-read scope.

Hosted deploy_product is the preferred canonical atomic-purchase workflow. Discover purchase eligibility and configuration first; never invent product/variant IDs, OS codes, SSH-key IDs or regions. A quote is optional, and max_total is the authorized spending ceiling. Hosted writes use request_key as the server Idempotency-Key and honor Read only, Write with approval or Full access. get_operation_request tracks dashboard approval; get_operation tracks execution. Approval is not completion.

Local bf_product_variant_deploy is available only when selected mutations are enabled with BF_API_MCP_ENABLE_MUTATIONS set to 1. It executes under API-key scopes without hosted dashboard approval. Both interfaces retain separate credential controls; execution receipts never expose passwords or private keys. DNSSEC has local tools and its own state contract, with no hosted DNSSEC tool.

See [purchase policies, receipt statuses and recovery limitations](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery).

## Update or disconnect

Change permissions or revoke the connection from AI connections. If the needed permission is outside the original consent, reconnect to grant it. Refresh the app's tool list after tool updates. Saved permission changes invalidate older pending requests, but cannot undo an action already dispatched.

Passwords and private keys are never returned through the hosted connection. Use your service details in the dashboard for credential access.

---

# Install an SDK or the command-line tool



Source: https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns



Download Python, Node.js, PHP or Go, configure an API key and list your services.



Check GET /v1/version and GET /v1/capabilities before using optional workflow features. Strict response validation is enforced.

Use bf for new integrations. bf-api is an actively supported compatibility alias of the same CLI, not a separate lower-level interface. Both are included in the Python SDK package and use the same commands, authentication and version.

Use an SDK inside an application. Use the Python CLI for terminal commands. All four SDKs call the same public API and handle signed authentication.

## Before you start

Create an API key using the [authentication guide](https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security). Download the current archive from [Settings → API → SDK downloads](https://my.blazingfast.io/settings/api). Each archive contains a README with language-specific examples. Current immutable downloads: [Python + CLI](https://docs.blazingfast.io/sdk/bf-sdk-python-0.1.17.tar.gz), [Node.js](https://docs.blazingfast.io/sdk/bf-sdk-nodejs-0.1.17.tar.gz), [PHP](https://docs.blazingfast.io/sdk/bf-sdk-php-0.1.17.tar.gz) and [Go](https://docs.blazingfast.io/sdk/bf-sdk-go-0.1.17.tar.gz). Verify [SHA256SUMS](https://docs.blazingfast.io/sdk/SHA256SUMS) before installing. Public registry publication is separate from these downloads.

| Package | Minimum runtime | Included tools |
| --- | --- | --- |
| Python | Python 3.10 | SDK, `bf` CLI (`bf-api` alias) and local MCP server |
| Node.js | Node.js 18 | SDK library |
| PHP | PHP 8.1 | SDK library |
| Go | Go 1.22 | SDK library |

## Python and CLI quickstart

Download the Python archive, then install it in a virtual environment. Replace the filename below with the version you downloaded.

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install ./bf-sdk-python-VERSION.tar.gz
bf --version
```

On Windows PowerShell, activate with `.\.venv\Scripts\Activate.ps1`. If creating the environment fails, install your operating system's Python venv support.

Set `BF_API_BASE_URL`, `BF_API_KEY` and `BF_API_SECRET` in the active shell, then run:

```bash
bf service list
bf billing balance
bf dns zone list
bf vps status SERVICE_UUID
```

Replace `SERVICE_UUID` with a service ID returned by the list. Use `bf --help` or `bf billing --help` to discover commands.

In Python:

```python
from bf_api import BfClient
client = BfClient()  # reads the environment variables
print(client.services_list(statuses=["active", "suspended"]))
```

## Node.js quickstart

Install the downloaded archive inside your Node.js project:

```bash
npm install ./bf-sdk-nodejs-VERSION.tar.gz
```

```javascript
const { BfClient } = require('bf-api');
async function main() {
  const client = new BfClient({
    baseUrl: process.env.BF_API_BASE_URL,
    apiKey: process.env.BF_API_KEY,
    apiSecret: process.env.BF_API_SECRET,
  });
  console.log(await client.services_list({ statuses: ["active", "suspended"] }));
}
main().catch(() => console.error("API request failed; check status, error code and request ID."));
```

## PHP quickstart

Extract the PHP archive. In a Composer project, use the extracted directory as a local package:

```bash
tar -xzf bf-sdk-php-VERSION.tar.gz
composer config repositories.bf path ./bf-sdk-php-VERSION
composer require blazingfast/bf-api:@dev
```

```php
<?php
require __DIR__ . '/vendor/autoload.php';
$client = new BfApi\BfClient([
    'baseUrl' => getenv('BF_API_BASE_URL'),
    'apiKey' => getenv('BF_API_KEY'),
    'apiSecret' => getenv('BF_API_SECRET'),
]);
print_r($client->services_list(['statuses' => ['active', 'suspended']]));
```

## Go quickstart

Extract the Go archive. In a Go module, reference its local directory:

```bash
tar -xzf bf-sdk-go-VERSION.tar.gz
go mod edit -replace blazingfast.io/sdk/go=./bf-sdk-go-VERSION
go get blazingfast.io/sdk/go
```

Create a client with `bfapi.NewClient(bfapi.Config{BaseURL: os.Getenv("BF_API_BASE_URL"), APIKey: os.Getenv("BF_API_KEY"), APISecret: os.Getenv("BF_API_SECRET")})`, then call `client.ServicesList(nil, nil)`. The archive README contains the complete Go program, including error handling.

## Local MCP for desktop and coding assistants

For the hosted ChatGPT connection, follow [Connect an AI assistant](https://docs.blazingfast.io/howto/api/connect-ai-assistant). Local MCP runs on your computer using the Python package and an API key.

After installation, `bf-api-mcp` starts the local server. Desktop apps may not use your terminal's PATH; find the full executable path with `command -v bf-api-mcp` and use it in the client configuration.

A basic JSON configuration is:

```json
{
  "mcpServers": {
    "bf-api": {
      "command": "/ABSOLUTE/PATH/.venv/bin/bf-api-mcp",
      "args": [],
      "env": {
        "BF_API_BASE_URL": "https://api.blazingfast.io",
        "BF_API_KEY": "YOUR_KEY_PREFIX",
        "BF_API_SECRET": "YOUR_ONE_TIME_SECRET"
      }
    }
  }
}
```

The archive README includes Claude, Cursor and VS Code configuration examples. Restart or refresh the client after saving.

Local MCP exposes viewing tools by default. `BF_API_MCP_ENABLE_MUTATIONS=1` enables selected write tools within your API-key permissions. Those API-key actions execute directly and do not use hosted AI dashboard approvals. Credential output has a separate opt-in; leave it disabled unless you specifically need it. Follow [the local MCP guide](https://docs.blazingfast.io/howto/api/local-mcp) for coverage limits and the distinction from hosted MCP.

## Current purchase and operation workflows

SDK/CLI 0.1.17 supports contract 2026-10-07.1. Read GET /v1/version and GET /v1/capabilities, then discover product purchase policies and requirements before configuring a purchase. A quote is optional: discovery can lead directly to an authorized deployment. Quotes do not reserve stock or lock prices; send an authorized max_total ceiling for the full final order amount.

Draft order creation does not charge the account. Atomic deployment is the documented exception: it combines order creation, payment of the full final order amount from account balance and queued provisioning. Paid is not ready; accepted is not completed. Service lifecycle status is separate from runtime power state.

Supported tracked deployment, VPS and dedicated writes can return a canonical operation receipt and be recovered using their original idempotency key. This does not extend recovery to every write or historical request. See [HTTP, SDK, CLI and MCP examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery). DNSSEC uses its separate endpoint and state contract.

Use the [native Python, Node.js, PHP and Go recovery examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery#native-sdk-examples). They also show each SDK's canonical operation-response option for atomic deployment.

## Downloads and checksums

The SDK tab links to `SHA256SUMS`. Download it alongside your archive and use `sha256sum --check --ignore-missing SHA256SUMS` on Linux, or `shasum -a 256` on macOS to compare the archive hash. A checksum detects a damaged or mismatched download.

See [troubleshooting](https://docs.blazingfast.io/howto/api/automation-troubleshooting) if a command is missing or a request fails.

---

# Machine-readable purchase and operation recovery



Source: https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery



Discover purchase requirements, request canonical receipts and recover a lost write response safely.



## Machine-readable purchase and recovery

Read GET /v1/version and GET /v1/capabilities before using optional workflow features. Account features distinguish implemented, enabled and permitted. Product purchase policies describe draft_order and atomic_deploy separately; inspect their implemented, enabled, eligible and permitted fields. Discovery is not a reservation, customer authorization or a provider health guarantee.

Follow a product's requirements_url or options_url. requirements.atomic_deploy describes canonical input names, required flags, types and discovery sources. requiredFields and conditionalRequiredFields remain the draft order's legacy userConfig requirements. Region and server configuration are resolved by the selected SKU URL. Read the returned OS choices and your owned SSH keys; never invent codes or identifiers.

Quotes retain their existing total, breakdown and items. quote.recommended_max_total equals the quoted final tax/setup/add-on-inclusive total, in quote.currency. After authorization, send that amount as max_total. The final deployment revalidates prices and returns HTTP 409 with error.code set to deployment_price_limit_exceeded if the current total exceeds the ceiling. It does not silently charge more. quote.guaranteed=false means there is no price lock. quote.id and pricing_revision fingerprint this priced cart for correlation; they are not redeemable quote resources or global catalog revisions. links.deploy points to the atomic purchase endpoint where applicable. Quote remains optional.

### A common operation receipt

For supported deployment, VPS and dedicated writes, send x-bf-response-format: operation to request the canonical Operation envelope. Check canonical_operation_responses first. The default preserves existing action/task fields and adds operation_id, operation_url and links. A cached retry preserves its initial response format; accept operation.id or operation_id, then poll links.operation or GET /v1/operations/{operationId}. No new key is needed to poll.

| Operation status | done | Meaning |
| --- | --- | --- |
| pending, running | false | Accepted or executing; not completed |
| unknown | false | Outcome needs reconciliation; never assume failure or submit a new write |
| succeeded | true | Recorded operation completed successfully |
| failed, cancelled | true | Recorded terminal outcome; inspect billing separately |

progress may be null. stage is informational and may be null; branch on status and done. Failed operations expose a safe code/message, never raw provider errors. Only succeeded operations expose a result. Deployment results identify service_ids and, when recorded, order_id/invoice_id. Service results identify service_id and recorded OS/snapshot fields when applicable. power_state is included only when original task completion evidence provides it; present-day runtime state is a separate read. Historical receipts may lack newly introduced result fields. The first terminal receipt is immutable.

links.operation, links.service, links.invoice and links.order are relative customer API URLs, included when their resource identity is known. DNSSEC keeps its own legacy state contract and polling endpoint; its operation string/UUID is not a generic operation handle. The optional canonical adapter does not change that contract.

### Recover a lost write response

GET /v1/operations?idempotency_key=original-key recovers a tracked write without repeating it. Lookup is confined to the authenticated account and its current billing.services.read, vps.read or dedicated.read permission for that operation. The same key is scoped to the original credential, HTTP method and exact path. Supply method and path together, plus credential_id if needed to disambiguate a key reused for other endpoints or credentials.

- HTTP 200: continue polling the original operation.
- HTTP 400, validation_error: correct lookup selectors; do not submit a new write.
- HTTP 404, operation_not_found: no recoverable identity found. This does not establish that the write never executed.
- HTTP 409, operation_lookup_ambiguous: supply the original method/path and, if necessary, credential_id.
- HTTP 410, operation_expired: identity remains but the receipt has expired; reconcile resources and billing.

Terminal receipts retain 90 days by default; operation_policy advertises the configured retention. Pending/unknown receipts remain for reconciliation. Lookup identities are retained indefinitely after receipt expiry and contain no raw key or credential secret. Recovery applies to newly tracked writes after this contract is enabled, not every historical request or every API write. Never generate a replacement key merely because a response or receipt was lost.

SDK recovery helpers are Python/Node/PHP operation_recover and Go OperationRecover. CLI: bf operations recover --request-key original-key --method POST --path /v1/vps/SERVICE_ID/reboot; add --wait to poll. Hosted MCP recover_operation and local MCP bf_operation_recover use the same existing key. get_operation_request tracks an MCP approval request; get_operation tracks the execution receipt. Approval acceptance is not provider completion.

New asynchronous write contracts use the common Operation envelope. Existing v1 shapes remain compatible through the opt-in adapter. Deprecated aliases are marked in OpenAPI and HTTP Deprecation metadata; no Sunset is published without a committed removal date.

## Direct HTTP example

Use an issued bearer-mode credential in BF_API_BEARER. Signed-mode credentials require all HMAC headers; generic OpenAPI clients do not implement signing automatically. This read uses the exact original key, method and path:

```bash
curl --fail-with-body --get 'https://api.blazingfast.io/v1/operations' \
  -H "Authorization: Bearer $BF_API_BEARER" \
  --data-urlencode "idempotency_key=$ORIGINAL_REQUEST_KEY" \
  --data-urlencode 'method=POST' \
  --data-urlencode "path=$ORIGINAL_REQUEST_PATH"
```

For a newly authorized, supported tracked write, send Idempotency-Key: YOUR_STABLE_WRITE_KEY and x-bf-response-format: operation to request the canonical receipt. These are separate headers: one identifies the write, the other selects its response representation. GET polling and recovery do not charge or repeat the original operation.

## Native SDK examples

Configure production authentication as described in the [installation guide](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns). These examples perform a read: ORIGINAL_REQUEST_KEY is the saved key from an existing tracked write and ORIGINAL_REQUEST_PATH is its exact API path. Do not create a replacement key when recovering. The original method below is POST; use the actual method of your write. Missing or expired receipts require reconciliation, not an automatic new purchase.

### Python

```python
import os
from bf_api import BfClient

client = BfClient()
receipt = client.operation_recover(
    os.environ["ORIGINAL_REQUEST_KEY"],
    method="POST",
    path=os.environ["ORIGINAL_REQUEST_PATH"],
)
print(receipt["operation"]["id"], receipt["operation"]["status"])
```

For a newly authorized deployment, product_variant_deploy(region, product_code, variant_code, payload, idempotency_key=key, operation_response=True) opts into the canonical receipt.

### Node.js

```javascript
const { BfClient } = require('bf-api');

async function main() {
  const client = new BfClient();
  const receipt = await client.operation_recover(process.env.ORIGINAL_REQUEST_KEY, {
    method: 'POST', path: process.env.ORIGINAL_REQUEST_PATH,
  });
  console.log(receipt.operation.id, receipt.operation.status);
}
main().catch((error) => { console.error(error.message); process.exitCode = 1; });
```

For a newly authorized deployment, product_variant_deploy(region, productCode, variantCode, payload, {idempotency_key: key, operation_response: true}) opts into the canonical receipt.

### PHP

```php
<?php
require __DIR__ . '/vendor/autoload.php';

$client = new \BfApi\BfClient();
$receipt = $client->operation_recover(
    getenv('ORIGINAL_REQUEST_KEY'), 'POST', getenv('ORIGINAL_REQUEST_PATH')
);
echo $receipt['operation']['id'] . ' ' . $receipt['operation']['status'] . PHP_EOL;
```

For a newly authorized deployment, product_variant_deploy($region, $productCode, $variantCode, $payload, $key, true) opts into the canonical receipt. PHP recovery uses positional selectors, not the Node.js options object.

### Go

```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    bf "blazingfast.io/sdk/go/bfapi"
)

func main() {
    client, err := bf.NewClient(bf.Config{})
    if err != nil { log.Fatal(err) }
    receipt, err := client.OperationRecover(context.Background(),
        os.Getenv("ORIGINAL_REQUEST_KEY"), bf.OperationRecoveryOptions{
            Method: "POST", Path: os.Getenv("ORIGINAL_REQUEST_PATH"),
        })
    if err != nil { log.Fatal(err) }
    fmt.Println(receipt.Operation.ID, receipt.Operation.Status)
}
```

For a newly authorized deployment, ProductVariantDeploy(region, productCode, variantCode, payload, key, true) opts into the canonical receipt.

SDKs require the explicit deployment key and never automatically retry writes. Cached retries preserve the initial response format, so inspect operation.id or the compatible operation_id. Poll the returned operation link or the SDK operation_get / Go OperationGet helper; only succeeded confirms completion. Receipt results and links identify known resources without exposing credentials.

## Optional quote, deployment and recovery

Discover the actual region, product, variant and configuration values first. The following purchase command charges the account; run it only after authorizing the target and final spending ceiling. deployment.json contains the canonical billing_cycle, hostname, os, optional ssh_key_id and max_total fields for the selected VPS, plus any discovered add-ons. Do not mix these with legacy billing/userConfig/maxTotal fields.

```bash
bf version
bf capabilities
bf catalog list REGION_CODE vps
bf catalog options REGION_CODE vps VARIANT_CODE
bf billing deploy REGION_CODE vps VARIANT_CODE --file deployment.json --quote
bf billing deploy REGION_CODE vps VARIANT_CODE --file deployment.json --request-key purchase-example-001 --operation-response --wait
bf operations recover --request-key ORIGINAL_KEY --method POST --path /v1/vps/SERVICE_UUID/reboot --wait
bf operations get OPERATION_ID
bf operations wait OPERATION_ID --wait-timeout 300
```

The --quote invocation is a preview, not a purchase, and is optional. --operation-response requests the canonical receipt; --wait polls without resubmitting. Most supported CLI writes generate, save and print an omitted key before dispatch. Retain it: a new invocation without a key represents a new action. Recovery requires the ORIGINAL_KEY and never generates one. The recovery method and path describe the original write; pass both together when disambiguation is needed. DNSSEC enable/disable still require an explicit --request-key.

A wait timeout does not cancel the operation or establish failure. Recover the original receipt before deciding whether to retry the identical write. A 404 lookup is not proof of no execution; 409 requires more precise selectors; 410 requires reconciling resources and billing. [Recovery scope and retention](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery) remain endpoint-specific.

## Purchase discovery and execution recovery

Hosted MCP uses https://mcp.blazingfast.io/mcp and your OAuth connection policy. Local MCP uses the installed SDK/CLI 0.1.17 and your API credentials. Discover the tools actually exposed by the client; their names differ:

- Optional quote: hosted quote_product_variant; local bf_product_variant_quote.
- Execution receipt: hosted get_operation; local bf_operation_get.
- Original-key recovery: hosted recover_operation; local bf_operation_recover.

For both recovery tools, the argument is idempotency_key, even though hosted write tools use request_key. This example recovers an existing VPS reboot; substitute the exact original key and owned service UUID:

```json
{
  "idempotency_key": "ORIGINAL_KEY",
  "method": "POST",
  "path": "/v1/vps/SERVICE_UUID/reboot"
}
```

Recovery is read-only and does not repeat a mutation. Supply method and path together when needed and credential_id only to select the original credential. Reads require current account access and the matching operation-read scope.

Hosted deploy_product is the preferred canonical atomic-purchase workflow. Discover purchase eligibility and configuration first; never invent product/variant IDs, OS codes, SSH-key IDs or regions. A quote is optional, and max_total is the authorized spending ceiling. Hosted writes use request_key as the server Idempotency-Key and honor Read only, Write with approval or Full access. get_operation_request tracks dashboard approval; get_operation tracks execution. Approval is not completion.

Local bf_product_variant_deploy is available only when selected mutations are enabled with BF_API_MCP_ENABLE_MUTATIONS set to 1. It executes under API-key scopes without hosted dashboard approval. Both interfaces retain separate credential controls; execution receipts never expose passwords or private keys. DNSSEC has local tools and its own state contract, with no hosted DNSSEC tool.

See [purchase policies, receipt statuses and recovery limitations](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery).

---

# Use the CLI on Windows, macOS and Linux



Source: https://docs.blazingfast.io/howto/api/cli-workflows



Install the Python CLI, configure credentials and follow read-first product workflows.



Use bf for new integrations. bf-api is an actively supported compatibility alias of the same CLI, not a separate lower-level interface. Both are included in the Python SDK package and use the same commands, authentication and version. It calls the public API from your computer; it does not execute a remote shell command inside your server. Server power/reinstall actions run remotely only after the API accepts them. The separate Snabb CLI is not interchangeable.

## Install and configure

Download the current Python archive and SHA256SUMS from [Settings → API](https://my.blazingfast.io/settings/api). Python 3.10+ is required. Use a virtual environment and keep TLS verification enabled.

Linux and macOS:

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install ./bf-sdk-python-0.1.17.tar.gz
export BF_API_BASE_URL="https://api.blazingfast.io"
export BF_API_KEY="YOUR_KEY_PREFIX"
export BF_API_SECRET="YOUR_ONE_TIME_SECRET"
bf --version
bf service list
```

Windows PowerShell (activation is not required when using the full executable path):

```powershell
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install .\bf-sdk-python-0.1.17.tar.gz
$env:BF_API_BASE_URL = "https://api.blazingfast.io"
$env:BF_API_KEY = "YOUR_KEY_PREFIX"
$env:BF_API_SECRET = "YOUR_ONE_TIME_SECRET"
.\.venv\Scripts\bf.exe service list
```

The values above are placeholders. Set real secrets through your private configuration; do not paste them into chat, commit them or include them in shared terminal transcripts. Use either signed credentials or the complete issued `BF_API_BEARER`, not your portal password. Environment files are not loaded automatically.

## Read before changing

```bash
bf billing balance
bf billing invoices
bf service list vps --status suspended
bf service list dedicated --status suspended
bf vps status SERVICE_UUID
bf dedicated status SERVICE_UUID
bf vps console SERVICE_UUID
bf dedicated console SERVICE_UUID
bf dns record list example.com
bf tcp-proxy show SERVICE_UUID
```

Choose IDs from your service list. Service UUID, product UUID, variant UUID, invoice UUID, order UUID and dedicated OS profile ID are different identifiers. Use `--help` for the intended command; not every API operation has a CLI equivalent.

Console commands return a browser URL. Sign in as the service owner to connect; copying the URL does not grant another account access. They do not provide a native VNC tunnel. For explicit credential reads in a private terminal, use `bf vps credentials SERVICE_UUID` or `bf dedicated credentials SERVICE_UUID` with the separate credential permission. Do not log the output.

## Dedicated server example

Read the catalog and select its exact configuration code, region, numeric OS profile and supported billing option. A saved SSH key must belong to your account.

```bash
bf dedicated catalog
bf dedicated deploy --configuration CONFIGURATION_CODE --region REGION_CODE --os-profile 123 --hostname myserver --ssh-key-id SSH_KEY_UUID --idempotency-key order-dedicated-001
bf dedicated deployment ORDER_UUID
```

Replace 123 with a returned profile ID; it is not a universal image ID. Deployment creates an unpaid order. Do not add `--pay-from-balance` unless you explicitly authorize payment. Installation starts after payment and any required administrator approval.

For an active server, after confirming that interruption is acceptable:

```bash
bf dedicated power SERVICE_UUID restart --idempotency-key restart-dedicated-001
bf dedicated tasks SERVICE_UUID
bf dedicated task SERVICE_UUID TASK_UUID
```

Reinstall requires `--confirm-erase`; rescue requires `--confirm-rescue`. Both need a compatible profile. `--wait` on deployment/password reset can reveal credentials: use only a private terminal and do not log that output.

## Optional quote, deployment and recovery

Discover the actual region, product, variant and configuration values first. The following purchase command charges the account; run it only after authorizing the target and final spending ceiling. deployment.json contains the canonical billing_cycle, hostname, os, optional ssh_key_id and max_total fields for the selected VPS, plus any discovered add-ons. Do not mix these with legacy billing/userConfig/maxTotal fields.

```bash
bf version
bf capabilities
bf catalog list REGION_CODE vps
bf catalog options REGION_CODE vps VARIANT_CODE
bf billing deploy REGION_CODE vps VARIANT_CODE --file deployment.json --quote
bf billing deploy REGION_CODE vps VARIANT_CODE --file deployment.json --request-key purchase-example-001 --operation-response --wait
bf operations recover --request-key ORIGINAL_KEY --method POST --path /v1/vps/SERVICE_UUID/reboot --wait
bf operations get OPERATION_ID
bf operations wait OPERATION_ID --wait-timeout 300
```

The --quote invocation is a preview, not a purchase, and is optional. --operation-response requests the canonical receipt; --wait polls without resubmitting. Most supported CLI writes generate, save and print an omitted key before dispatch. Retain it: a new invocation without a key represents a new action. Recovery requires the ORIGINAL_KEY and never generates one. The recovery method and path describe the original write; pass both together when disambiguation is needed. DNSSEC enable/disable still require an explicit --request-key.

A wait timeout does not cancel the operation or establish failure. Recover the original receipt before deciding whether to retry the identical write. A 404 lookup is not proof of no execution; 409 requires more precise selectors; 410 requires reconciling resources and billing. [Recovery scope and retention](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery) remain endpoint-specific.

## Orders, payment and retries

Use the [order and payment guide](https://docs.blazingfast.io/howto/api/order-and-pay-from-balance). Draft order creation does not pay. Atomic `bf deploy` is the combined wallet-payment and provisioning workflow; see the guide for both options. Balance payment can be partial and may start provisioning; inspect the returned result.

Most CLI lifecycle write keys are optional in 0.1.17; DNSSEC enable/disable require --request-key explicitly. If omitted, the CLI generates, saves locally and prints a key before sending. Reuse that key with identical arguments after a timeout; a new invocation without a key represents a new action. Different actions need different keys. If a write times out, check its task, order or invoice before retrying. The SDK does not automatically retry writes. A returned task means accepted, not completed.

See the [product coverage matrix](https://docs.blazingfast.io/howto/api/product-automation-coverage) for unsupported CLI operations, and endpoint-specific limits. Storage commands are supported: `bf storage list`, `attach-options`, `attach`, `detach` and `rename`. Writes require the appropriate scope and confirmation.

---

# Connect a local MCP client



Source: https://docs.blazingfast.io/howto/api/local-mcp



Run the Python MCP server locally with an API key and understand its tool and credential limits.



Local MCP runs on your computer as `bf-api-mcp`, installed with the Python SDK. It uses an API key to call BlazingFast. Hosted MCP instead uses OAuth and your AI connection policy; follow [the hosted connection guide](https://docs.blazingfast.io/howto/api/connect-ai-assistant) for that flow.

## Configure a local client

Install the Python SDK using [the CLI guide](https://docs.blazingfast.io/howto/api/cli-workflows). Point your MCP client to the executable's absolute path. Linux/macOS normally use `.venv/bin/bf-api-mcp`; Windows uses `.venv\Scripts\bf-api-mcp.exe`. Desktop applications may not inherit your shell's environment or PATH.

For clients using the mcpServers configuration format:

```json
{
  "mcpServers": {
    "blazingfast-local": {
      "command": "/ABSOLUTE/PATH/.venv/bin/bf-api-mcp",
      "args": [],
      "env": {
        "BF_API_BASE_URL": "https://api.blazingfast.io",
        "BF_API_KEY": "YOUR_KEY_PREFIX",
        "BF_API_SECRET": "YOUR_ONE_TIME_SECRET"
      }
    }
  }
}
```

Use your client's protected secret storage or a private user configuration. Never commit credentials. Other clients may use a different top-level configuration key; consult that client's instructions.

## First tools

Ask the agent to use `bf_service_list`, `bf_billing_balance`, `bf_dns_record_list`, `bf_vps_status` or `bf_dedicated_status` with the discovered owned resource. The client calls tools; these names are not shell commands.

Local and hosted names differ. Hosted equivalents include `list_services`, `get_balance`, `list_dns_records`, `get_vps_status` and `get_dedicated_status`. Discover the actual tools exposed by your client rather than guessing a name.

## Permissions and writes

Local viewing tools are enabled by default. `BF_API_MCP_ENABLE_MUTATIONS=1` exposes selected write tools, including VPS power, basic DNS zone/record changes, service autopay/cancellation, dedicated deployment/power/reinstall/rescue/password reset. They execute directly under the API key's permissions; they do not wait for hosted AI dashboard approval.

Keep mutations disabled for reporting. Reinstallation erases disks and rescue/reset interrupts connections. Dedicated mutations use explicit confirmations and stable idempotency keys; inspect returned tasks after uncertain outcomes.

`bf_service_list` accepts status and type filters, for example status `suspended` and type `dedicated`. Recorded hostnames are included in safe summaries. `bf_vps_console` and `bf_dedicated_console` return browser links; browser login and ownership are still required. Hosted equivalents are `get_vps_console` and `get_dedicated_console`.

`BF_API_MCP_ENABLE_CREDENTIALS=1` separately exposes VPS and dedicated credential tools, including `bf_vps_credentials`, with their corresponding credential-read scopes. Leave it disabled for normal AI use: credential output may enter your AI client's conversation/history. Hosted MCP does not expose passwords or private keys at all.

## Purchase discovery and execution recovery

Hosted MCP uses https://mcp.blazingfast.io/mcp and your OAuth connection policy. Local MCP uses the installed SDK/CLI 0.1.17 and your API credentials. Discover the tools actually exposed by the client; their names differ:

- Optional quote: hosted quote_product_variant; local bf_product_variant_quote.
- Execution receipt: hosted get_operation; local bf_operation_get.
- Original-key recovery: hosted recover_operation; local bf_operation_recover.

For both recovery tools, the argument is idempotency_key, even though hosted write tools use request_key. This example recovers an existing VPS reboot; substitute the exact original key and owned service UUID:

```json
{
  "idempotency_key": "ORIGINAL_KEY",
  "method": "POST",
  "path": "/v1/vps/SERVICE_UUID/reboot"
}
```

Recovery is read-only and does not repeat a mutation. Supply method and path together when needed and credential_id only to select the original credential. Reads require current account access and the matching operation-read scope.

Hosted deploy_product is the preferred canonical atomic-purchase workflow. Discover purchase eligibility and configuration first; never invent product/variant IDs, OS codes, SSH-key IDs or regions. A quote is optional, and max_total is the authorized spending ceiling. Hosted writes use request_key as the server Idempotency-Key and honor Read only, Write with approval or Full access. get_operation_request tracks dashboard approval; get_operation tracks execution. Approval is not completion.

Local bf_product_variant_deploy is available only when selected mutations are enabled with BF_API_MCP_ENABLE_MUTATIONS set to 1. It executes under API-key scopes without hosted dashboard approval. Both interfaces retain separate credential controls; execution receipts never expose passwords or private keys. DNSSEC has local tools and its own state contract, with no hosted DNSSEC tool.

See [purchase policies, receipt statuses and recovery limitations](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery).

## Coverage limits

Local MCP is a curated subset, not a generic API proxy. It has no hosted-style invoice-payment or general-order tools, no Website Protection/TCP Proxy tools, no full DNS import-preview workflow, and only storage listing. Use the API/SDK/CLI or hosted MCP where the [coverage matrix](https://docs.blazingfast.io/howto/api/product-automation-coverage) documents support.

If a tool is missing, confirm the installed SDK version, refresh tool discovery and review the opt-in environment settings. Do not broaden credentials just to work around an absent tool.

---

# Create an order and pay from account balance



Source: https://docs.blazingfast.io/howto/api/order-and-pay-from-balance



Discover valid locations and OS choices, review the price, create an unpaid order and pay separately.



## Choose the ordering and payment workflow

| Workflow | Use when | Payment |
| --- | --- | --- |
| Separate order and invoice | You need invoice review, a mixed cart, or separate payment approval | Quote → create an unpaid draft → inspect the invoice → explicitly pay → track provisioning |
| Atomic deployment | You authorize one discovered regional product and payment of the full final order amount from account balance together | Quote optionally → POST /v1/deploy/{region}/{productCode}/{variantCode} → payment of the full final order amount from account balance and queued provisioning |

The atomic deploy endpoint always attempts payment of the full final order amount from account balance; it never silently creates an unpaid order or uses a card/top-up. Insufficient credit returns HTTP 402 with error.code=insufficient_credit, without a committed new order, invoice or debit. The final tax/setup/add-on-inclusive amount must satisfy max_total. Both billing.order.create and billing.invoice.pay permissions are required.

A separate invoice payment may be partial if wallet funds are insufficient; read its remaining amount. That behavior is different from atomic deploy's all-or-nothing payment. A successful payment does not mean the guest or provider is ready.

Use one stable Idempotency-Key per intended write. Same key and exact request is a retry; a different request with that key is rejected. Separate order and payment requests need separate keys. CLI write keys are optional: an omitted key is generated, saved and printed before dispatch. Preserve it for retries. SDKs never automatically retry writes.

After a timeout or unknown response, inspect the original order, invoice, service or returned operation URL before retrying. Reuse the original key and exact payload; never create a new identity simply because a response was lost. Inspect fullyPaid/paidNow and the invoice status to confirm payment. Poll the operation until succeeded and check service readiness to confirm provisioning; accepted, pending or unknown does not confirm completion. A later provisioning failure must be handled separately from payment; inspect billing state rather than assuming an automatic refund.

Use bf billing order-preview/order-create and bf billing invoice-pay for the separate workflow. Use bf deploy or bf billing deploy for atomic deployment; bf dedicated deploy creates an unpaid order unless its explicit payment option is supplied.

Review the product and price before creating a draft, then inspect its invoice before paying.

## Find a product and its configuration

In your AI assistant, ask for the product, location, operating system, quantity and billing period you want. The assistant uses the product catalog and order-options tool to find eligible configurations.

Using the CLI:

```bash
bf billing products --query 1G
bf billing order-options PRODUCT_UUID VARIANT_UUID
bf billing order-preview PRODUCT_UUID VARIANT_UUID --currency EUR --unit MONTH --count 1
```

Replace IDs with the catalog results. Use the exact returned location and OS codes. Eligible options do not reserve stock or guarantee capacity.

## Create the unpaid order

Put your chosen configuration in `order.json`:

```json
{
  "currency": "EUR",
  "items": [{
    "productId": "PRODUCT_UUID",
    "variantId": "VARIANT_UUID",
    "qty": 1,
    "billing": {"unit": "MONTH", "count": 1},
    "userConfig": {
      "hostname": "myserver",
      "location": "LOCATION_CODE",
      "os": {"code": "OS_CODE"}
    }
  }]
}
```

This VPS example uses placeholders, not universal configuration codes. Other products can require different fields; read their options or use the dashboard if API ordering is unsupported.

```bash
bf billing order-create --file order.json --request-key order-myserver-001
bf billing invoices
```

The response identifies the order and invoice. Check the resulting total and currency. The CLI uses current server-side pricing; the earlier preview is not a price lock.

## Pay the invoice

Read your balance and the invoice's outstanding amount. When you decide to pay that invoice:

```bash
bf billing balance
bf billing invoice-pay INVOICE_UUID --request-key pay-myserver-001
bf billing invoices
```

This uses existing account balance, not a card. If balance is insufficient, a partial payment may leave the invoice unpaid. Check the returned payment result and remaining amount.

In ChatGPT, make an explicit request such as “Pay invoice INV-... from my account balance.” The selected AI policy determines whether dashboard approval is needed.

## Track provisioning

Payment can start provisioning. List services and inspect the service's status. Dedicated deployment tasks have their own progress endpoints. A paid invoice does not prove installation is complete.

## Retry an uncertain request

Keep the same request key and payload for the same action. Use different keys for order creation and payment. If a request times out, read the order or invoice before retrying; never create a new key just because the response was lost. SDKs do not automatically retry writes. Server deduplication has a finite retention window.

The API permissions are `billing.products.read` for discovery, `billing.order.create` for ordering, `billing.invoice.pay` for payment, and the relevant invoice/balance read permissions.

---

# Create DNS zones and manage Website Protection



Source: https://docs.blazingfast.io/howto/api/dns-and-protection-automation



Start with an empty zone, template, JSON or zone file, then inspect records and protection.



DNS determines where a hostname points. Website Protection controls mitigation for a proxied A record. Proxy routing and protection are separate settings.

## Create a zone

You need an active DNS service and `dns.write`. First list your zones and available templates:

```bash
bf dns zone list
bf dns template list
```

Choose one starting point:

| Starting point | CLI option | Result |
| --- | --- | --- |
| Empty | `--empty` | Platform nameservers and required SOA only |
| Saved template | `--template TEMPLATE_NAME` | Records from an exact, unique template name |
| JSON record sets | `--json-file records.json` | Records from a local JSON array |
| DNS zone file | `--zone-file example.zone` | Records parsed from local zone-file text |

For example:

```bash
bf dns zone create example.com --empty --request-key zone-example-001
```

Creating a zone does not register a domain or change registrar nameservers. Copy the zone's authoritative nameservers to your registrar when you intend to use it.

## Preview a file import

An import source is chosen instead of empty mode or a template. A JSON file contains record sets, not a complete API request:

```json
[
  {"name":"@","type":"A","ttl":300,"values":["192.0.2.1"]},
  {"name":"www","type":"CNAME","ttl":300,"values":["example.com."]}
]
```

```bash
bf dns zone create example.com --json-file records.json --dry-run --request-key preview-example-001
bf dns zone create example.com --json-file records.json --request-key import-example-001
```

Review the preview's records and notes before creating. Use a different key for preview and creation; reuse the creation key on retries. Preview does not reserve the zone. Existing zones are not overwritten.

The platform manages apex NS and SOA. File imports do not fetch remote URLs. Zone files support standard IN records, `$ORIGIN`, `$TTL`, quoted TXT and multiline records; `$INCLUDE` and `$GENERATE` are unsupported. Limits are 200 record sets, 50 values per set, TTL 1–86,400 seconds and 100,000 zone-file characters.

## Inspect and change record protection

For a domain in your DNS account, use its zone and record name. `@` means the root record. A separate hosting service ID is not required, including when the origin is external.

```bash
bf dns protection show example.com --record @
bf dns protection set example.com --record @ --enabled off --request-key protection-example-001 --confirm
bf dns protection show example.com --record @
```

The write changes mitigation on an eligible proxied A record. It keeps the proxy switch, origin IP, DNS values and TTL unchanged. Disabling mitigation reduces protection. A missing or unknown protection value does not mean it is disabled.

An AI assistant follows the same read-first workflow and your selected connection policy.

## Country access and TCP Proxy

```bash
bf dns country-policy show example.com --record @
bf tcp-proxy show SERVICE_UUID
bf tcp-proxy stats SERVICE_UUID --range 24h
```

Website country modes are `off`, `allow`, `deny`. TCP Proxy country modes are `disabled`, `allow`, `block`. They are different schemas.

Read the existing configuration before writing. Supplied arrays replace the full array; omitted fields stay unchanged. Check that firewall or country changes retain the access you need.

Use `dns.read` / `dns.write` for DNS and Website Protection, and `tcp_proxy.read` / `tcp_proxy.write` for TCP Proxy.

---

# API integration guide



Source: https://docs.blazingfast.io/api/integration-guide



Use SDKs, authenticate requests, paginate results and handle retries, idempotency and webhooks.



Use this guide for integration workflows. See the [generated endpoint reference](https://docs.blazingfast.io/api/reference) for exact parameters, permissions and response models.

## Current API, SDK, CLI and MCP

Check GET /v1/version and GET /v1/capabilities before using optional workflow features. Strict response validation is enforced.

Use bf for new integrations. bf-api is an actively supported compatibility alias of the same CLI, not a separate lower-level interface. Both are included in the Python SDK package and use the same commands, authentication and version.

The current reference describes 182 customer API operations. SDK/CLI 0.1.17 downloads are available for Python, Node.js, PHP and Go. The Python package includes `bf`, `bf-api` and the local `bf-api-mcp` server. Download [Python](https://docs.blazingfast.io/sdk/bf-sdk-python-0.1.17.tar.gz), [Node.js](https://docs.blazingfast.io/sdk/bf-sdk-nodejs-0.1.17.tar.gz), [PHP](https://docs.blazingfast.io/sdk/bf-sdk-php-0.1.17.tar.gz) or [Go](https://docs.blazingfast.io/sdk/bf-sdk-go-0.1.17.tar.gz), and verify the archive against [SHA256SUMS](https://docs.blazingfast.io/sdk/SHA256SUMS).

| Environment | API origin | SDK downloads | Hosted MCP |
| --- | --- | --- | --- |
| Production | `https://api.blazingfast.io` | [Downloads](https://docs.blazingfast.io/downloads) | `https://mcp.blazingfast.io/mcp` |

Set `BF_API_BASE_URL` to the origin without `/v1`. SDKs sign requests using `BF_API_KEY` and `BF_API_SECRET`; the copyable endpoint snippets use bearer authentication with `BF_API_BEARER`. Set its complete issued credential privately. Choose the authentication mode when creating the credential in Settings → API.

Start with discovery:

```bash
bf version
bf capabilities
bf regions
bf catalog list nl vps
bf service list
```

`GET /v1/version` identifies the deployed API contract. `GET /v1/capabilities` reports feature availability. Check the required scopes, owned resources and current stock as well; a documented operation does not guarantee that every environment has the same products or provider availability.

## Authentication and generated clients

For HMAC/SignedAuth requests, all five headers are required: `x-api-key`, `x-ts`, `x-nonce`, `x-content-sha256` and `x-signature`. The body hash and signature cover the exact transmitted bytes. Refresh the timestamp and nonce for every HTTP attempt while retaining the original idempotency key and payload on write retries.

Generic OpenAPI-generated clients do not automatically implement BlazingFast HMAC signing. SignedAuth's API-key declaration alone cannot compute the signature. Prefer an official SDK, or Bearer authentication with a bearer-mode credential. Implement custom signing only after following the [signing algorithm](https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security). A signed-mode credential cannot be used as a bearer-mode credential simply by changing headers.

## Pagination and page size

Pagination is endpoint-specific. Clients must follow the model documented for each endpoint; there is no API-wide page-based pagination contract.

| Model | Request | Continue with | Examples |
| --- | --- | --- | --- |
| Page | `page`, `limit` | Increment page until `page >= pages` or items is empty | `GET /v1/services`, billing lists |
| Cursor | `cursor`, `limit` | Pass `next_cursor` unchanged; null means finished | `GET /v1/api-credentials`, audit and webhook-delivery lists |
| Offset | `offset`, `limit` | Use `next_offset`; null means finished | `GET /v1/products`, `GET /v1/dns/zones?view=summary` |

`limit` is the canonical page-size parameter. `page_size` and `pageSize` are deprecated compatibility request aliases only where that endpoint explicitly documents them. If multiple size parameters are supplied, their values must match. Defaults and bounds vary by endpoint. Page-based responses retain `pageSize` for compatibility; do not interpret that response field as a recommendation to use the deprecated request alias.

For services, use `GET /v1/services?statuses=active,suspended&type=vps&limit=50&page=1`. Ownership, status, type, search, `external_id` and label filters are applied server-side before pagination and counts. The default is active plus suspended. Historical states require an explicit status selection; this API uses `terminated` for its terminal lifecycle state rather than adding unsupported cancelled/expired filter values.

`group_by=type` groups only the current paginated result set. `GET /v1/services/grouped` returns the complete filtered dashboard inventory without pagination and supports its documented status/type filters. This is a legacy compatibility endpoint with an active-only default; MCP/automation clients should pass status explicitly. use `status=suspended` or `status=all` explicitly. It does not provide the paginated endpoint's search or metadata filters.

## Service families and product codes

type is the normalized service family for inventory filters. product_code is the specific purchasable family for catalog/deployment selection.

| product_code | Normalized type |
| --- | --- |
| vps | vps |
| dedicated | dedicated |
| tcp-proxy | other |
| waf | dns |
| license | other |

Discover the exact product_code before purchasing; type=other does not select a product.

MCP/automation should pass lifecycle/type filters explicitly. Prefer /v1/services?statuses=active,suspended; follow all pages. Legacy /v1/services/grouped accepts one status or all: fetch active and suspended separately and merge by ID when excluding history. Filters run before pagination; lifecycle is separate from runtime power.

## DNSSEC

Registered-domain DNSSEC is public at GET/POST /v1/domains/{serviceId}/dnssec. Read and action=refresh need domains.read; enable/disable need domains.write, acknowledge=true and a stable Idempotency-Key. Enable supports managed signing or external public DNSKEYs. HTTP 202 is accepted, not completed: poll the same DNSSEC GET and reconcile unconfirmed outcomes. Registrar configuration does not verify parent propagation.

SDK/CLI 0.1.17 includes DNSSEC methods and bf domain dnssec show/check/enable/disable; writes require --confirm and an explicit --request-key. Local MCP has read/refresh tools and an opt-in update tool; hosted MCP has none. See [DNSSEC modes, keys, scopes and operation states](https://docs.blazingfast.io/howto/services/domains-and-dns-zone-operations#dnssec).

## Choose the ordering and payment workflow

| Workflow | Use when | Payment |
| --- | --- | --- |
| Separate order and invoice | You need invoice review, a mixed cart, or separate payment approval | Quote → create an unpaid draft → inspect the invoice → explicitly pay → track provisioning |
| Atomic deployment | You authorize one discovered regional product and payment of the full final order amount from account balance together | Quote optionally → POST /v1/deploy/{region}/{productCode}/{variantCode} → payment of the full final order amount from account balance and queued provisioning |

The atomic deploy endpoint always attempts payment of the full final order amount from account balance; it never silently creates an unpaid order or uses a card/top-up. Insufficient credit returns HTTP 402 with error.code=insufficient_credit, without a committed new order, invoice or debit. The final tax/setup/add-on-inclusive amount must satisfy max_total. Both billing.order.create and billing.invoice.pay permissions are required.

A separate invoice payment may be partial if wallet funds are insufficient; read its remaining amount. That behavior is different from atomic deploy's all-or-nothing payment. A successful payment does not mean the guest or provider is ready.

Use one stable Idempotency-Key per intended write. Same key and exact request is a retry; a different request with that key is rejected. Separate order and payment requests need separate keys. CLI write keys are optional: an omitted key is generated, saved and printed before dispatch. Preserve it for retries. SDKs never automatically retry writes.

After a timeout or unknown response, inspect the original order, invoice, service or returned operation URL before retrying. Reuse the original key and exact payload; never create a new identity simply because a response was lost. Inspect fullyPaid/paidNow and the invoice status to confirm payment. Poll the operation until succeeded and check service readiness to confirm provisioning; accepted, pending or unknown does not confirm completion. A later provisioning failure must be handled separately from payment; inspect billing state rather than assuming an automatic refund.

Use bf billing order-preview/order-create and bf billing invoice-pay for the separate workflow. Use bf deploy or bf billing deploy for atomic deployment; bf dedicated deploy creates an unpaid order unless its explicit payment option is supplied.

## Find the right resource

| Resource | Typical tasks |
| --- | --- |
| Integrations | Version, capabilities, account audit events, API credentials and OAuth connections |
| Billing and deployment | Products, regional plans, quotes, order previews, orders, invoices and balance payments |
| Services | Status/type filters, recorded hostnames, service details, billing settings, renewal and termination |
| VPS | Status, recorded credentials, browser console, installed OS, IPs, power, reinstall, snapshots, backups and usage |
| Dedicated servers | Catalog, deployment, browser console, credentials, power, reinstall, rescue and task history |
| DNS and Website Protection | Empty or imported zones, templates, records, proxy routing, protection, SSL and country access |
| Domains | Registrations, contacts, nameservers, lock and privacy |
| TCP Proxy | Backends, ports, traffic and source/country access settings |
| SSH, Firewall and Storage | Public keys, firewall policies and volume operations |
| Webhooks | Signed notifications, delivery history, tests and secret rotation |

Use `GET /v1/services` for the service inventory. By default it includes active and suspended services; select terminated/history statuses explicitly. For suspended VPS and dedicated servers, use `GET /v1/services?status=suspended&type=vps,dedicated`.

Lists include recorded hostname and type, never passwords. Credential endpoints require separate permissions and private response handling. Console endpoints return a browser URL that still requires sign-in and ownership; they do not return provider VNC tickets.

## Deploy and track a service

1. Discover the region, product, variant, available OS choices and your SSH keys. Use the returned identifiers and codes.
2. Obtain an optional quote or preview. Neither reserves stock nor purchases the service.
3. Deploy with the canonical fields: `billing_cycle`, `hostname`, `os`, `ssh_key_id`, `addons`, `max_total`, `external_id` and `labels`, as supported by the selected product. Use `max_total` to cap the price you accept.
4. Save the response's service IDs, request ID and operation handle. A paid or accepted response can still mean provisioning is in progress.
5. Poll the returned operation/task status or use supported webhooks, then read the service's runtime status before connecting.

Use each endpoint's snake_case fields. Legacy fields remain compatible; SDKs translate native argument names.

Use snapshots before risky changes and backups for recovery. Poll progress until completion, then verify guest reachability.

## Retry keys and uncertain outcomes

See [machine-readable purchase and operation recovery](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery) for runtime requirements, optional canonical receipts, quote ceilings and lost-response recovery.

Use a stable `Idempotency-Key` for writes. The same key and exact request identify a retry; a different payload with that key is rejected. Keep the key with your application's order or operation record.

CLI `--request-key` and its `--idempotency-key` alias are optional. If omitted, the CLI generates a key once, saves it locally before dispatch and prints it for explicit retries. An explicit key is useful when your management system needs to control the retry identity.

After a timeout or interrupted write, inspect the service, invoice or operation before retrying. Reuse the original key and payload. Generating a new key can create a second action. SDKs do not automatically retry writes; safe read retries follow their documented limits and `Retry-After`.

Hosted MCP's request key maps to the API's idempotency key. The connection's scopes and policy still apply: read only, write with approval, or full access. Local MCP uses an API key and exposes read-only tools by default; enable mutations explicitly when needed. Hosted MCP does not expose passwords or private keys.

## Domain names and free DNS

Enter `example.com` or `www.example.com` without a trailing dot. Dotted absolute names are accepted too. Customer-facing `fqdn` responses now use plain lowercase hostnames:

```json
{"ok":true,"fqdn":"example.com","type":"A","proxied":true,"protection":true}
```

For DNS record selectors, `@` means the zone apex and `www` means that zone's www record. Raw DNS RRset names, zone names and DNS target values can retain a trailing dot; it marks an absolute DNS name. Preserve that notation when using advanced RRsets, zone files or CNAME/MX/NS target values.

Creating a free DNS zone does not automatically create proxy/WAF configuration. Direct DNS is the default; protection requires an explicit request and an eligible backend or active Website Protection entitlement.

Read the current record and configuration before changing them. Prefer `GET /v1/dns/zones/{name}/records/config` for a read-only configuration lookup. Use the zone's `/records/protection` GET/POST endpoints to inspect or toggle mitigation without a hosting service ID. That switch preserves proxy routing, origin IPs, DNS values and TTL; it does not remove the proxy or free a protected-domain slot.

## Website Protection and domain migration

The €25/month Website Protection plan includes 10 protected domains. Capacity counts distinct protected DNS zones, including protection transitions that are pending. Additional records under the same zone do not consume a new zone slot. Unprotected free DNS zones do not consume those protected-domain slots.

One protected hostname can use multiple backend servers. Follow the endpoint's backend/record schema and read back the saved routing; supplying a backend array replaces that array. The current release supports IP-based affinity. Automatic origin-health checks and failover are not guaranteed; remove unavailable origins through the API and verify traffic before relying on a migration. Traffic statistics describe WAF/proxy traffic, not authoritative DNS query statistics.

For a domain replacement:

1. Add the new domain/zone and configure its origin routing.
2. Enable protection while checking available domain capacity.
3. Upload your own certificate in advance, or arrange automatic issuance once DNS points to the proxy.
4. Verify certificate configuration, DNS resolution and an HTTPS request through the proxy.
5. Switch the website and retain the old domain for redirects while a protected slot remains available.
6. When the old domain is no longer needed, turn off proxy routing for its protected records or remove its zone through the appropriate endpoint, then check capacity again. Switching mitigation off alone keeps the proxy and does not free a slot.

Old and new protected domains each use a slot. If all 10 are occupied, retire an old protected domain or obtain more capacity before protecting another; the API does not promise a temporary extra slot. DNSSEC delegation must be retired safely before deleting a signed DNS zone.

## SSL readiness and validation errors

Automatic certificate issuance requires the domain to point to the proxy. You can pre-configure routing and upload a valid certificate and its matching private key before switching DNS.

Use the documented `upload-ssl` endpoint and read back with `get-ssl`. Upload validation checks certificate syntax, hostname coverage, validity dates and the matching private key before provider writes. Invalid inputs return a safe 400 error such as `invalid_ssl_cert`, `invalid_ssl_key`, `ssl_key_mismatch`, `invalid_ssl_domain`, `ssl_cert_expired` or `ssl_cert_not_yet_valid`. Use the actual returned code and message.

Read `data.status`, `data.ready` and `data.readiness_scope`. A scope of `certificate_configuration` means readiness covers the configured certificate. It does not establish DNS propagation, public browser trust or successful HTTPS on every proxy edge. Verify those separately.

An accepted upload can return `pending` or `unknown` when readback is not yet confirmed. Keep the upload's `expected_fingerprint256`, poll `get-ssl`, and compare the reported certificate fingerprint before considering it ready. A provider lookup failure is an error, not proof that the certificate is absent. Private key material is never returned in these readiness responses.

## Errors, rate limits and audit

Responses carry `x-request-id`; API errors include the same request ID. SDK errors expose it for support and application logs. You can supply `x-client-request-id` as your own correlation label; it does not replace an idempotency key.

Inspect HTTP status and the canonical `error.code`, `error.message`, `error.request_id` and `error.field_errors`. Flat `code`, `message`, `request_id`, `field_errors`, `details` and `status` fields are legacy compatibility fields and may still be returned. New integrations should read the nested envelope:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

Production enforces the published response schemas; treat missing or null optional data according to the endpoint contract.

For 429 responses, follow `Retry-After`. Rate headers include `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` when authenticated accounting is available. Keep automatic retries bounded and retain a write's original identity.

Use `GET /v1/audit/events` with the documented filters to review account-owned activity. For support, include the action, time, SDK version, HTTP status, error code and request ID. Never send secrets, private keys or complete authorization headers.

## Webhooks and application state

Subscribe only to events supported by the current capabilities and webhook event catalog. Verify signatures against the exact raw request body, acknowledge deliveries promptly and deduplicate by event ID. A delivery retry must not execute the same business operation twice.

Use delivery history and the webhook test endpoint to verify your receiver. Secret rotation returns the new secret once; update the receiver's verification configuration. For completion-sensitive workflows, correlate notifications with the resource or operation and read its current state.

## Related guides and downloads

- [Native SDK, CLI and MCP purchase/recovery examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery).
- [API keys and authentication](https://docs.blazingfast.io/howto/api/api-authentication-scopes-and-security).
- [SDK and CLI installation](https://docs.blazingfast.io/howto/api/api-cli-sdks-and-mcp-integration-patterns).
- [Hosted AI connections](https://docs.blazingfast.io/howto/api/connect-ai-assistant).
- [Local MCP](https://docs.blazingfast.io/howto/api/local-mcp).
- [Orders and payments](https://docs.blazingfast.io/howto/api/order-and-pay-from-balance).
- [DNS and Website Protection automation](https://docs.blazingfast.io/howto/api/dns-and-protection-automation).
- [Troubleshooting](https://docs.blazingfast.io/howto/api/automation-troubleshooting).
- [Full endpoint map](https://docs.blazingfast.io/docs/api-endpoints.html) and [OpenAPI JSON](https://docs.blazingfast.io/api/public/openapi/userapi-v1).

The schema describes public HTTP operations. SDKs handle request signing; MCP tools additionally apply the connection's permissions and policy.

---

# Troubleshoot API and AI connections



Source: https://docs.blazingfast.io/howto/api/automation-troubleshooting



Resolve missing tools, denied access, expired keys and uncertain changes without repeating actions.



First identify how you connected: a hosted AI connection uses BlazingFast sign-in and AI connection permissions; an SDK, CLI or local MCP server uses an API key.

## Missing tools or blocked AI actions

1. Confirm the BlazingFast app is selected in the conversation.
2. Open [AI connections](https://my.blazingfast.io/settings/connections) and check its expiry, selected permissions and policy.
3. If the required permission is available, enable it and save. If it was not included in the original consent, reconnect.
4. Refresh the app connection's tool list after a tool update, then start a new conversation.
5. For pending changes, check the operation request's status instead of submitting a second request.

Read only blocks writes. Write with approval waits for the dashboard. Full access executes permitted changes automatically. The AI platform can still decline a tool call or request its own confirmation.

If the AI client says its own safety gate blocked a call, this does not prove BlazingFast received it. Check the invoice, service or operation status before trying again.

## API errors

| Result | What to check |
| --- | --- |
| 400 | Required fields, supported codes, types and mutually exclusive options |
| 401 | Key/token, secret, expiry, enabled state; computer clock for signed requests |
| 403 | Required scopes, account/project access and IP restrictions |
| 404 | Resource identifier, ownership and endpoint path |
| 409 | Current service state, conflicts or an operation already in progress |
| 429 | Request rate; follow Retry-After when supplied |
| 5xx or timeout | Read current state and retain the original request key before retrying a write |

An IP-restricted endpoint can return 403 before key authentication. Follow the API origin displayed in your account's Settings → API page. Use the origin alone as `BF_API_BASE_URL`, with no trailing `/v1`.

## CLI command or local MCP executable not found

Run `bf --version` and `bf --help` in the virtual environment where you installed it. Activate that environment or configure the full executable path. Desktop apps do not necessarily inherit your terminal's PATH or environment.

Update using the newest downloadable archive when a command is absent in an older SDK. Do not install a similarly named package from another source.

## A change has an uncertain outcome

A timeout is not proof that nothing happened. Read the resource, task or invoice. Preserve the same retry key and payload if retrying that action. Do not generate a replacement key or pay the invoice a second time without checking its balance.

For Website Protection, a response can say configuration was saved but synchronization is incomplete. Read back the saved configuration and follow the returned status; do not describe it as a rollback.

## Understanding resource usage

VPS CPU is a fraction: 0.25 means 25%. Network and disk I/O byte counters are cumulative; rates require two samples and the elapsed time. VM disk counters do not establish guest filesystem free space. Missing values mean unavailable. Backup pool usage and the number of a VPS's backups answer different questions.

## Contact support

Include the action, time and timezone, SDK version, HTTP status, error code, and `request_id` or `x-request-id` if supplied. Do not include API secrets, passwords, private keys or full authorization headers.

---

# API endpoint reference



Source: https://docs.blazingfast.io/api/reference



Find each public endpoint's parameters, required permissions and responses.



This reference is generated from the current OpenAPI schema and documents 182 public operations. Each operation has a stable operationId and shows its method, path, parameters, required permissions and response models. cURL is selected by default; switch to Node.js, PHP, Python or Go for native HTTP examples. Download the [OpenAPI JSON](https://docs.blazingfast.io/api/public/openapi/userapi-v1) for client generation.

Use the [integration guide](https://docs.blazingfast.io/api/integration-guide) for SDK/CLI 0.1.17 installation, authentication, pagination, retries, idempotency, webhooks and workflows. Generic OpenAPI clients do not automatically implement HMAC signing; use Bearer authentication or an official SDK unless you implement signing yourself.

## Current purchase and operation workflows

SDK/CLI 0.1.17 supports contract 2026-10-07.1. Read GET /v1/version and GET /v1/capabilities, then discover product purchase policies and requirements before configuring a purchase. A quote is optional: discovery can lead directly to an authorized deployment. Quotes do not reserve stock or lock prices; send an authorized max_total ceiling for the full final order amount.

Draft order creation does not charge the account. Atomic deployment is the documented exception: it combines order creation, payment of the full final order amount from account balance and queued provisioning. Paid is not ready; accepted is not completed. Service lifecycle status is separate from runtime power state.

Supported tracked deployment, VPS and dedicated writes can return a canonical operation receipt and be recovered using their original idempotency key. This does not extend recovery to every write or historical request. See [HTTP, SDK, CLI and MCP examples](https://docs.blazingfast.io/howto/api/machine-readable-purchase-and-operation-recovery). DNSSEC uses its separate endpoint and state contract.

Pagination is endpoint-specific. Follow each endpoint's page/limit, cursor/next_cursor or offset/next_offset contract. limit is the canonical page-size request parameter; page_size and pageSize are deprecated compatibility aliases only where documented.

For service lists, ownership and filters are applied server-side before pagination. GET /v1/services defaults to active and suspended. group_by=type groups only the current page; GET /v1/services/grouped returns the complete inventory under its documented status/type filters, with its legacy active-only default. Pass status explicitly for this compatibility endpoint; prefer /v1/services?statuses=active,suspended&group_by=type for new automation.

API errors use the canonical nested error.code, error.message, error.request_id and error.field_errors structure. Flat error fields remain legacy compatibility fields. Most CLI lifecycle --request-key flags are optional; DNSSEC enable/disable require an explicit key. Preserve generated keys for retries. Examples describe requests and responses; this page does not send API requests.

## Customer API reference

API origin: https://api.blazingfast.io

OpenAPI: https://docs.blazingfast.io/api/public/openapi/userapi-v1

### Pagination

Pagination is endpoint-specific. Follow the pagination model documented for each endpoint; do not send page to a cursor- or offset-based endpoint.

Page-based lists such as GET /v1/services use page and limit, with page, pageSize, total and pages in the response. Example: GET /v1/services?page=2&limit=50. Stop when page >= pages or items is empty.

Cursor-based lists such as GET /v1/api-credentials use limit and cursor. Pass the returned next_cursor unchanged on the next request; null means finished.

Offset-based lists such as GET /v1/products and GET /v1/dns/zones?view=summary use limit and offset. Use the returned next_offset; null means finished. DNS zone summary has its own default limit, while the default legacy view is not paginated.

limit is the canonical page-size parameter. Deprecated page_size and pageSize request aliases are retained only on endpoints that explicitly document them; supplied size values must match. Defaults and maximum sizes are endpoint-specific. Page-based responses retain pageSize for compatibility.

GET /v1/services applies ownership, status, type, search, external_id and label filters server-side before pagination and counts. Default states are active and suspended; historical services require an explicit status selection. group_by=type groups only the current page. GET /v1/services/grouped returns the complete inventory under its documented status/type filters, without pagination; its legacy compatibility default is active only; MCP/automation clients should pass status explicitly and prefer the paginated service endpoint with statuses=active,suspended.

### GET /v1/api-credentials

List your API credentials

Operation ID: apiCredentials

Owner-only, secret-free inventory. Cursor pagination defaults to 50. Managed MCP credentials are read-only here.

Scopes: api_credentials.read

- query limit (optional): Maximum items, default 50.
- query cursor (optional): Next UUID cursor.
- query include_revoked (optional): Include revoked keys.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Credential inventory.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example integration",
      "prefix": "ak_EXAMPLE",
      "mode": "signed",
      "enabled": true,
      "created_at": "2026-10-01T00:00:00.000Z",
      "expires_at": "2026-11-01T00:00:00.000Z",
      "revoked_at": null,
      "last_used_at": null,
      "last_used_ip": null,
      "scopes": [
        "billing.services.read"
      ],
      "allowed_cidrs": []
    }
  ],
  "next_cursor": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/api-credentials

Create a restricted API credential

Operation ID: apiCredentialCreate

Requires a stable Idempotency-Key. Requested scopes and allowed CIDRs cannot exceed the issuer; expiry is capped by the issuer. The secret is returned only on issuance or same-key retry within 24 hours. Managed MCP/support keys cannot delegate.

Scopes: api_credentials.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "audit.read",
          "api_credentials.read",
          "api_credentials.write",
          "oauth.connections.read",
          "oauth.connections.write",
          "billing.balance.read",
          "billing.invoices.read",
          "billing.orders.read",
          "billing.products.read",
          "billing.services.read",
          "billing.services.write",
          "billing.transactions.read",
          "billing.unpaid_total.read",
          "billing.order.create",
          "billing.invoice.pay",
          "vps.read",
          "vps.credentials.read",
          "vps.write",
          "dedicated.read",
          "dedicated.credentials.read",
          "dedicated.write",
          "dns.read",
          "dns.write",
          "domains.read",
          "domains.write",
          "ssh.read",
          "ssh.write",
          "firewall.read",
          "firewall.write",
          "storage.read",
          "storage.write",
          "tcp_proxy.read",
          "tcp_proxy.write",
          "webhooks.read",
          "webhooks.write"
        ]
      },
      "minItems": 1,
      "maxItems": 35
    },
    "mode": {
      "type": "string",
      "enum": [
        "signed",
        "bearer"
      ],
      "default": "signed"
    },
    "ttl_days": {
      "type": "integer",
      "minimum": 1,
      "maximum": 365,
      "default": 30
    },
    "allowed_cidrs": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64
      },
      "maxItems": 50
    }
  },
  "required": [
    "name",
    "scopes"
  ],
  "additionalProperties": false
}
```

Response 201: Created credential and signing secret.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example integration",
    "prefix": "ak_EXAMPLE",
    "mode": "signed",
    "enabled": true,
    "created_at": "2026-10-01T00:00:00.000Z",
    "expires_at": "2026-11-01T00:00:00.000Z",
    "revoked_at": null,
    "last_used_at": null,
    "last_used_ip": null,
    "scopes": [
      "billing.services.read"
    ],
    "allowed_cidrs": []
  },
  "secret": "sk_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEX"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/api-credentials/{id}

Read your credential metadata

Operation ID: apiCredential

Never returns signing secrets.

Scopes: api_credentials.read

- path id (required): Owned credential UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Credential metadata.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example integration",
    "prefix": "ak_EXAMPLE",
    "mode": "signed",
    "enabled": true,
    "created_at": "2026-10-01T00:00:00.000Z",
    "expires_at": "2026-11-01T00:00:00.000Z",
    "revoked_at": null,
    "last_used_at": null,
    "last_used_ip": null,
    "scopes": [
      "billing.services.read"
    ],
    "allowed_cidrs": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/api-credentials/{id}

Update a restricted API credential

Operation ID: apiCredentialUpdate

Change name, scopes, expiry, enabled state or allowed CIDRs without exceeding the current issuer. Revoked or managed credentials cannot be reactivated.

Scopes: api_credentials.write

- path id (required): Owned credential UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "audit.read",
          "api_credentials.read",
          "api_credentials.write",
          "oauth.connections.read",
          "oauth.connections.write",
          "billing.balance.read",
          "billing.invoices.read",
          "billing.orders.read",
          "billing.products.read",
          "billing.services.read",
          "billing.services.write",
          "billing.transactions.read",
          "billing.unpaid_total.read",
          "billing.order.create",
          "billing.invoice.pay",
          "vps.read",
          "vps.credentials.read",
          "vps.write",
          "dedicated.read",
          "dedicated.credentials.read",
          "dedicated.write",
          "dns.read",
          "dns.write",
          "domains.read",
          "domains.write",
          "ssh.read",
          "ssh.write",
          "firewall.read",
          "firewall.write",
          "storage.read",
          "storage.write",
          "tcp_proxy.read",
          "tcp_proxy.write",
          "webhooks.read",
          "webhooks.write"
        ]
      },
      "minItems": 1,
      "maxItems": 35
    },
    "allowed_cidrs": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64
      },
      "maxItems": 50
    },
    "enabled": {
      "type": "boolean"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    }
  },
  "additionalProperties": false
}
```

Response 200: Updated credential metadata.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example integration",
    "prefix": "ak_EXAMPLE",
    "mode": "signed",
    "enabled": true,
    "created_at": "2026-10-01T00:00:00.000Z",
    "expires_at": "2026-11-01T00:00:00.000Z",
    "revoked_at": null,
    "last_used_at": null,
    "last_used_ip": null,
    "scopes": [
      "billing.services.read"
    ],
    "allowed_cidrs": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/api-credentials/{id}

Revoke an API credential

Operation ID: apiCredentialRevoke

Disables an owned ordinary credential; does not delete history. Managed MCP grants use connection revocation instead.

Scopes: api_credentials.write

- path id (required): Owned credential UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Credential revoked.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/api-credentials/{id}/rotate

Rotate an API credential

Operation ID: apiCredentialRotate

Requires Idempotency-Key. Replaces prefix and secret immediately; old authentication stops working. Use a different management key, or the dashboard, to rotate the key used by an integration. Self-rotation is rejected to avoid losing access after an interrupted response. Superseded receipts never reveal obsolete secrets.

Scopes: api_credentials.write

- path id (required): Owned ordinary credential UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (optional)

```json
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
```

Response 200: Rotated credential and secret.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example integration",
    "prefix": "ak_EXAMPLE",
    "mode": "signed",
    "enabled": true,
    "created_at": "2026-10-01T00:00:00.000Z",
    "expires_at": "2026-11-01T00:00:00.000Z",
    "revoked_at": null,
    "last_used_at": null,
    "last_used_ip": null,
    "scopes": [
      "billing.services.read"
    ],
    "allowed_cidrs": []
  },
  "secret": "sk_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEX"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/oauth/connections

List connected applications

Operation ID: oauthConnections

Owner-only hosted MCP OAuth connection inventory. Does not expose access tokens, refresh tokens or internal client credentials. Connection-management transport must be configured.

Scopes: oauth.connections.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Connected applications.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "application": "Example application",
      "scopes": [
        "billing.services.read"
      ],
      "created_at": "2026-10-01T00:00:00.000Z",
      "expires_at": "2026-11-01T00:00:00.000Z",
      "policy": "read_only",
      "access_policy": "read_only",
      "enabled": true,
      "last_used_at": null,
      "revoked": false
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/oauth/connections/{id}

Revoke a connected application

Operation ID: oauthConnectionRevoke

Revokes only this account’s grant using the existing fenced revocation flow. Repeating revocation is safe. Does not grant or expand permissions.

Scopes: oauth.connections.write

- path id (required): Connection UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Connection revoked.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/audit/actions

List durable customer API action events

Operation ID: auditActions

Requested intent is saved before entering a write handler; accepted is not completion. Terminal operation results are recorded separately. Covers customer API and hosted MCP writes. Broader Billing dashboard/admin/committed state observations are available through audit/business. Updates are blocked; privileged retention deletes after the configured period.

Scopes: audit.read

- query limit (optional): Maximum items, default 50.
- query cursor (optional): Next event cursor.
- query resource_id (optional): Resource ID or zone name.
- query phase (optional): Action phase.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Account-owned action history.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "1",
      "request_id": "00000000-0000-4000-8000-000000000002",
      "actor": {
        "type": "api_key",
        "id": "00000000-0000-4000-8000-000000000001"
      },
      "action": "POST /v1/vps/:serviceId/reboot",
      "resource_id": "00000000-0000-4000-8000-000000000001",
      "phase": "accepted",
      "operation_id": null,
      "created_at": "2026-10-01T00:00:00.000Z"
    }
  ],
  "next_cursor": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/audit/business

List account-owned business audit events

Operation ID: auditBusiness

Durable Billing dashboard/admin request acceptance and committed service/invoice/order/lifecycle observations. A committed lifecycle log row is not proof of task completion. Database transitions without a verified human identity use system; identities are never inferred from metadata. Admin identity is withheld from customer responses. No payloads, credentials, provider errors or financial customer details are logged. This does not cover every action of other services or constitute a WORM export.

Scopes: audit.read

- query limit (optional): Maximum items, default 50 (1–100).
- query cursor (optional): Exclusive cursor returned as next_cursor.
- query actor_type (optional): Verified actor category.
- query resource_type (optional): service, invoice, order or account.
- query resource_id (optional): Owned resource UUID.
- query request_id (optional): Correlation UUID.
- query action (optional): Exact action.
- query phase (optional): requested, accepted, rejected, unknown or committed.
- query from (optional): Inclusive ISO timestamp.
- query to (optional): Inclusive ISO timestamp.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Owner-filtered business observations, newest first.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "1",
      "request_id": null,
      "actor": {
        "type": "system",
        "id": null
      },
      "source": "database",
      "action": "service.changed",
      "resource_type": "service",
      "resource_id": "00000000-0000-4000-8000-000000000001",
      "phase": "committed",
      "changes": {
        "before": {
          "status": "active"
        },
        "after": {
          "status": "suspended"
        }
      },
      "created_at": "2026-10-01T00:00:00.000Z"
    }
  ],
  "next_cursor": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/{serviceId}/dnssec

Read DNSSEC status

Operation ID: domainDnssec

Returns the locally saved DNSSEC state for your registered domain. Use action refresh to check current registration state. Zone signing and parent propagation are separate from enabled registration status.

Scopes: domains.read

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Saved DNSSEC status.

Illustrative response:

```json
{
  "ok": true,
  "domain": "example.com",
  "tld": "com",
  "support": "supported",
  "nameservers": [
    "dns1.blazingfast.io",
    "dns2.blazingfast.io"
  ],
  "keys": [],
  "status": "not_configured",
  "delegationStatus": "not_verified",
  "dnsProvider": "managed",
  "canEnable": true,
  "canDisable": false,
  "enabled": false,
  "checkedAt": "2026-10-01T00:00:00.000Z",
  "operation": "idle",
  "source": "local"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/{serviceId}/dnssec

Update or check DNSSEC

Operation ID: domainDnssecUpdate

Enable managed signing or submit external public DNSKEY records, disable delegation without deleting signing keys, or refresh status. Enable/disable require acknowledgement and an Idempotency-Key. Refresh requires domains.read; changes require domains.write. HTTP 200 returns refresh state; HTTP 202 means enable/disable accepted, not completed: poll the same DNSSEC GET for operation and errorCode. operationId is a DNSSEC operation UUID, not a generic /v1/operations handle. queued/pending/running are ongoing; unconfirmed requires reconciliation; failed is not success. idle with the intended registrar status confirms registrar configuration only. delegationStatus=not_verified never proves parent-zone propagation. Do not repeat an unconfirmed change.

Scopes: domains.read OR domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header Idempotency-Key (optional): Required for enable/disable: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse identical payloads; not required for refresh.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "const": "enable",
          "enum": [
            "enable"
          ]
        },
        "mode": {
          "type": "string",
          "const": "managed",
          "enum": [
            "managed"
          ]
        },
        "acknowledge": {
          "type": "boolean",
          "const": true,
          "enum": [
            true
          ]
        }
      },
      "required": [
        "action",
        "mode",
        "acknowledge"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "const": "enable",
          "enum": [
            "enable"
          ]
        },
        "mode": {
          "type": "string",
          "const": "external",
          "enum": [
            "external"
          ]
        },
        "acknowledge": {
          "type": "boolean",
          "const": true,
          "enum": [
            true
          ]
        },
        "keys": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "flags": {
                "type": "number",
                "const": 257,
                "enum": [
                  257
                ]
              },
              "protocol": {
                "type": "number",
                "const": 3,
                "enum": [
                  3
                ]
              },
              "alg": {
                "type": "integer"
              },
              "pub_key": {
                "type": "string",
                "minLength": 40,
                "maxLength": 4096,
                "pattern": "^[A-Za-z0-9+/]+={0,2}$"
              }
            },
            "required": [
              "flags",
              "protocol",
              "alg",
              "pub_key"
            ],
            "additionalProperties": false
          },
          "minItems": 1,
          "maxItems": 4
        }
      },
      "required": [
        "action",
        "mode",
        "acknowledge",
        "keys"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "const": "disable",
          "enum": [
            "disable"
          ]
        },
        "acknowledge": {
          "type": "boolean",
          "const": true,
          "enum": [
            true
          ]
        }
      },
      "required": [
        "action",
        "acknowledge"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "const": "refresh",
          "enum": [
            "refresh"
          ]
        }
      },
      "required": [
        "action"
      ],
      "additionalProperties": false
    }
  ]
}
```

Response 200: Current DNSSEC state after refresh (domains.read).

Response 202: Enable/disable accepted with domains.write; poll this domain’s DNSSEC GET, not the generic operation endpoint.

Illustrative response:

```json
{
  "ok": true,
  "domain": "example.com",
  "tld": "com",
  "support": "supported",
  "nameservers": [
    "dns1.blazingfast.io",
    "dns2.blazingfast.io"
  ],
  "keys": [],
  "status": "not_configured",
  "delegationStatus": "not_verified",
  "dnsProvider": "managed",
  "canEnable": false,
  "canDisable": false,
  "enabled": false,
  "checkedAt": "2026-10-01T00:00:00.000Z",
  "operation": "queued",
  "operationId": "00000000-0000-4000-8000-000000000002",
  "requestedAction": "enable",
  "source": "local"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/history

List DNS change history

Operation ID: dnsHistory

Owned-zone changes with DNS values and protection state. Stable cursor continuation; only this owner’s history is returned.

Scopes: dns.read

- path name (required): Zone or domain name.
- query limit (optional): Maximum changes (default 10; 1–50).
- query cursor (optional): nextCursor returned by the preceding response; scoped to this owner and zone.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS change history with nextCursor.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000002",
      "action": "records.update",
      "status": "applied",
      "actorType": "userapi",
      "restoredFromId": null,
      "changes": [
        {
          "name": "example.com.",
          "type": "A",
          "changetype": "REPLACE",
          "beforeTtl": 300,
          "afterTtl": 300,
          "beforeValues": [
            "192.0.2.9"
          ],
          "afterValues": [
            "192.0.2.10"
          ]
        }
      ],
      "protectionChanges": [],
      "beforeRecordCount": 3,
      "afterRecordCount": 3,
      "createdAt": "2026-10-01T00:00:00.000Z"
    }
  ],
  "nextCursor": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dns/zones/{name}/history/{changeId}/restore

Restore DNS change

Operation ID: dnsHistoryRestore

Restores the state before the selected applied change, including protection and origin addresses. Requires acknowledgement, a stable retry key and current entitlements. A locked or ambiguous zone is not modified.

Scopes: dns.write

- path name (required): Zone or domain name.
- path changeId (required): Owned DNS change UUID.
- header Idempotency-Key (required): Stable retry key.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "acknowledge": {
      "type": "boolean",
      "const": true,
      "enum": [
        true
      ]
    }
  },
  "required": [
    "acknowledge"
  ],
  "additionalProperties": false
}
```

Response 200: Restored DNS/protection state or already-current result.

Illustrative response:

```json
{
  "ok": true,
  "appliedTo": "live_dns",
  "changeId": "00000000-0000-4000-8000-000000000001",
  "restoredFromId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/stats

Read Website Protection statistics

Operation ID: dnsStats

Website Protection (WAF) traffic aggregates for your owned zone and subdomains, bounded to current ownership. This compatibility route does not report authoritative DNS query statistics. Requests, bytes, latency, cache-hit percentage, decisions, countries and automation categories. No individual visitor identities or raw logs. Missing collection is an error, not zero traffic.

Scopes: dns.read

- path name (required): Zone or domain name.
- query range (optional): Window; defaults to 24h.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Owned-domain network aggregates. Requests are counts; bytes are bytes; latency is milliseconds.

Illustrative response:

```json
{
  "ok": true,
  "domain": "example.com",
  "range": "24h",
  "since": "2026-10-01T00:00:00.000Z",
  "until": "2026-11-01T00:00:00.000Z",
  "updatedAt": "2026-10-01T00:00:00.000Z",
  "lastEventAt": null,
  "coverage": "proxy_network",
  "coverageNote": "Proxy traffic only.",
  "summary": {
    "requests": 0,
    "bytes": 0,
    "averageResponseMs": 0,
    "cacheHitPercent": 0,
    "serverErrors": 0,
    "blocked": 0
  },
  "traffic": [],
  "countries": [],
  "automation": [],
  "statuses": [],
  "decisions": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/regions

List regions

Operation ID: regions

Lists regions with VPS image choices or public orderable dedicated stock. Codes are lowercase; this does not reserve capacity.

Scopes: billing.products.read

- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Region list with next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "nl",
      "name": "Netherlands"
    },
    {
      "id": "pt",
      "name": "Portugal"
    }
  ],
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products

List products

Operation ID: products

Flat public, active product variants with public, active parent products. type is the high-level normalized service family; product_code is the more specific purchasable product family. tcp-proxy maps to type=other, waf to type=dns, and license to type=other. Do not substitute product_code values into a type filter. id is the readable SKU; product_id and variant_id are order identifiers. Region and type eligibility are applied before pagination. CPU is vCPUs for VPS or sockets for dedicated; ram is MiB and disk is GiB. billing_cycles contains server-configured or converted period prices in the requested currency, exact decimal strings, unit/count and setup_fee. price prefers the monthly option. Account currency governs quotes and orders. configuration_url discovers required fields, defaults, compatible OS choices, connectivity and IP add-ons. Add-ons and tax are excluded from catalog prices: quote the complete cart before ordering. Domain pricing requires a live domain quote. available is not a reservation; capacity_verified=false for VPS. Dedicated available_stock is known compatible stock. A backend outage returns partial=true, unavailable_types and availability=unknown where possible; unknown stock is null, not zero. Image/stock snapshots are cached internally up to 15 seconds; checkout revalidates.

Scopes: billing.products.read

- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query product_code (optional): More specific purchasable product family; distinct from type. tcp-proxy maps to other, waf to dns, license to other.
- query region (optional): Region code from GET /v1/regions, for example nl or pt. Case-insensitive.
- query type (optional): High-level normalized type filter; tcp-proxy/license use other and waf uses dns. Distinct from product_code; applied before pagination.
- query currency (optional): Configured pricing currency: EUR or USD, default EUR.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Flat product list with next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "8G",
      "product_id": "00000000-0000-4000-8000-000000000001",
      "variant_id": "00000000-0000-4000-8000-000000000002",
      "name": "Example VPS",
      "type": "vps",
      "product_code": "vps",
      "variant_code": "8G",
      "region": "nl",
      "regions": [
        "nl"
      ],
      "cpu": 4,
      "cpu_unit": "vcpus",
      "ram": 8192,
      "ram_unit": "MiB",
      "disk": 100,
      "disk_unit": "GiB",
      "price": "12.00",
      "billing_cycle": "monthly",
      "billing_cycles": [
        {
          "billing_cycle": "monthly",
          "unit": "MONTH",
          "count": 1,
          "period_months": 1,
          "price": "12.00",
          "setup_fee": "0",
          "currency": "EUR"
        },
        {
          "billing_cycle": "quarterly",
          "unit": "QUARTAL",
          "count": 1,
          "period_months": 3,
          "price": "30.00",
          "setup_fee": "0",
          "currency": "EUR"
        }
      ],
      "currency": "EUR",
      "available": true,
      "capacity_verified": false,
      "configuration_code": null,
      "available_stock": null
    }
  ],
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}

List products in a region

Operation ID: getProductsByRegion

Flat public, active product variants with public, active parent products. type is the high-level normalized service family; product_code is the more specific purchasable product family. tcp-proxy maps to type=other, waf to type=dns, and license to type=other. Do not substitute product_code values into a type filter. id is the readable SKU; product_id and variant_id are order identifiers. Region and type eligibility are applied before pagination. CPU is vCPUs for VPS or sockets for dedicated; ram is MiB and disk is GiB. billing_cycles contains server-configured or converted period prices in the requested currency, exact decimal strings, unit/count and setup_fee. price prefers the monthly option. Account currency governs quotes and orders. configuration_url discovers required fields, defaults, compatible OS choices, connectivity and IP add-ons. Add-ons and tax are excluded from catalog prices: quote the complete cart before ordering. Domain pricing requires a live domain quote. available is not a reservation; capacity_verified=false for VPS. Dedicated available_stock is known compatible stock. A backend outage returns partial=true, unavailable_types and availability=unknown where possible; unknown stock is null, not zero. Image/stock snapshots are cached internally up to 15 seconds; checkout revalidates. Applies region restrictions on the server before pagination. A conflicting region query parameter is rejected.

Scopes: billing.products.read

- path region (required): Region code, for example nl or pt; all includes every eligible region.
- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query product_code (optional): More specific purchasable product family; distinct from type. tcp-proxy maps to other, waf to dns, license to other.
- query type (optional): High-level normalized type filter; tcp-proxy/license use other and waf uses dns. Distinct from product_code.
- query currency (optional): Configured pricing currency: EUR or USD, default EUR.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Region-filtered flat product list with next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "8G",
      "product_id": "00000000-0000-4000-8000-000000000001",
      "variant_id": "00000000-0000-4000-8000-000000000002",
      "name": "Example VPS",
      "type": "vps",
      "product_code": "vps",
      "variant_code": "8G",
      "region": "nl",
      "regions": [
        "nl"
      ],
      "cpu": 4,
      "cpu_unit": "vcpus",
      "ram": 8192,
      "ram_unit": "MiB",
      "disk": 100,
      "disk_unit": "GiB",
      "price": "12.00",
      "billing_cycle": "monthly",
      "billing_cycles": [
        {
          "billing_cycle": "monthly",
          "unit": "MONTH",
          "count": 1,
          "period_months": 1,
          "price": "12.00",
          "setup_fee": "0",
          "currency": "EUR"
        },
        {
          "billing_cycle": "quarterly",
          "unit": "QUARTAL",
          "count": 1,
          "period_months": 3,
          "price": "30.00",
          "setup_fee": "0",
          "currency": "EUR"
        }
      ],
      "currency": "EUR",
      "available": true,
      "capacity_verified": false,
      "configuration_code": null,
      "available_stock": null
    }
  ],
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}/list

List product codes by region

Operation ID: productCodes

Compact grouped public variant codes: products maps each family to an array of exact SKUs. Region eligibility is applied before pagination. limit counts variants across all families, not families; default 50. Follow next_offset until null and merge groups. Codes do not prove available stock; read the variant details and options. all includes all eligible regions; use a specific region for details and deployment. partial=true means collection is incomplete, not known zero stock. Existing flat catalog endpoints remain unchanged.

Scopes: billing.products.read

- path region (required): Region code or all.
- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query currency (optional): Pricing currency: EUR or USD; defaults to EUR. Quotes and orders use account currency.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Grouped family/SKU discovery with continuation.

Illustrative response:

```json
{
  "ok": true,
  "region": "nl",
  "products": {
    "vps": [
      "8G"
    ]
  },
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}/list/{productCode}

List variant codes for a family

Operation ID: getProductsByRegionListByProductCode

Same compact grouped response, restricted to the selected product family before pagination. An empty family array means no matching public plans on this page. Read detail availability separately; this does not reserve stock.

Scopes: billing.products.read

- path region (required): Eligible region, for example nl or pt. A single region is required.
- path productCode (required): Product family.
- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query currency (optional): Pricing currency: EUR or USD; defaults to EUR. Quotes and orders use account currency.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Selected family and exact SKUs with continuation.

Illustrative response:

```json
{
  "ok": true,
  "region": "nl",
  "products": {
    "vps": [
      "8G"
    ]
  },
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}/{productCode}/{variantCode}

Read a product by public code

Operation ID: getProduct

Exact eligible region/family/SKU lookup. Returns safe hardware, public billing prices, availability, order UUIDs and links to prices/options/quote/deployment. Duplicate public SKUs in the family/region return catalog_variant_ambiguous (409); no plan is silently selected. Missing or hidden plans return 404. Provider outages may return unknown availability; they are never represented as known zero stock. This read is not a reservation.

Scopes: billing.products.read

- path region (required): Eligible region, for example nl or pt. A single region is required.
- path productCode (required): Product family.
- path variantCode (required): Exact case-sensitive public SKU, for example 2G or PTV4-1. Never an internal inventory ID.
- query currency (optional): Pricing currency: EUR or USD; defaults to EUR. Quotes and orders use account currency.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Exact public plan and discovery links.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "8G",
    "product_id": "00000000-0000-4000-8000-000000000001",
    "variant_id": "00000000-0000-4000-8000-000000000002",
    "name": "Example VPS",
    "type": "vps",
    "product_code": "vps",
    "variant_code": "8G",
    "region": "nl",
    "regions": [
      "nl"
    ],
    "cpu": 4,
    "cpu_unit": "vcpus",
    "ram": 8192,
    "ram_unit": "MiB",
    "disk": 100,
    "disk_unit": "GiB",
    "price": "12.00",
    "billing_cycle": "monthly",
    "billing_cycles": [
      {
        "billing_cycle": "monthly",
        "unit": "MONTH",
        "count": 1,
        "period_months": 1,
        "price": "12.00",
        "setup_fee": "0",
        "currency": "EUR"
      },
      {
        "billing_cycle": "quarterly",
        "unit": "QUARTAL",
        "count": 1,
        "period_months": 3,
        "price": "30.00",
        "setup_fee": "0",
        "currency": "EUR"
      }
    ],
    "currency": "EUR",
    "available": true,
    "capacity_verified": false,
    "configuration_code": null,
    "available_stock": null,
    "prices_url": "/v1/products/nl/vps/8G/prices",
    "options_url": "/v1/products/nl/vps/8G/options",
    "quote_url": "/v1/billing/orders/preview",
    "deploy_url": "/v1/deploy/nl/vps/8G"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}/{productCode}/{variantCode}/prices

Read billing prices by public code

Operation ID: productPrices

Base-plan prices only, as exact decimal strings with unit/count, setup_fee and currency. Optional billing_cycle filters configured periods; an unavailable period returns billing_cycle_not_available (400). An omitted period returns all public prices in the requested currency. Add-ons and tax require POST /v1/billing/orders/preview using the returned order UUIDs. Domain prices require a domain quote. price_scope=base_plan is not a final payable amount.

Scopes: billing.products.read

- path region (required): Eligible region, for example nl or pt. A single region is required.
- path productCode (required): Product family.
- path variantCode (required): Exact case-sensitive public SKU, for example 2G or PTV4-1. Never an internal inventory ID.
- query currency (optional): Pricing currency: EUR or USD; defaults to EUR. Quotes and orders use account currency.
- query billing_cycle (optional): Optional billing period from the returned values.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Configured billing prices; never a fabricated price for a missing period.

Illustrative response:

```json
{
  "ok": true,
  "region": "nl",
  "product_code": "vps",
  "variant_code": "8G",
  "currency": "EUR",
  "prices": [
    {
      "billing_cycle": "monthly",
      "unit": "MONTH",
      "count": 1,
      "period_months": 1,
      "price": "12.00",
      "setup_fee": "0",
      "currency": "EUR"
    },
    {
      "billing_cycle": "quarterly",
      "unit": "QUARTAL",
      "count": 1,
      "period_months": 3,
      "price": "30.00",
      "setup_fee": "0",
      "currency": "EUR"
    }
  ],
  "price_scope": "base_plan",
  "pricing_mode": "configured",
  "quote_url": "/v1/billing/orders/preview"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/products/{region}/{productCode}/{variantCode}/options

Read configuration options by public code

Operation ID: productOptions

Same authoritative configuration discovery as the UUID order-options endpoint, resolved by eligible region, family and exact SKU. Returns required inputs, defaults, compatible OS choices, owned SSH-key selection fields, connectivity options and IP/add-on limits. No private provider settings, inventory identities or credentials. Discovery does not reserve stock or pay.

Scopes: billing.products.read

- path region (required): Eligible region, for example nl or pt. A single region is required.
- path productCode (required): Product family.
- path variantCode (required): Exact case-sensitive public SKU, for example 2G or PTV4-1. Never an internal inventory ID.
- query currency (optional): Pricing currency: EUR or USD; defaults to EUR. Quotes and orders use account currency.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Validated public order options with exact order UUIDs.

Illustrative response:

```json
{
  "ok": true,
  "region": "nl",
  "product_code": "vps",
  "variant_code": "8G",
  "productId": "00000000-0000-4000-8000-000000000001",
  "variantId": "00000000-0000-4000-8000-000000000002",
  "supported": true,
  "capacityVerified": false,
  "requiredFields": [
    {
      "field": "hostname",
      "label": "Hostname",
      "description": "Server hostname.",
      "format": "hostname"
    },
    {
      "field": "location",
      "label": "Location",
      "description": "Location code."
    },
    {
      "field": "os.code",
      "label": "Operating system",
      "description": "Operating system code."
    }
  ],
  "locations": [
    {
      "code": "NL",
      "name": "Netherlands",
      "operatingSystems": [
        {
          "code": "debian-13",
          "name": "Debian",
          "family": "debian",
          "version": "13",
          "arch": "amd64",
          "isDefault": true
        }
      ]
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/my/services

List my purchased services

Operation ID: listMyServices

Read-only alias of GET /v1/services with identical ownership, scope, filters and response contract. Defaults to active+suspended; terminated services require an explicit filter. Lifecycle status is separate from runtime power. Hostname and region are included when known; passwords are available only from separately scoped credential endpoints.

Scopes: billing.services.read

- query status (optional): Service lifecycle status; defaults to active and suspended when no status filter is supplied. Power state is separate.
- query type (optional): High-level normalized service family: vps, dedicated, webhosting, storage, dns, domain or other (comma-separated). Distinct from catalog product_code: tcp-proxy and license map to other; waf maps to dns. Applied before pagination; use discovered product_code for purchasing.
- query statuses (optional): Comma-separated lifecycle statuses, for example active,suspended. Use this or status, not both. Filtering and counts use service status, never runtime power state.
- query types (optional): Comma-separated service types. Alias for type; do not supply both.
- query search (optional): Search hostname, customer IPv4/IPv6, display name, product name, SKU or full service UUID; maximum 200 characters. Applied before pagination.
- query external_id (optional): Exact customer integration reference; applied before pagination.
- query label (optional): Exact metadata label match: key=value. Applied before pagination.
- query include_counts (optional): Request counts only for selected statuses, with the same ownership, type and search filters. Omitted by default.
- query group_by (optional): Group the current page by type, retaining items and pagination.
- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Filtered purchased service instances.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "status": "active",
      "displayName": "Example VPS",
      "hostname": "server.example.com",
      "type": "vps",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "dueDate": "2026-11-01T00:00:00.000Z",
      "billingUnit": "MONTH",
      "billingCount": 1,
      "sku": "4G",
      "ipv4": "192.0.2.10",
      "ipv6": null,
      "meta": {
        "serviceType": "vps"
      }
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/images

List VPS images

Operation ID: vpsImages

Returns VM-template OS codes and their region, family, version, architecture and default flag, without internal template references. Optional product_id and variant_id must be supplied together to restrict to a public VPS plan and its region. For full plan-specific configuration use the existing order-options endpoint. compatibility_verified=false means this is catalog discovery, not a physical capacity or placement guarantee. New VPS order configuration uses userConfig.os.code and uppercase userConfig.location.

Scopes: billing.products.read

- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query region (optional): Region code from GET /v1/regions, for example nl or pt. Case-insensitive.
- query product_id (optional): Public product UUID; supply with variant_id.
- query variant_id (optional): Public VPS variant UUID; supply with product_id.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: VPS OS images with next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": "debian-13",
      "name": "Debian",
      "family": "debian",
      "version": "13",
      "arch": "amd64",
      "is_default": true,
      "region": "nl"
    }
  ],
  "next_offset": null,
  "compatibility_verified": false
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/images

List dedicated images

Operation ID: dedicatedImages

Returns compatible OS profile IDs for public dedicated configurations with available stock. Filter by region and configuration_code from the product catalog. An image ID can occur in several configurations; preserve its region/configuration context. Supply the numeric id as osProfileId when creating a dedicated deployment.

Scopes: dedicated.read

- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- query region (optional): Region code from GET /v1/regions, for example nl or pt. Case-insensitive.
- query configuration_code (optional): Dedicated configuration code from GET /v1/products.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Compatible dedicated OS profiles with next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [
    {
      "id": 1,
      "name": "Debian 13",
      "region": "pt",
      "configuration_code": "EXAMPLE-PT",
      "ssh_keys_supported": true
    }
  ],
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/ssh-keys

List my SSH keys

Operation ID: getSshKeys

Read-only alias of GET /v1/ssh/keys. Returns only keys owned by the authenticated account with names, fingerprints and public-key metadata; no private keys. Keeps the existing keys response contract (not a paginated catalog collection). Retrieve a selected public key through /v1/ssh/keys/{id}/public when required for provisioning.

Scopes: ssh.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Owned SSH key metadata.

Illustrative response:

```json
{
  "ok": true,
  "keys": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example key",
      "algorithm": "ed25519",
      "fingerprint": "SHA256:example-fingerprint",
      "isPrimary": false,
      "hasPrivateKey": false,
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-01T00:00:00.000Z"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/tcp-proxy/{serviceId}

Read TCP Proxy configuration

Operation ID: getTcpProxy

Returns only customer configuration. Requires ownership or project service.view permission. tcpProxy is null for non-TCP services.

Scopes: tcp_proxy.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: TCP Proxy configuration.

Illustrative response:

```json
{
  "tcpProxy": {
    "proxyIp": "192.0.2.20",
    "backendIp": "192.0.2.10",
    "ports": [
      {
        "listen": 443,
        "backend": 443
      }
    ],
    "includedPorts": 1,
    "additionalPorts": 0,
    "defaults": {},
    "allowedSourceCidrs": [],
    "blockedSourceCidrs": [],
    "countryPolicy": {
      "mode": "disabled",
      "countries": []
    },
    "status": "active"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/tcp-proxy/{serviceId}

Update TCP Proxy configuration

Operation ID: tcpProxyUpdate

Requires service.tcp-proxy.manage permission. Supply backendIp, ports, allowedSourceCidrs, blockedSourceCidrs or countryPolicy. Supplied arrays replace complete existing arrays; omitted fields remain unchanged. TCP country modes: disabled/allow/block. IPv4 only. Paid port entitlement is enforced. Send the same Idempotency-Key and body on retries; never retry an uncertain outcome with a new key.

Scopes: tcp_proxy.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "backend_ip": {
      "type": "string"
    },
    "ports": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          {
            "type": "object",
            "properties": {
              "listen": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "backend": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "backend_ip": {
                "type": "string"
              },
              "proxy_protocol_v2": {
                "type": "boolean"
              },
              "max_connections_per_ip": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000000
              },
              "max_new_connections_per_second_per_ip": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000000
              },
              "connection_burst": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1000000
              },
              "max_packets_per_second_per_ip": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000000
              },
              "packet_burst": {
                "type": "integer",
                "minimum": 0,
                "maximum": 10000000
              }
            },
            "required": [
              "listen"
            ],
            "additionalProperties": false
          }
        ]
      },
      "minItems": 1,
      "maxItems": 512
    },
    "allowed_source_cidrs": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "maxItems": 256
    },
    "blocked_source_cidrs": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "maxItems": 256
    },
    "country_policy": {
      "type": "object",
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "disabled",
            "allow",
            "block"
          ]
        },
        "countries": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[A-Z]{2}$"
          },
          "maxItems": 256
        }
      },
      "required": [
        "mode",
        "countries"
      ],
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
```

Response 200: Updated configuration; does not purchase extra ports.

Illustrative response:

```json
{
  "ok": true,
  "tcpProxy": {
    "proxyIp": "192.0.2.20",
    "backendIp": "192.0.2.10",
    "ports": [
      {
        "listen": 443,
        "backend": 443
      }
    ],
    "includedPorts": 1,
    "additionalPorts": 0,
    "defaults": {},
    "allowedSourceCidrs": [],
    "blockedSourceCidrs": [],
    "countryPolicy": {
      "mode": "disabled",
      "countries": []
    },
    "status": "active"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/tcp-proxy/{serviceId}/stats

Read TCP Proxy analytics

Operation ID: tcpProxyStats

Window/bucket byte totals, observed connection events and blocked packet counts. Not instantaneous throughput or open sockets.

Scopes: tcp_proxy.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- query range (optional): Time window (default 24h).
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Time-window summary and bucketed analytics.

Illustrative response:

```json
{
  "ok": true,
  "proxyIp": "192.0.2.20",
  "range": "24h",
  "since": "2026-10-01T00:00:00.000Z",
  "until": "2026-10-02T00:00:00.000Z",
  "updatedAt": "2026-10-02T00:00:00.000Z",
  "lastEventAt": null,
  "retentionDays": 7,
  "summary": {
    "connections": 0,
    "bytesIn": 0,
    "bytesOut": 0,
    "limited": 0,
    "errors": 0,
    "averageDurationMs": 0,
    "blockedPackets": 0
  },
  "traffic": [],
  "blockedTraffic": [],
  "ports": [],
  "statuses": [],
  "blockedPorts": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/dns/waf/record/config

Read Website Protection settings

Operation ID: getServiceDnsWafConfig

Read-only HTTPS/origin and custom-loader flags. Unknown settings are null; no raw provider configuration, private keys or scripts.

Scopes: dns.read

- path serviceId (required): Your DNS zone name (example.com) or an owned service UUID. A name selects the owned zone directly; a UUID also requires domain in the query/body.
- query domain (optional): Owned DNS zone; required only with a UUID selector. Must match a domain-name selector when supplied.
- query name (optional): A record name, e.g. @ or www.; default @.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Safe settings.

Illustrative response:

```json
{
  "ok": true,
  "settings": {
    "ssl_schema": null,
    "force_ssl": null,
    "ssl": null,
    "custom_loader": null
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/records/config

Read Website Protection record settings

Operation ID: dnsRecordConfig

Read-only safe HTTPS/origin and custom-loader flags for an active, owned, proxied A record. No service UUID or domain registration is needed. Unknown flags are null; no raw provider configuration, scripts or keys are exposed.

Scopes: dns.read

- path name (required): Zone or domain name.
- query name (optional): Record name, e.g. @ or www.; default @.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Safe Website Protection settings.

Illustrative response:

```json
{
  "ok": true,
  "domain": "example.com",
  "name": "www",
  "settings": {
    "ssl_schema": "https",
    "force_ssl": "1",
    "ssl": "ecc",
    "custom_loader": "0"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/country-policy

Read website country policy

Operation ID: getDnsCountryPolicy

For an owned, active, proxied A record.

Scopes: dns.read

- path name (required): Zone or domain name.
- query record (optional): Record name; default @.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Saved policy.

Illustrative response:

```json
{
  "ok": true,
  "hostname": "example.com",
  "policy": {
    "mode": "off",
    "countries": [],
    "unknown": "allow",
    "whitelist_bypass": true
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/dns/zones/{name}/country-policy

Replace website country policy

Operation ID: dnsCountryPolicySet

Body: record and policy containing mode (off/allow/deny), countries (ISO alpha-2), optional unknown (allow/deny) and whitelist_bypass. Replacement can block visitors. Send an Idempotency-Key. Check saved and synchronized independently.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "record": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253
    },
    "policy": {
      "type": "object",
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "off",
            "allow",
            "deny"
          ]
        },
        "countries": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "maxItems": 249,
          "default": []
        },
        "unknown": {
          "type": "string",
          "enum": [
            "allow",
            "deny"
          ]
        },
        "whitelist_bypass": {
          "type": "boolean",
          "default": false
        }
      },
      "required": [
        "mode"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "record",
    "policy"
  ],
  "additionalProperties": false,
  "description": "Use valid ISO alpha-2 country codes. allow/deny requires at least one country; off disables the policy."
}
```

Response 200: Saved and synchronized policy.

Illustrative response:

```json
{
  "ok": true,
  "hostname": "example.com",
  "policy": {
    "mode": "off",
    "countries": [],
    "unknown": "allow",
    "whitelist_bypass": true
  },
  "saved": true,
  "synchronized": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/records/protection

Read DNS record protection

Operation ID: getDnsRecordProtection

Read saved mitigation state for an owned, active, proxied A record, including external origins. No hosting service ID required. Null protection/stateUnknown must not be interpreted as disabled.

Scopes: dns.read

- path name (required): Zone or domain name.
- query name (optional): A record name; default @.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Mitigation state, proxy state, origin IPs and synchronization status. No internal provider configuration.

Illustrative response:

```json
{
  "ok": true,
  "fqdn": "example.com",
  "type": "A",
  "proxied": true,
  "protection": true,
  "originValues": [
    "192.0.2.10"
  ],
  "ttl": 300,
  "stateUnknown": false,
  "pending": false,
  "lastSyncedAt": "2026-10-01T00:00:00.000Z"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dns/zones/{name}/records/protection

Change DNS record protection

Operation ID: dnsRecordProtectionSet

Toggle mitigation only; preserves proxy routing, origin addresses, DNS values and TTL. Enabling requires an active entitlement or eligible origin IPs. Send an Idempotency-Key. MCP requests require dashboard approval. A failed/unconfirmed response may have changed provider state; never assume it did not execute.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253
    },
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "name",
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Confirmed mitigation state and audit change ID, or stateUnknown on an unconfirmed update.

Illustrative response:

```json
{
  "ok": true,
  "fqdn": "example.com",
  "type": "A",
  "proxied": true,
  "protection": true,
  "stateUnknown": false,
  "changeId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/balance

Check wallet balance

Operation ID: billingBalance

Returns current account credit and currency so billing dashboards or automation can decide whether balance payment is available.

Scopes: billing.balance.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Current balance details.

Illustrative response:

```json
{
  "ok": true,
  "exists": true,
  "currency": "EUR",
  "credit": "100",
  "vcredit": "0"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/invoices

Browse invoices

Operation ID: listInvoices

Returns paginated customer invoices. Use this to build invoice history views, overdue checks, or reconciliation jobs.

Scopes: billing.invoices.read

- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated invoice list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "number": "INV-EXAMPLE-000001",
      "status": "unpaid",
      "total": "100.00",
      "paidTotal": "0.00",
      "currency": "EUR",
      "type": "purchase",
      "refundedTotal": "0.00",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "dueDate": "2026-11-01T00:00:00.000Z",
      "payDate": null,
      "order": null
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/invoices/unpaid-total

Check unpaid total

Operation ID: billingUnpaidTotal

Returns the current unpaid amount across customer invoices. This is useful for dashboard badges and automation that should pause when debt exists.

Scopes: billing.unpaid_total.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Current unpaid invoice summary.

Illustrative response:

```json
{
  "ok": true,
  "data": {
    "unpaidTotal": 0,
    "currency": "EUR"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/orders

Browse orders

Operation ID: billingOrders

Returns paginated customer orders and supports filtering by order or payment status for reporting and customer portals.

Scopes: billing.orders.read

- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- query status (optional): Optional order status filter.
- query paymentStatus (optional): Optional payment status filter.
- query external_id (optional): Exact customer reference on an owned order item; applied before pagination.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated order list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "status": "pending",
      "currency": "EUR",
      "total": "100.00",
      "paymentStatus": "unpaid",
      "paymentMethod": null,
      "createdAt": "2026-10-01T00:00:00.000Z",
      "invoice": {
        "id": "00000000-0000-4000-8000-000000000001",
        "number": "INV-EXAMPLE-000001",
        "status": "unpaid",
        "total": "100.00",
        "paidTotal": "0.00",
        "currency": "EUR"
      }
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/services

Browse billable services

Operation ID: billingServices

Returns the billing-facing service list. Use this endpoint when the main goal is commercial visibility rather than grouped customer dashboards.

Scopes: billing.services.read

- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated billing service list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "status": "active",
      "displayName": "Example VPS",
      "hostname": "server.example.com",
      "type": "vps",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "dueDate": "2026-11-01T00:00:00.000Z",
      "billingUnit": "MONTH",
      "billingCount": 1,
      "sku": "4G",
      "ipv4": "192.0.2.10",
      "ipv6": null,
      "meta": {
        "serviceType": "vps"
      }
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/products

Browse product catalog

Operation ID: billingProducts

Returns product catalog entries that can be used for storefront search, quoting, and pre-checkout selection flows.

Scopes: billing.products.read

- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- query category (optional): Optional category filter.
- query q (optional): Optional free-text search query.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated product list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example VPS",
      "category": "vps",
      "variants": [
        {
          "id": "00000000-0000-4000-8000-000000000002",
          "productId": "00000000-0000-4000-8000-000000000001",
          "sku": "4G",
          "serviceType": "vps",
          "attributes": {
            "compute": {
              "CPU": 2,
              "RAM": 4
            },
            "storage": {
              "DISK_SPACE": 40
            }
          },
          "addons": [],
          "billingOptions": [
            {
              "unit": "MONTH",
              "count": 1,
              "currency": "EUR",
              "price": "100.00",
              "setupFee": "0.00"
            }
          ]
        }
      ]
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/products/{productId}/variants/{variantId}/order-options

Discover product order options

Operation ID: billingProductOrderOptions

Read-only complete configuration discovery for a public, active product and variant. Returns required and optional fields, conditional requirements, priced add-ons, billing options and eligible OS/regions. VPS uses userConfig.location and userConfig.os.code. Managed dedicated uses userConfig.dedicated.configurationCode, regionCode, osProfileId and hostname; optional sshKeyId must belong to your account. Includes physical/default connectivity, purchasable bandwidth add-ons, IPv4 limits and reservation TTL. supported=false means dashboard-only. No capacity is reserved; compatible catalog stock is not a reservation. Domain pricingMode=domain_quote requires a domain-specific quote. No infrastructure secrets are returned.

Scopes: billing.products.read

- path productId (required): Product UUID from the catalog.
- path variantId (required): Variant UUID belonging to this product.
- query region (optional): Region code from GET /v1/regions, for example nl or pt. Case-insensitive.
- query currency (optional): Pricing currency, default EUR.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Product-specific location and OS options. A catalog outage returns an error, never fallback options.

Illustrative response:

```json
{
  "ok": true,
  "productId": "00000000-0000-4000-8000-000000000001",
  "variantId": "00000000-0000-4000-8000-000000000002",
  "supported": true,
  "capacityVerified": false,
  "requiredFields": [
    {
      "field": "hostname",
      "label": "Hostname",
      "description": "Server hostname.",
      "format": "hostname"
    },
    {
      "field": "location",
      "label": "Location",
      "description": "Location code."
    },
    {
      "field": "os.code",
      "label": "Operating system",
      "description": "Operating system code."
    }
  ],
  "locations": [
    {
      "code": "NL",
      "name": "Netherlands",
      "operatingSystems": [
        {
          "code": "debian-13",
          "name": "Debian",
          "family": "debian",
          "version": "13",
          "arch": "amd64",
          "isDefault": true
        }
      ]
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/billing/transactions

Browse transactions

Operation ID: billingTransactions

Returns paginated financial transaction records for account history and payment auditing.

Scopes: billing.transactions.read

- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated transaction list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "status": "completed",
      "type": "payment",
      "currency": "EUR",
      "amountIn": "100.00",
      "amountOut": "0.00",
      "fee": "0.00",
      "gateway": null,
      "invoiceId": "00000000-0000-4000-8000-000000000002",
      "meta": null
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/billing/orders/preview

Preview order total

Operation ID: billingOrderPreview

Submit the same complete cart as order creation, including userConfig and public add-on key/qty selections. Uses checkout validation and pricing, equivalent billing periods, account currency and tax. Requires complete billing details. Returns reserved=false: no reservation, order, invoice or payment is created. A quote does not guarantee later stock or prices. The older single-item preview body is accepted and normalized to the same cart.

Scopes: billing.products.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "idempotency_key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "currency": {
          "type": "string",
          "enum": [
            "EUR",
            "USD"
          ]
        },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "product_id": {
                "type": "string",
                "format": "uuid"
              },
              "variant_id": {
                "type": "string",
                "format": "uuid"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              },
              "user_config": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  },
                  {
                    "type": "array",
                    "items": {
                      "description": "JSON value; product-specific fields are discovered through order-options."
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "JSON value; product-specific fields are discovered through order-options."
                    }
                  }
                ]
              },
              "attributes": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  },
                  {
                    "type": "array",
                    "items": {
                      "description": "JSON value; product-specific fields are discovered through order-options."
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "JSON value; product-specific fields are discovered through order-options."
                    }
                  }
                ]
              },
              "billing": {
                "type": "object",
                "properties": {
                  "unit": {
                    "type": "string",
                    "enum": [
                      "ONCE",
                      "HOUR",
                      "DAY",
                      "WEEK",
                      "MONTH",
                      "QUARTAL",
                      "SEMIANNUAL",
                      "YEAR"
                    ]
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 120
                  }
                },
                "required": [
                  "unit",
                  "count"
                ],
                "additionalProperties": false
              },
              "addons": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120,
                      "pattern": "^[A-Za-z0-9_.:-]+$"
                    },
                    "qty": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    }
                  },
                  "required": [
                    "key",
                    "qty"
                  ],
                  "additionalProperties": false
                },
                "maxItems": 50
              }
            },
            "required": [
              "product_id",
              "variant_id",
              "qty",
              "billing"
            ],
            "additionalProperties": false
          },
          "minItems": 1,
          "maxItems": 50
        }
      },
      "required": [
        "currency",
        "items"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "product_id": {
          "type": "string",
          "format": "uuid"
        },
        "variant_id": {
          "type": "string",
          "format": "uuid"
        },
        "currency": {
          "type": "string",
          "maxLength": 3,
          "minLength": 3
        },
        "unit": {
          "type": "string",
          "minLength": 1,
          "maxLength": 20
        },
        "count": {
          "type": "integer",
          "minimum": 1,
          "maximum": 120
        },
        "quantity": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 1
        },
        "user_config": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            }
          ]
        },
        "addons": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "required": [
              "key",
              "qty"
            ],
            "additionalProperties": false
          },
          "maxItems": 50
        }
      },
      "required": [
        "product_id",
        "variant_id",
        "currency",
        "unit",
        "count"
      ],
      "additionalProperties": false
    }
  ],
  "example": {
    "currency": "EUR",
    "items": [
      {
        "product_id": "00000000-0000-4000-8000-000000000001",
        "variant_id": "00000000-0000-4000-8000-000000000002",
        "qty": 1,
        "billing": {
          "unit": "MONTH",
          "count": 1
        },
        "user_config": {
          "hostname": "example",
          "location": "NL",
          "os": {
            "code": "debian-13"
          }
        },
        "addons": []
      }
    ]
  },
  "description": "Illustrative VPS cart. Replace IDs, required user_config fields, billing period and add-ons with the selected public plan’s order-options. The server validates ownership, eligibility and prices; caller-supplied hardware/price cannot change the plan. Quotes require complete billing details and use account currency."
}
```

Response 200: Order preview with calculated totals.

Illustrative response:

```json
{
  "ok": true,
  "currency": "EUR",
  "subtotal": "100.00",
  "tax": "0.00",
  "total": "100.00",
  "reserved": false,
  "breakdown": {
    "base_price": "100.00",
    "addons": "0.00",
    "setup_fee": "0.00",
    "tax": "0.00",
    "total": "100.00"
  },
  "items": [
    {
      "productId": "00000000-0000-4000-8000-000000000001",
      "variantId": "00000000-0000-4000-8000-000000000002",
      "productName": "Example VPS",
      "sku": "4G",
      "quantity": 1,
      "billing": {
        "unit": "MONTH",
        "count": 1
      },
      "unitPrice": "100",
      "setupFee": "0",
      "subtotal": "100",
      "addons": []
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/deploy/{region}/{productCode}/{variantCode}/quote

Quote a configured product by code

Operation ID: productVariantQuote

Accepts exactly the same simple or legacy body as deployment. Uses authoritative account currency, configuration, tax and add-on prices. Returns a price breakdown and reserved=false; creates no order, invoice, reservation or payment. No Idempotency-Key required. The quote object adds an opaque diagnostic id, guaranteed=false, currency, final total, breakdown, pricing_revision and recommended_max_total. Pass recommended_max_total as max_total to deployment. The revision fingerprints this priced cart; it is not a price lock, reservation or redeemable quote. A quote is optional and is not a stock or price guarantee.

Scopes: billing.products.read

- path region (required): Eligible region, for example nl or pt. A single region is required.
- path productCode (required): Product family.
- path variantCode (required): Exact case-sensitive public SKU, for example 2G or PTV4-1. Never an internal inventory ID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "billing": {
          "type": "object",
          "properties": {
            "unit": {
              "type": "string",
              "enum": [
                "ONCE",
                "HOUR",
                "DAY",
                "WEEK",
                "MONTH",
                "QUARTAL",
                "SEMIANNUAL",
                "YEAR"
              ]
            },
            "count": {
              "type": "integer",
              "minimum": 1,
              "maximum": 120
            }
          },
          "required": [
            "unit",
            "count"
          ],
          "additionalProperties": false
        },
        "userConfig": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            }
          ]
        },
        "addons": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "required": [
              "key",
              "qty"
            ],
            "additionalProperties": false
          },
          "maxItems": 50
        },
        "maxTotal": {
          "type": "string",
          "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
        }
      },
      "required": [
        "billing"
      ],
      "additionalProperties": false,
      "deprecated": true,
      "description": "Deprecated compatibility deployment shape. Prefer the canonical snake_case payload; no sunset date has been assigned."
    },
    {
      "type": "object",
      "properties": {
        "billing_cycle": {
          "type": "string",
          "enum": [
            "monthly",
            "quarterly",
            "semi_annually",
            "annually",
            "biennially",
            "triennially",
            "hourly",
            "daily",
            "weekly",
            "one_time"
          ],
          "default": "monthly"
        },
        "hostname": {
          "type": "string",
          "maxLength": 253,
          "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
        },
        "os": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            },
            {
              "type": "integer",
              "exclusiveMinimum": 0
            }
          ]
        },
        "ssh_key_id": {
          "type": "string",
          "format": "uuid"
        },
        "connectivity_gbps": {
          "type": "number",
          "exclusiveMinimum": 0,
          "maximum": 100
        },
        "additional_ips": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        },
        "backend_ip": {
          "type": "string"
        },
        "ports": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "listen": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "backend": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              }
            },
            "required": [
              "listen",
              "backend"
            ],
            "additionalProperties": false
          },
          "minItems": 1,
          "maxItems": 100
        },
        "domain": {
          "type": "string",
          "minLength": 1,
          "maxLength": 253
        },
        "license_ip": {
          "type": "string"
        },
        "parent_service_id": {
          "type": "string",
          "format": "uuid"
        },
        "addons": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "maxLength": 120,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "required": [
              "key",
              "qty"
            ],
            "additionalProperties": false
          },
          "maxItems": 50
        },
        "max_total": {
          "type": "string",
          "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
        },
        "external_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "labels": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "maxLength": 120
          }
        }
      },
      "additionalProperties": false
    }
  ],
  "example": {
    "billing_cycle": "monthly",
    "hostname": "test",
    "os": "debian-13",
    "max_total": "25.00"
  },
  "description": "Simple fields: billing_cycle, hostname, os, owned ssh_key_id, dedicated connectivity_gbps/additional_ips, TCP backend_ip/ports, external_id/labels, max_total. Use discovered choices; dedicated OS accepts its exact code or numeric ID. Path fixes region. Legacy billing/userConfig/addons/maxTotal remains accepted; never mix both shapes. Ceilings include tax/setup/add-ons in account currency."
}
```

Response 200: Validated price, breakdown and selected line items.

Illustrative response:

```json
{
  "ok": true,
  "currency": "EUR",
  "subtotal": "12.00",
  "tax": "0.00",
  "total": "12.00",
  "reserved": false,
  "breakdown": {
    "base_price": "12.00",
    "addons": "0.00",
    "setup_fee": "0.00",
    "tax": "0.00",
    "total": "12.00"
  },
  "items": [
    {
      "productId": "00000000-0000-4000-8000-000000000001",
      "variantId": "00000000-0000-4000-8000-000000000002",
      "productName": "Example VPS",
      "sku": "2G",
      "quantity": 1,
      "billing": {
        "unit": "MONTH",
        "count": 1
      },
      "unitPrice": "12",
      "setupFee": "0",
      "subtotal": "12",
      "addons": []
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/operations

Recover an operation by idempotency key

Operation ID: recoverOperation

Lookup is confined to the authenticated account and permitted operation kinds. Keys are scoped to the original credential, HTTP method and exact path. Supply method/path together and optionally credential_id to disambiguate a key reused across endpoints or credentials (409 operation_lookup_ambiguous). Only new tracked deployment/VPS/dedicated writes with a retained identity are recoverable. 404 operation_not_found does not prove the write never executed. Identities remain after terminal receipt retention (90 days by default); 410 operation_expired means the original receipt is no longer available. Pending/unknown receipts are retained for reconciliation. Never generate a new key to repeat an uncertain write.

Scopes: billing.services.read OR vps.read OR dedicated.read

- query idempotency_key (required): Original Idempotency-Key; 8–128 letters, digits, dot, underscore, colon or dash.
- query method (optional): Original HTTP method; supply with path.
- query path (optional): Exact original /v1/ path without query string; supply with method.
- query credential_id (optional): Original credential UUID, when needed for disambiguation.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Original operation receipt; owner and read scopes are checked.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
    "kind": "vps",
    "action": "reboot",
    "status": "succeeded",
    "done": true,
    "progress": 100,
    "stage": null,
    "created_at": "2026-10-01T00:00:00.000Z",
    "updated_at": "2026-10-01T00:00:00.000Z",
    "service_ids": [
      "00000000-0000-4000-8000-000000000001"
    ],
    "error": null,
    "result": {
      "service_id": "00000000-0000-4000-8000-000000000001"
    }
  },
  "links": {
    "operation": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
    "service": "/v1/services/00000000-0000-4000-8000-000000000001"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/operations/{operationId}

Read operation status

Operation ID: getOperation

Poll the opaque operation_id returned by supported wallet deployments and VPS/dedicated actions. Owner checks and the underlying read scope are enforced on every read. When durable_operations is enabled, new handles are stored independently of encryption keys and the first observed terminal outcome is immutable. Terminal receipts retain 90 days by default; pending/unknown receipts remain for reconciliation. Legacy encrypted handles remain readable but can be invalidated by encryption-key rotation. Deployment readiness respects historical activation; a service error alone is not proof of permanent provisioning failure. The canonical operation has status, done, progress, stage and optional typed result. Result is populated only on succeeded; failed/cancelled are terminal, unknown is nonterminal and is not success. Tracked writes accept x-bf-response-format: operation; the default response preserves legacy fields. DNSSEC and other untracked workflows retain their documented polling contracts. Client wait timeout never repeats/cancels a purchase.

Scopes: billing.services.read OR vps.read OR dedicated.read

- path operationId (required): Opaque op_ token from the accepted response.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Unified status, safe progress and service IDs.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
    "kind": "vps",
    "action": "reboot",
    "status": "succeeded",
    "done": true,
    "progress": 100,
    "stage": null,
    "created_at": "2026-10-01T00:00:00.000Z",
    "updated_at": "2026-10-01T00:00:00.000Z",
    "service_ids": [
      "00000000-0000-4000-8000-000000000001"
    ],
    "error": null
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/services/{serviceId}/metadata

Replace customer integration metadata

Operation ID: serviceMetadataUpdate

Replaces only this owned service’s external_id and labels; omitted fields are cleared. Does not change hardware, price, credentials or lifecycle. Up to 20 bounded labels. Do not store secrets in labels. Searches use external_id or label=key=value.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "external_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "labels": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "maxLength": 120
      }
    }
  },
  "additionalProperties": false
}
```

Response 200: Saved customer reference and labels.

Illustrative response:

```json
{
  "ok": true,
  "service_id": "00000000-0000-4000-8000-000000000001",
  "external_id": "example-vps-1",
  "labels": {
    "environment": "test"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/webhooks

List webhook endpoints

Operation ID: listWebhooks

Owned endpoints without signing secrets. Maximum five per account; feature must be enabled for this environment.

Scopes: webhooks.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Owned webhook endpoints.

Illustrative response:

```json
{
  "ok": true,
  "items": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/webhooks

Register a signed webhook

Operation ID: webhookCreate

HTTPS port 443, public IPv4 destinations only. Verified TLS, pinned DNS, no redirects. Events: invoice.paid, service.ready, service.suspended, service.terminated and operation.failed (Billing provisioning-job failures, not all power/reinstall failures). No historical backfill. Sensitive signing_secret is returned on creation or identical retry while the endpoint exists: never log it or send it to AI. At-least-once delivery: verify raw-body HMAC and timestamp, deduplicate event IDs, return 2xx promptly. Off by default until migration and worker deployment.

Scopes: webhooks.write

- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2048
    },
    "events": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "invoice.paid",
          "service.ready",
          "service.suspended",
          "service.terminated",
          "operation.failed",
          "operation.succeeded",
          "operation.cancelled",
          "invoice.created",
          "invoice.overdue",
          "service.provisioning",
          "service.expiring",
          "operation.started",
          "backup.started",
          "backup.completed",
          "backup.failed",
          "snapshot.created",
          "snapshot.failed",
          "dns.changed",
          "service.power_changed",
          "domain.verification_required",
          "domain.renewal_pending",
          "domain.renewed",
          "domain.transfer_updated"
        ]
      },
      "minItems": 1,
      "maxItems": 23
    }
  },
  "required": [
    "url",
    "events"
  ],
  "additionalProperties": false
}
```

Response 201: New endpoint and private signing secret.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "url": "https://example.com/hooks",
    "events": [
      "invoice.paid"
    ],
    "enabled": true,
    "createdAt": "2026-10-01T00:00:00.000Z"
  },
  "signing_secret": "whsec_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/version

Read API contract revision

Operation ID: apiVersion

Authenticated discovery. release is a configured public release label or null, not an internal image or provider identifier. A contract revision is not proof of product availability.

Scopes: 

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: API version and contract revision.

Illustrative response:

```json
{
  "ok": true,
  "api_version": "1",
  "contract_revision": "2026-10-07.1",
  "release": null,
  "deployment": null,
  "released_at": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/capabilities

Discover capabilities and effective permissions

Operation ID: apiCapabilities

Distinguishes implemented support, environment enabled state and effective key permissions. enabled=null and availability=unconfirmed mean the backend could not confirm a gate, not that it is disabled. partial=true indicates incomplete discovery. Does not guarantee region inventory, provider health or order approval. Networking and generic metrics are reported not_implemented until supported.

Scopes: 

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Capability gates and key permissions.

Illustrative response:

```json
{
  "ok": true,
  "contract_revision": "2026-10-07.1",
  "dependency_revision": null,
  "partial": true,
  "features": {
    "webhooks": {
      "implemented": true,
      "enabled": null,
      "permitted": true,
      "availability": "unconfirmed"
    },
    "private_networks": {
      "implemented": false,
      "enabled": false,
      "permitted": false,
      "availability": "not_implemented"
    }
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/audit/events

Read account audit history

Operation ID: auditEvents

Default view=requests preserves request history. view=activity merges durable API/MCP actions and Billing business events with actor/action/resource/status filters. Activity partial=true means a history source was unavailable; available_sources lists confirmed sources. Reuse opaque cursors with the same filters; ownership is always enforced. Acceptance is not provider completion. No passwords, tokens, private keys or webhook secrets. Activity source_ip follows the existing privacy masking policy.

Scopes: audit.read

- query limit (optional): Maximum items, default 50 (1–100).
- query view (optional): History view.
- query cursor (optional): Reuse next_cursor exactly with the same owner and filters.
- query method (optional): HTTP method; request view only.
- query actor_type (optional): Verified actor category.
- query actor_id (optional): Exact verified actor UUID.
- query action (optional): Semantic action, for example vps.reinstall.
- query resource_type (optional): Resource category.
- query resource_id (optional): Exact resource identity.
- query status (optional): Action phase.
- query request_id (optional): Exact request UUID.
- query from (optional): Inclusive ISO 8601 timestamp.
- query to (optional): Inclusive ISO 8601 timestamp.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Filtered history and next_cursor.

Illustrative response:

```json
{
  "ok": true,
  "next_cursor": null,
  "items": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/webhooks/{id}/test

Queue a signed webhook test

Operation ID: webhookTest

Queues a synthetic webhook.test event through the normal delivery worker. HTTP 202 means queued, not delivered. Read delivery history to check the result. Enabled owned endpoints only; one new test per endpoint per minute. Idempotency-Key is required; identical retries return the same delivery. Empty request body. Requires webhook_management capability.

Scopes: webhooks.write

- path id (required): Owned endpoint UUID.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (optional)

```json
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
```

Response 202: Test event and delivery IDs.

Illustrative response:

```json
{
  "ok": true,
  "endpoint_id": "00000000-0000-4000-8000-000000000001",
  "delivery_id": "00000000-0000-4000-8000-000000000002",
  "event_id": "00000000-0000-4000-8000-000000000002",
  "status": "pending"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/webhooks/{id}/rotate-secret

Rotate webhook signing secret

Operation ID: webhookRotateSecret

Replaces the signing secret for an owned endpoint immediately. An already in-flight delivery may still use the old secret; accept both briefly at your receiver. Idempotency-Key is required. Identical retries return the same secret for 24 hours unless a subsequent rotation superseded it; superseded or expired keys never rotate again. Sensitive signing_secret: never log or send it to AI. Empty request body. Requires webhook_management capability.

Scopes: webhooks.write

- path id (required): Owned endpoint UUID.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (optional)

```json
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
```

Response 200: New private signing secret.

Illustrative response:

```json
{
  "ok": true,
  "endpoint_id": "00000000-0000-4000-8000-000000000001",
  "signing_secret": "whsec_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "rotated_at": "2026-10-01T00:00:00.000Z"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/webhooks/{id}

Enable or pause webhook deliveries

Operation ID: webhookUpdate

Pauses new and queued deliveries; an in-flight attempt may finish. Re-enable resumes pending deliveries.

Scopes: webhooks.write

- path id (required): Owned endpoint UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Updated endpoint.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "url": "https://example.com/hooks",
    "events": [
      "invoice.paid"
    ],
    "enabled": false,
    "createdAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/webhooks/{id}

Delete a webhook endpoint

Operation ID: webhookDelete

Deletes the endpoint and its delivery history. An in-flight attempt may finish. Use a new retry key for an intentional replacement.

Scopes: webhooks.write

- path id (required): Owned endpoint UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Endpoint deleted.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/webhooks/{id}/deliveries

Read webhook delivery history

Operation ID: webhookDeliveries

Owned delivery results, no response bodies or signing secrets. Delivered records retain 30 days, failed records 90 days. Paused pending events remain until deletion. Up to 12 attempts with exponential backoff capped at six hours.

Scopes: webhooks.read

- path id (required): Owned endpoint UUID.
- query limit (optional): Maximum items, default 50 (1–100).
- query offset (optional): Start offset, default 0. Use next_offset from the response; null means finished. This contract has no page or pageSize fields.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Delivery attempts and next_offset.

Illustrative response:

```json
{
  "ok": true,
  "items": [],
  "next_offset": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/webhooks/{id}/deliveries/{deliveryId}/retry

Retry an exhausted delivery

Operation ID: webhookRetry

Only failed deliveries on your enabled endpoint can be retried. Pending/leased/successful events cannot be replayed; repeating this request returns delivery_not_retryable. Event ID is preserved.

Scopes: webhooks.write

- path id (required): Owned endpoint UUID.
- path deliveryId (required): Failed delivery UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (optional)

```json
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
```

Response 200: Delivery requeued.

Illustrative response:

```json
{
  "ok": true,
  "delivery_id": "00000000-0000-4000-8000-000000000002",
  "status": "pending"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/deploy/{region}/{productCode}/{variantCode}

Deploy product variant from wallet

Operation ID: productVariantDeploy

One call validates a public VPS, managed dedicated, TCP proxy, Website Protection or software-license variant, creates its order/invoice, charges the full final order amount to the account balance and queues normal provisioning. Insufficient funds returns HTTP 402 insufficient_credit with no committed order/payment. Uses account billing currency and authoritative prices including tax, setup and add-ons. max_total is an optional decimal-string spending ceiling in that currency. Requires both scopes. Idempotency-Key is required; reuse identical arguments after interruption. Never charges a card or tops up the wallet. Acceptance is not a ready server: inspect returned serviceIds. Dedicated admin approvals, inventory and license rollout gates still apply. Domains/free products are not supported by this convenience endpoint; legacy unpaid checkout/payment remain unchanged.

Scopes: billing.order.create + billing.invoice.pay

- path region (required): Region code, for example nl or pt.
- path productCode (required): Catalog product_code: vps, dedicated, tcp-proxy, waf or license.
- path variantCode (required): Exact public catalog variant_code/SKU, for example 2G or PTV4-1.
- header Idempotency-Key (required): Stable retry key, 8–128 characters. Never replace it after an uncertain response.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "billing": {
          "type": "object",
          "properties": {
            "unit": {
              "type": "string",
              "enum": [
                "ONCE",
                "HOUR",
                "DAY",
                "WEEK",
                "MONTH",
                "QUARTAL",
                "SEMIANNUAL",
                "YEAR"
              ]
            },
            "count": {
              "type": "integer",
              "minimum": 1,
              "maximum": 120
            }
          },
          "required": [
            "unit",
            "count"
          ],
          "additionalProperties": false
        },
        "userConfig": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "JSON value; product-specific fields are discovered through order-options."
              }
            }
          ]
        },
        "addons": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "required": [
              "key",
              "qty"
            ],
            "additionalProperties": false
          },
          "maxItems": 50
        },
        "maxTotal": {
          "type": "string",
          "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
        }
      },
      "required": [
        "billing"
      ],
      "additionalProperties": false,
      "deprecated": true,
      "description": "Deprecated compatibility deployment shape. Prefer the canonical snake_case payload; no sunset date has been assigned."
    },
    {
      "type": "object",
      "properties": {
        "billing_cycle": {
          "type": "string",
          "enum": [
            "monthly",
            "quarterly",
            "semi_annually",
            "annually",
            "biennially",
            "triennially",
            "hourly",
            "daily",
            "weekly",
            "one_time"
          ],
          "default": "monthly"
        },
        "hostname": {
          "type": "string",
          "maxLength": 253,
          "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
        },
        "os": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            },
            {
              "type": "integer",
              "exclusiveMinimum": 0
            }
          ]
        },
        "ssh_key_id": {
          "type": "string",
          "format": "uuid"
        },
        "connectivity_gbps": {
          "type": "number",
          "exclusiveMinimum": 0,
          "maximum": 100
        },
        "additional_ips": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        },
        "backend_ip": {
          "type": "string"
        },
        "ports": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "listen": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "backend": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              }
            },
            "required": [
              "listen",
              "backend"
            ],
            "additionalProperties": false
          },
          "minItems": 1,
          "maxItems": 100
        },
        "domain": {
          "type": "string",
          "minLength": 1,
          "maxLength": 253
        },
        "license_ip": {
          "type": "string"
        },
        "parent_service_id": {
          "type": "string",
          "format": "uuid"
        },
        "addons": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "maxLength": 120,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              },
              "qty": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "required": [
              "key",
              "qty"
            ],
            "additionalProperties": false
          },
          "maxItems": 50
        },
        "max_total": {
          "type": "string",
          "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
        },
        "external_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "labels": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "maxLength": 120
          }
        }
      },
      "additionalProperties": false
    }
  ],
  "example": {
    "billing_cycle": "monthly",
    "hostname": "test",
    "os": "debian-13",
    "max_total": "25.00"
  },
  "description": "Simple fields: billing_cycle, hostname, os, owned ssh_key_id, dedicated connectivity_gbps/additional_ips, TCP backend_ip/ports, external_id/labels, max_total. Use discovered choices; dedicated OS accepts its exact code or numeric ID. Path fixes region. Legacy billing/userConfig/addons/maxTotal remains accepted; never mix both shapes. Ceilings include tax/setup/add-ons in account currency."
}
```

Response 200: Fully paid order with asynchronous provisioning queued.

Illustrative response:

```json
{
  "ok": true,
  "orderId": "00000000-0000-4000-8000-000000000001",
  "invoiceId": "00000000-0000-4000-8000-000000000002",
  "invoiceNumber": "INV-EXAMPLE-000001",
  "total": "100.00",
  "currency": "EUR",
  "status": "paid",
  "paidNow": "100.00",
  "fullyPaid": true,
  "serviceIds": [
    "00000000-0000-4000-8000-000000000003"
  ],
  "provisioning": "queued",
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/billing/orders/draft

Start draft order

Operation ID: billingOrderDraft

Creates a draft order from one or more items so you can continue into invoice creation and payment.

Scopes: billing.order.create

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "idempotency_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "currency": {
      "type": "string",
      "enum": [
        "EUR",
        "USD"
      ]
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid"
          },
          "variant_id": {
            "type": "string",
            "format": "uuid"
          },
          "qty": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "user_config": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "null"
              },
              {
                "type": "array",
                "items": {
                  "description": "JSON value; product-specific fields are discovered through order-options."
                }
              },
              {
                "type": "object",
                "additionalProperties": {
                  "description": "JSON value; product-specific fields are discovered through order-options."
                }
              }
            ]
          },
          "attributes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "null"
              },
              {
                "type": "array",
                "items": {
                  "description": "JSON value; product-specific fields are discovered through order-options."
                }
              },
              {
                "type": "object",
                "additionalProperties": {
                  "description": "JSON value; product-specific fields are discovered through order-options."
                }
              }
            ]
          },
          "billing": {
            "type": "object",
            "properties": {
              "unit": {
                "type": "string",
                "enum": [
                  "ONCE",
                  "HOUR",
                  "DAY",
                  "WEEK",
                  "MONTH",
                  "QUARTAL",
                  "SEMIANNUAL",
                  "YEAR"
                ]
              },
              "count": {
                "type": "integer",
                "minimum": 1,
                "maximum": 120
              }
            },
            "required": [
              "unit",
              "count"
            ],
            "additionalProperties": false
          },
          "addons": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 120,
                  "pattern": "^[A-Za-z0-9_.:-]+$"
                },
                "qty": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 100
                }
              },
              "required": [
                "key",
                "qty"
              ],
              "additionalProperties": false
            },
            "maxItems": 50
          }
        },
        "required": [
          "product_id",
          "variant_id",
          "qty",
          "billing"
        ],
        "additionalProperties": false
      },
      "minItems": 1,
      "maxItems": 50
    }
  },
  "required": [
    "currency",
    "items"
  ],
  "additionalProperties": false,
  "example": {
    "currency": "EUR",
    "items": [
      {
        "product_id": "00000000-0000-4000-8000-000000000001",
        "variant_id": "00000000-0000-4000-8000-000000000002",
        "qty": 1,
        "billing": {
          "unit": "MONTH",
          "count": 1
        },
        "user_config": {
          "hostname": "example",
          "location": "NL",
          "os": {
            "code": "debian-13"
          }
        },
        "addons": []
      }
    ]
  },
  "description": "Illustrative VPS cart. Replace IDs, required user_config fields, billing period and add-ons with the selected public plan’s order-options. The server validates ownership, eligibility and prices; caller-supplied hardware/price cannot change the plan. Quotes require complete billing details and use account currency."
}
```

Response 200: Created draft order and related billing payload.

Illustrative response:

```json
{
  "ok": true,
  "orderId": "00000000-0000-4000-8000-000000000001",
  "invoiceId": "00000000-0000-4000-8000-000000000002",
  "invoiceNumber": "INV-EXAMPLE-000001",
  "total": "100.00",
  "currency": "EUR",
  "status": "unpaid"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/billing/invoices/{id}/pay

Pay invoice from wallet

Operation ID: payInvoice

Attempts to settle the target invoice using account balance. This is the customer API path for balance-driven payment automation.

Scopes: billing.invoice.pay

- path id (required): Invoice UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Invoice payment result.

Illustrative response:

```json
{
  "ok": true,
  "paidNow": "100",
  "partial": false,
  "fullyPaid": true,
  "invoiceId": "00000000-0000-4000-8000-000000000001",
  "orderId": null,
  "status": "paid",
  "meta": {
    "createdServices": 0,
    "renewedServices": 1,
    "createdServiceIds": [],
    "provisioning": null
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services

Browse services

Operation ID: listServices

Returns customer service summaries with hostname and recorded region code. Region uses provider/migration metadata, falling back to original order location; use VPS status for the currently assigned region. Null means unavailable. Does not disclose internal node or cluster identifiers. Ownership, status, type, search, external_id and label filters are applied server-side before pagination and counts. The default is active plus suspended; historical states require an explicit status filter. group_by=type groups only the current page, not the complete inventory.

Scopes: billing.services.read

- query status (optional): Service lifecycle status; defaults to active and suspended when no status filter is supplied. Power state is separate.
- query type (optional): High-level normalized service family: vps, dedicated, webhosting, storage, dns, domain or other (comma-separated). Distinct from catalog product_code: tcp-proxy and license map to other; waf maps to dns. Applied before pagination; use discovered product_code for purchasing.
- query statuses (optional): Comma-separated lifecycle statuses, for example active,suspended. Use this or status, not both. Filtering and counts use service status, never runtime power state.
- query types (optional): Comma-separated service types. Alias for type; do not supply both.
- query search (optional): Search hostname, customer IPv4/IPv6, display name, product name, SKU or full service UUID; maximum 200 characters. Applied before pagination.
- query external_id (optional): Exact customer integration reference; applied before pagination.
- query label (optional): Exact metadata label match: key=value. Applied before pagination.
- query include_counts (optional): Request counts only for selected statuses, with the same ownership, type and search filters. Omitted by default.
- query group_by (optional): Group the current page by type, retaining items and pagination.
- query page (optional): Page number for pagination.
- query limit (optional): Maximum items to return (default 50; range 1–100). Canonical page-size parameter. Deprecated page_size and pageSize aliases remain accepted; supplied size values must match.
- query page_size (optional, deprecated): Deprecated compatibility alias for limit; values must match when supplied together.
- query pageSize (optional, deprecated): Deprecated compatibility alias for limit; range 1–100, default 50.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Paginated service list.

Illustrative response:

```json
{
  "ok": true,
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "pages": 1,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "status": "active",
      "displayName": "Example VPS",
      "hostname": "server.example.com",
      "type": "vps",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "dueDate": "2026-11-01T00:00:00.000Z",
      "billingUnit": "MONTH",
      "billingCount": 1,
      "sku": "4G",
      "ipv4": "192.0.2.10",
      "ipv6": null,
      "meta": {
        "serviceType": "vps"
      }
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/grouped

Browse services by type

Operation ID: listServicesGrouped

Returns the complete filtered customer-safe inventory grouped by type, without pagination. Intended for dashboard inventory. This is a legacy compatibility endpoint. Its default is active only, retained for backward compatibility; automation and MCP clients should pass status explicitly and prefer /v1/services?statuses=active,suspended&group_by=type for relevant lifecycle states. status=suspended or status=all explicitly includes other states. This differs from GET /v1/services?group_by=type, which groups only its current paginated result set. This endpoint supports status and type filters; use /v1/services for search and integration-metadata filters.

Scopes: billing.services.read

- query status (optional): Legacy default active; pass this explicitly. Filter by service status. Use all to disable status filtering.
- query type (optional): Optional comma-separated list of service types to keep in the grouped response.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Grouped service list.

Illustrative response:

```json
{
  "ok": true,
  "status": "active",
  "type": null,
  "services": {
    "dns": [],
    "vps": [],
    "dedicated": [],
    "webhosting": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}

Open service detail

Operation ID: getService

Returns the customer-facing detail view for one service.

Scopes: billing.services.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Detailed service record.

Illustrative response:

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000001",
    "status": "active",
    "displayName": "Example VPS",
    "hostname": "server.example.com",
    "type": "vps",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "dueDate": "2026-11-01T00:00:00.000Z",
    "billingUnit": "MONTH",
    "billingCount": 1,
    "sku": "4G",
    "ipv4": "192.0.2.10",
    "ipv6": null,
    "meta": {
      "serviceType": "vps"
    }
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/services/{serviceId}/autopay

Toggle wallet autopay

Operation ID: serviceAutopay

Enables or disables autopay for a supported service so future renewal invoices can be handled automatically when policy allows it.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Updated autopay state.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "autopayEnabled": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/renewal/options

Review renewal options

Operation ID: serviceRenewalOptions

Returns valid renewal units or counts for the target service before you create a renewal checkout.

Scopes: billing.services.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available renewal options.

Illustrative response:

```json
{
  "ok": true,
  "currency": "EUR",
  "current": {
    "unit": "MONTH",
    "count": 1,
    "value": "MONTH:1",
    "label": "Monthly",
    "recurringUnitPrice": "100.00"
  },
  "options": [
    {
      "unit": "MONTH",
      "count": 1,
      "value": "MONTH:1",
      "label": "Monthly",
      "price": "100.00"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/renewal

Renew and pay using the current billing cycle

Operation ID: serviceRenewal

Renews the existing plan and billing cycle from account balance in one call. Reuses an eligible unpaid renewal invoice or creates one; never pays a purchase, upgrade, changed-cycle or mixed-service invoice. Full payment only: insufficient credit or max_total violation rolls back new invoices and any debit. Idempotency-Key is required: reuse the same key and exact body after an interrupted response. The financial receipt is durable. Optional max_total caps the outstanding amount in invoice/account currency; it is not a supplied price. Domain renewals can return renewal_pending=true: paid_through remains the last confirmed date until provider processing completes. Manual suspensions are not cleared by this request.

Scopes: billing.services.write + billing.invoice.pay

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (required): Unique renewal attempt key, 8–128 letters, digits or . _ : -. Reuse it on retries; a new key authorizes another cycle.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (optional)

```json
{
  "type": "object",
  "properties": {
    "max_total": {
      "type": "string",
      "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
    }
  },
  "additionalProperties": false
}
```

Response 200: Paid renewal receipt, or paid pending provider confirmation.

Illustrative response:

```json
{
  "ok": true,
  "service_id": "00000000-0000-4000-8000-000000000001",
  "invoice_id": "00000000-0000-4000-8000-000000000002",
  "invoice_number": "INV-EXAMPLE-001",
  "status": "paid",
  "invoice_status": "paid",
  "paid_now": "10.00",
  "currency": "EUR",
  "billing": {
    "unit": "MONTH",
    "count": 1
  },
  "paid_through": "2026-11-01T00:00:00.000Z",
  "renewal_pending": false
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/renewal/checkout

Start renewal checkout

Operation ID: serviceRenewalCheckout

Creates a renewal billing flow for the selected service and renewal period.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "unit": {
      "type": "string",
      "minLength": 1
    },
    "count": {
      "type": "integer",
      "minimum": 1
    }
  },
  "required": [
    "unit",
    "count"
  ],
  "additionalProperties": false
}
```

Response 200: Renewal checkout result.

Illustrative response:

```json
{
  "ok": true,
  "orderId": null,
  "invoiceId": "00000000-0000-4000-8000-000000000002",
  "invoiceNumber": "INV-EXAMPLE-000001",
  "total": "100.00",
  "currency": "EUR",
  "status": "unpaid"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/upgrade/options

Review upgrade options

Operation ID: serviceUpgradeOptions

Returns supported upgrade choices for the selected service.

Scopes: billing.services.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available upgrade options.

Illustrative response:

```json
{
  "ok": true,
  "extraDiskGB": 0,
  "keepExtraDisk": false,
  "service": {
    "category": "vps",
    "isCpanel": false
  },
  "current": {
    "variantId": "00000000-0000-4000-8000-000000000001",
    "sku": "4G",
    "dims": {
      "cpu": 2,
      "ram": 4,
      "disk": 40
    }
  },
  "currency": "EUR",
  "billing": {
    "unit": "MONTH",
    "count": 1
  },
  "proration": {
    "multiplier": 1,
    "fraction": 1,
    "periodStart": "2026-10-01T00:00:00.000Z",
    "periodEnd": "2026-11-01T00:00:00.000Z"
  },
  "options": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/upgrade/checkout

Start upgrade checkout

Operation ID: serviceUpgradeCheckout

Creates or applies an upgrade flow for the selected service and variant.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "variant_id": {
      "type": "string",
      "format": "uuid"
    }
  },
  "required": [
    "variant_id"
  ],
  "additionalProperties": false
}
```

Response 200: Upgrade checkout result.

Illustrative response:

```json
{
  "ok": true,
  "orderId": "00000000-0000-4000-8000-000000000001",
  "invoiceId": "00000000-0000-4000-8000-000000000002",
  "invoiceNumber": "INV-EXAMPLE-000001",
  "total": "100.00",
  "currency": "EUR",
  "status": "unpaid"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/billing/options

Review billing options

Operation ID: serviceBillingOptions

Returns the current billing-cycle choices exposed for the selected service.

Scopes: billing.services.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available billing options.

Illustrative response:

```json
{
  "ok": true,
  "currency": "EUR",
  "current": {
    "unit": "MONTH",
    "count": 1,
    "value": "MONTH:1",
    "label": "Monthly"
  },
  "options": [
    {
      "unit": "MONTH",
      "count": 1,
      "value": "MONTH:1",
      "label": "Monthly",
      "price": "100.00"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/billing/change/options

Review billing-cycle options

Operation ID: serviceBillingChangeOptions

Returns the proration-aware billing-cycle change choices for a service before checkout.

Scopes: billing.services.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available billing-cycle change options.

Illustrative response:

```json
{
  "ok": true,
  "currency": "EUR",
  "current": {
    "unit": "MONTH",
    "count": 1,
    "value": "MONTH:1",
    "label": "Monthly",
    "recurringUnitPrice": "100.00"
  },
  "proration": {
    "fraction": 1,
    "periodStart": "2026-10-01T00:00:00.000Z",
    "periodEnd": "2026-11-01T00:00:00.000Z"
  },
  "options": [
    {
      "unit": "MONTH",
      "count": 1,
      "value": "MONTH:1",
      "label": "Monthly",
      "targetRecurringUnitPrice": "100.00",
      "credit": "100.00",
      "payNow": "0.00"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/billing/change/checkout

Start billing-cycle change

Operation ID: serviceBillingChangeCheckout

Creates a prorated checkout when a customer changes the service billing cycle.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "unit": {
      "type": "string",
      "minLength": 1
    },
    "count": {
      "type": "integer",
      "minimum": 1
    }
  },
  "required": [
    "unit",
    "count"
  ],
  "additionalProperties": false
}
```

Response 200: Billing-cycle change checkout result.

Illustrative response:

```json
{
  "ok": true,
  "applied": true,
  "payNow": "0.00",
  "currency": "EUR"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/cancel

Request service cancellation

Operation ID: serviceCancel

Convenience alias for service termination. Use this when the customer intent is straightforward cancellation.

Scopes: billing.services.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Cancellation result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/dns/waf

Check DNS/WAF eligibility

Operation ID: serviceDnsWafStatus

Returns the protection mode and service eligibility for DNS proxy and WAF-related actions on the selected service.

Scopes: dns.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS/WAF eligibility details.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "serviceStatus": "active",
  "backendIpv4": "192.0.2.10",
  "dnsWaf": {
    "serviceId": null,
    "active": false
  },
  "free": {
    "eligible": true
  },
  "eligible": true,
  "mode": "free"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/services/{serviceId}/dns/waf/record

Inspect protected record

Operation ID: getServiceDnsWafRecord

Returns the current proxy, protection, and origin values for one service-scoped DNS record.

Scopes: dns.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- query domain (required): Zone or apex domain for the protected record.
- query name (required): Record name such as @ or www.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Protected record status.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "serviceStatus": "active",
  "backendIpv4": "192.0.2.10",
  "domain": "example.com",
  "record": {
    "name": "example.com.",
    "type": "A",
    "ttl": 300,
    "values": [
      "192.0.2.10"
    ],
    "proxied": false,
    "originValues": null,
    "protection": false
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy

Toggle proxy mode

Operation ID: serviceDnsWafRecordProxy

Enables or disables proxy mode for a service-scoped record. This is the main action for moving a record behind the managed proxy layer.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "enabled": {
      "type": "boolean"
    },
    "ttl": {
      "type": "integer",
      "minimum": 1,
      "maximum": 86400
    }
  },
  "required": [
    "domain",
    "name",
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Updated proxy state.

Illustrative response:

```json
{
  "ok": true,
  "appliedTo": "powerdns",
  "proxied": true,
  "providerBackends": [
    "192.0.2.10"
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/protection

Toggle protection mode

Operation ID: serviceDnsWafRecordProtection

Enables or disables the protection layer for a proxied record.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "domain",
    "name",
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Updated protection state.

Illustrative response:

```json
{
  "ok": true,
  "fqdn": "example.com",
  "protection": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/origin-sync

Run origin sync

Operation ID: serviceDnsWafRecordOriginSync

Refreshes the protected record origin target so the proxy backend follows the current service IP.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "domain",
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: Origin sync result.

Illustrative response:

```json
{
  "ok": true,
  "fqdn": "example.com",
  "backendIpv4": "192.0.2.10"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/show

View proxy settings

Operation ID: serviceDnsWafProxyConfigShow

Returns the proxy configuration for an owned proxied record. Accepts an owned DNS zone name or service UUID. With a zone-name selector, domain is optional and must match when supplied; name defaults to @. Prefer the read-only GET /v1/dns/zones/{name}/records/config. This legacy POST can ensure proxy registration.

Scopes: dns.read

- path serviceId (required): Your DNS zone name (example.com) or an owned service UUID. A name selects the owned zone directly; a UUID also requires domain in the query/body.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1024
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253,
      "default": "@"
    }
  },
  "additionalProperties": false
}
```

Response 200: Current proxy configuration.

Illustrative response:

```json
{
  "ok": true,
  "data": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/update-setting

Change proxy setting

Operation ID: serviceDnsWafProxyConfigUpdateSetting

Changes one supported proxy setting such as force SSL, SSL mode, or custom loader behavior.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "option": {
      "type": "string",
      "enum": [
        "ssl_schema",
        "force_ssl",
        "ssl",
        "custom_loader"
      ]
    },
    "value": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "domain",
    "name",
    "option",
    "value"
  ],
  "additionalProperties": false
}
```

Response 200: Updated proxy setting result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/get-ssl

View SSL settings

Operation ID: serviceDnsWafProxyConfigGetSsl

Returns certificate metadata and configuration readiness for the selected protected record. ready confirms a matching, currently valid certificate in the provider configuration; it does not confirm public DNS propagation or browser trust. Provider lookup failures return a safe error.

Scopes: dns.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "domain",
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: SSL configuration details.

Illustrative response:

```json
{
  "ok": true,
  "data": {
    "hasCert": true,
    "ready": true,
    "status": "ready",
    "mode": "c",
    "readiness_scope": "certificate_configuration",
    "cert": {
      "subject": "CN=example.com",
      "issuer": "CN=Example CA",
      "validFrom": "2026-10-01T00:00:00.000Z",
      "validTo": "2027-10-06T00:00:00.000Z",
      "fingerprint256": "AA:BB:CC"
    }
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/upload-ssl

Upload custom SSL certificate

Operation ID: serviceDnsWafProxyConfigUploadSsl

Validates the hostname, validity dates, certificate chain syntax and matching private key before uploading. Domains may be configured before DNS points to the proxy. Returns certificate configuration readiness and expected_fingerprint256 after readback. pending or unknown means the accepted upload is not yet confirmed; check get-ssl before retrying. Private key material is never returned.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "mode": {
      "type": "string",
      "enum": [
        "c",
        "w"
      ]
    },
    "cert": {
      "type": "string",
      "minLength": 1
    },
    "pkey": {
      "type": "string",
      "minLength": 1
    },
    "bundle": {
      "type": "string",
      "default": ""
    }
  },
  "required": [
    "domain",
    "name",
    "mode",
    "cert",
    "pkey"
  ],
  "additionalProperties": false
}
```

Response 200: SSL upload result.

Illustrative response:

```json
{
  "ok": true,
  "data": {
    "hasCert": false,
    "ready": false,
    "status": "pending",
    "mode": "c",
    "readiness_scope": "certificate_configuration"
  },
  "expected_fingerprint256": "AA:BB:CC"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/get-loader

View custom loader

Operation ID: serviceDnsWafProxyConfigGetLoader

Returns the currently configured custom loader or response page for a protected record.

Scopes: dns.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "domain",
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: Current loader configuration.

Illustrative response:

```json
{
  "ok": true,
  "data": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/services/{serviceId}/dns/waf/record/proxy-config/upload-loader

Upload custom loader

Operation ID: serviceDnsWafProxyConfigUploadLoader

Uploads custom HTML used by the proxy layer for the selected record.

Scopes: dns.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "html": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "domain",
    "name",
    "html"
  ],
  "additionalProperties": false
}
```

Response 200: Loader upload result.

Illustrative response:

```json
{
  "ok": true,
  "data": null,
  "html": "<!doctype html><title>Loading</title>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/catalog

Browse dedicated inventory

Operation ID: dedicatedCatalog

Returns currently sellable configurations, regions, hardware, billing periods, and compatible operating-system profiles.

Scopes: dedicated.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available dedicated inventory.

Illustrative response:

```json
{
  "ok": true,
  "items": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dedicated/deployments

Create dedicated deployment

Operation ID: dedicatedDeploy

Creates an unpaid order and invoice using catalog configurationCode, regionCode, numeric osProfileId, hostname, optional owned sshKeyId, billing and selectable add-ons. Use order-options to discover valid add-on keys and quantities, and preview the same complete configuration before ordering. Provisioning begins only after payment and any configured approval. Never invent configuration or OS IDs.

Scopes: dedicated.write

- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "configuration_code": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160
    },
    "region_code": {
      "type": "string",
      "pattern": "^[A-Z0-9-]{2,16}$"
    },
    "os_profile_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "hostname": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253,
      "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
    },
    "ssh_key_id": {
      "type": "string",
      "format": "uuid"
    },
    "addons": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "^[A-Za-z0-9_.:-]+$"
          },
          "qty": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          }
        },
        "required": [
          "key",
          "qty"
        ],
        "additionalProperties": false
      },
      "maxItems": 50
    },
    "currency": {
      "type": "string",
      "enum": [
        "EUR",
        "USD"
      ],
      "default": "EUR"
    },
    "billing": {
      "type": "object",
      "properties": {
        "unit": {
          "type": "string",
          "enum": [
            "MONTH",
            "QUARTAL",
            "SEMIANNUAL",
            "YEAR"
          ],
          "default": "MONTH"
        },
        "count": {
          "type": "integer",
          "minimum": 1,
          "maximum": 120,
          "default": 1
        }
      },
      "additionalProperties": false,
      "default": {
        "unit": "MONTH",
        "count": 1
      }
    }
  },
  "required": [
    "configuration_code",
    "region_code",
    "os_profile_id",
    "hostname"
  ],
  "additionalProperties": false
}
```

Response 201: Created order and invoice; not yet installed.

Illustrative response:

```json
{
  "ok": true,
  "orderId": "00000000-0000-4000-8000-000000000001",
  "invoiceId": "00000000-0000-4000-8000-000000000002",
  "invoiceNumber": "INV-EXAMPLE-000001",
  "total": "100.00",
  "currency": "EUR",
  "status": "unpaid",
  "deploymentStatusUrl": "/v1/dedicated/deployments/00000000-0000-4000-8000-000000000001",
  "message": "Invoice created. Provisioning begins after payment and any configured approval."
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/deployments/{orderId}

Check deployment

Operation ID: dedicatedDeployment

Returns payment, provisioning, service, IP, power, OS, and operation state for a dedicated order without exposing its password.

Scopes: dedicated.read

- path orderId (required): Dedicated deployment order UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Dedicated deployment status.

Illustrative response:

```json
{
  "ok": true,
  "deployment": {
    "orderId": "00000000-0000-4000-8000-000000000001",
    "orderStatus": "pending",
    "paymentStatus": "unpaid",
    "invoice": {
      "id": "00000000-0000-4000-8000-000000000001",
      "number": "INV-EXAMPLE-000001",
      "status": "unpaid",
      "total": "100.00",
      "paidTotal": "0.00",
      "currency": "EUR"
    },
    "serviceId": null,
    "serviceStatus": null,
    "ip": null,
    "power": null,
    "hostname": null,
    "osName": null,
    "operations": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}

Check dedicated server

Operation ID: dedicatedStatus

Returns the owned server lifecycle, hardware, operating system, IP, power state, and recent operations.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Dedicated server status.

Illustrative response:

```json
{
  "ok": true,
  "lifecycleStatus": "active",
  "service": {
    "state": "active",
    "configurationCode": "EXAMPLE",
    "regionCode": "PT",
    "hostname": "server.example.com",
    "osName": "Debian 13",
    "hardware": {
      "lineName": "Example dedicated server",
      "cpuSockets": 2,
      "ramGb": 256,
      "storageGb": 240,
      "linkGbps": 10,
      "physicalLinkGbps": 10,
      "cpuDescription": "Example CPU",
      "ramDescription": "DDR4 ECC",
      "storageDescription": "SSD"
    },
    "primaryIp": "192.0.2.10",
    "power": "online",
    "powerCheckedAt": "2026-10-01T00:00:00.000Z",
    "rescueMode": false,
    "canManage": true,
    "canConsole": true,
    "canReinstall": true,
    "canRescue": true
  },
  "operations": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/credentials

Reveal current credentials

Operation ID: dedicatedCredentials

Explicit no-store credential endpoint. Returns the owned server IP, username, and current generated password after activation.

Scopes: dedicated.credentials.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Dedicated server access credentials.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "ip": "192.0.2.10",
  "username": "root",
  "password": "<generated-password>",
  "credentialKind": "activate",
  "operationId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dedicated/{serviceId}/power

Queue power action

Operation ID: dedicatedPower

Body action: start, stop, restart or exit_rescue. Exiting rescue boots the installed system from disk. Interrupting actions require explicit intent. Task acceptance is not completion; inspect the returned task.

Scopes: dedicated.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "start",
        "stop",
        "restart",
        "exit_rescue"
      ]
    }
  },
  "required": [
    "action"
  ],
  "additionalProperties": false
}
```

Response 202: Queued power operation.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "00000000-0000-4000-8000-000000000002",
    "kind": "power_on",
    "state": "queued"
  },
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/tasks

List dedicated tasks

Operation ID: dedicatedTasks

Returns customer-visible operations for the owned server. Read history before repeating an uncertain action.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Dedicated task history.

Illustrative response:

```json
{
  "ok": true,
  "tasks": [
    {
      "id": "00000000-0000-4000-8000-000000000002",
      "kind": "reinstall",
      "status": "in_progress",
      "stage": "installing",
      "errorCode": null,
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-01T00:00:00.000Z"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/traffic

Read network traffic

Operation ID: getDedicatedByServiceIdTraffic

Returns available network samples. Rates are bits per second and traffic totals are bytes. Missing statistics are not zero traffic. Does not report guest resource usage.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Network statistics or unavailable result.

Illustrative response:

```json
{
  "ok": true,
  "available": false,
  "period": "24h",
  "interfaces": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/power-stats

Read electrical power statistics

Operation ID: dedicatedStats

Electrical consumption in watts, not CPU utilization. Any estimated energy value is not a billing meter. Hardware may not expose measurements.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Power statistics or unavailable result.

Illustrative response:

```json
{
  "ok": true,
  "available": false,
  "period": "24h",
  "points": [],
  "summary": {
    "currentWatts": null,
    "averageWatts": null,
    "peakWatts": null,
    "estimatedKwh": null
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/reinstall-options

List compatible installation images

Operation ID: dedicatedReinstallOptions

Read compatible numeric profile IDs before requesting reinstall. Reading options does not start an installation.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Compatible OS profiles.

Illustrative response:

```json
{
  "ok": true,
  "enabled": true,
  "currentProfileId": 1,
  "profiles": [
    {
      "id": 1,
      "name": "Debian 13",
      "allowSshKeys": true
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/rescue-options

List compatible rescue images

Operation ID: dedicatedRescueOptions

Read compatible numeric rescue profile IDs before requesting maintenance boot.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Compatible rescue profiles.

Illustrative response:

```json
{
  "ok": true,
  "enabled": true,
  "profiles": [
    {
      "id": 2,
      "name": "Example rescue image"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dedicated/{serviceId}/reinstall

Erase and reinstall the server

Operation ID: dedicatedReinstall

Irreversibly overwrites installed data. Read compatible profiles first; use an account-owned SSH key when supported. Inspect the returned task rather than submitting another installation.

Scopes: dedicated.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "profile_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "hostname": {
      "type": "string",
      "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
    },
    "ssh_key_id": {
      "type": "string",
      "format": "uuid"
    },
    "confirmation": {
      "type": "string",
      "const": "ERASE",
      "enum": [
        "ERASE"
      ]
    }
  },
  "required": [
    "profile_id",
    "confirmation"
  ],
  "additionalProperties": false
}
```

Response 202: Queued reinstall operation.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "00000000-0000-4000-8000-000000000002",
    "state": "waiting_provider"
  },
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dedicated/{serviceId}/rescue

Boot a rescue environment

Operation ID: dedicatedRescue

Interrupts applications and connections; does not itself reinstall the OS. Use a compatible rescue profile, then exit_rescue to return to installed-system boot.

Scopes: dedicated.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "profile_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "confirmation": {
      "type": "string",
      "const": "RESCUE",
      "enum": [
        "RESCUE"
      ]
    }
  },
  "required": [
    "profile_id",
    "confirmation"
  ],
  "additionalProperties": false
}
```

Response 202: Queued rescue operation.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "00000000-0000-4000-8000-000000000002",
    "state": "waiting_provider"
  },
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/tasks/{taskId}

Check dedicated task

Operation ID: dedicatedTask

Returns bounded customer-safe status for a power or maintenance task.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- path taskId (required): Dedicated operation UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Dedicated task status.

Illustrative response:

```json
{
  "ok": true,
  "task": {
    "id": "00000000-0000-4000-8000-000000000002",
    "kind": "reinstall",
    "status": "in_progress",
    "stage": "installing",
    "errorCode": null,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dedicated/{serviceId}/password-reset

Reset dedicated password

Operation ID: dedicatedPasswordReset

Interrupts connections while maintenance replaces the OS administrator password. Track the returned task; retrieve the result privately only after success.

Scopes: dedicated.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (required): Stable action key: 8–128 letters, digits, dot, underscore, colon or hyphen. Reuse the same key and payload on retries; inspect task state after a timeout.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 202: Queued password reset.

Illustrative response:

```json
{
  "ok": true,
  "operation": {
    "id": "00000000-0000-4000-8000-000000000002",
    "state": "waiting_provider"
  },
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/password-reset-credential

Reveal reset password

Operation ID: dedicatedPasswordResetCredential

Explicit no-store endpoint returning the generated password after successful reset. Sensitive output: do not log or send to an AI conversation.

Scopes: dedicated.credentials.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- query operationId (optional): Optional password-reset operation UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: New dedicated server password.

Illustrative response:

```json
{
  "ok": true,
  "operationId": "00000000-0000-4000-8000-000000000002",
  "password": "<generated-password>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/status

Check VPS status

Operation ID: vpsStatus

Returns hostname, assigned region code (for example NL or PT), customer IPv4/IPv6, power state and selected runtime metrics. Region describes the hosting country, not a specific datacenter building; null means unavailable. Does not disclose internal node or cluster identifiers. Ownership, status, type, search, external_id and label filters are applied server-side before pagination and counts. The default is active plus suspended; historical states require an explicit status filter. group_by=type groups only the current page, not the complete inventory.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: VPS runtime status, hostname and assigned region.

Illustrative response:

```json
{
  "ok": true,
  "vm": {
    "status": "running",
    "power": "on",
    "hostname": "server.example.com",
    "os": {
      "name": "Debian",
      "version": "13",
      "family": "debian",
      "source": "provisioning_metadata",
      "guestVerified": false
    },
    "ipv4": "192.0.2.10",
    "ipv6": null,
    "uptime": 3600,
    "cpus": 2,
    "cpu": 0.05,
    "mem": 536870912,
    "maxmem": 4294967296,
    "disk": 0,
    "maxdisk": 42949672960,
    "netin": 0,
    "netout": 0,
    "diskread": 0,
    "diskwrite": 0
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/credentials

Reveal recorded VPS credentials

Operation ID: vpsCredentials

Explicit, audited, no-store password retrieval. The platform-recorded root password may differ if changed inside the guest. Never log output or send it to a hosted AI conversation.

Scopes: vps.credentials.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Recorded rootPassword, hostname, IPv4 and IPv6.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "hostname": "server.example.com",
  "ipv4": "192.0.2.10",
  "ipv6": null,
  "rootPassword": "<generated-password>",
  "credentialSource": "platform_record",
  "guestVerified": false
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/console

Open browser console

Operation ID: vpsConsole

Returns an authenticated portal console URL, not a raw VNC connection or provider ticket. Browser login and service access are checked before connecting.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Console URL and requiresBrowserLogin.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "consoleUrl": "https://my.blazingfast.io/manage/vps/00000000-0000-4000-8000-000000000001/vnc",
  "requiresBrowserLogin": true,
  "transport": "browser"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dedicated/{serviceId}/console

Open browser console

Operation ID: dedicatedConsole

Returns an authenticated portal console URL. No provider address or VNC password is exposed. Sign in to connect.

Scopes: dedicated.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Console URL and requiresBrowserLogin.

Illustrative response:

```json
{
  "ok": true,
  "serviceId": "00000000-0000-4000-8000-000000000001",
  "consoleUrl": "https://my.blazingfast.io/manage/dedicated/00000000-0000-4000-8000-000000000001/console",
  "requiresBrowserLogin": true,
  "transport": "browser"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/reboot

Reboot server

Operation ID: rebootVps

Triggers a reboot action for the selected VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Reboot action result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002",
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/start

Start server

Operation ID: vpsStart

Starts a stopped VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Start action result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002",
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/stop

Stop server

Operation ID: vpsStop

Stops a running VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Stop action result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002",
  "operation_id": "op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "operation_url": "/v1/operations/op_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/password/reset

Reset root password

Operation ID: vpsPasswordReset

Generates and applies a new root password, then returns it once to the caller.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Generated password and reset result.

Illustrative response:

```json
{
  "ok": true,
  "newPassword": "<generated-password>",
  "credentialSynced": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/actions/{actionId}

Check action status

Operation ID: vpsActionStatus

Polls the current state of a long-running VPS action such as power, backup, or reinstall work.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- path actionId (required): Action UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Action status details.

Illustrative response:

```json
{
  "ok": true,
  "action": {
    "id": "00000000-0000-4000-8000-000000000002",
    "type": "start",
    "phase": "completed",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/reinstall/os

Browse reinstall images

Operation ID: vpsReinstallOs

Returns operating system choices available for VPS reinstall.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Available reinstall operating systems.

Illustrative response:

```json
{
  "ok": true,
  "osTemplates": [
    {
      "code": "debian-13",
      "name": "Debian",
      "version": "13",
      "arch": "amd64"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/reinstall

Start reinstall

Operation ID: vpsReinstall

Queues a durable reinstall and returns HTTP 202 with an action ID and operation URL. Poll the operation URL until completion, then read VPS credentials separately with vps.credentials.read. Acceptance does not mean the guest is ready.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header Idempotency-Key (optional): Recommended stable retry key. CLI 0.1.17 makes the flag optional: an omitted key is generated once, saved locally before dispatch and printed for explicit retries. Reuse the same key and exact payload. With durable_writes enabled, the API retains the dispatch identity after its encrypted response expires in 24 hours. An unknown outcome requires inspecting service/operation state; never generate a new key to retry it. Missing keys keep legacy behavior.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "os_code": {
      "type": "string",
      "minLength": 1
    },
    "hostname": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    },
    "ssh_key_id": {
      "anyOf": [
        {
          "type": "string",
          "format": "uuid"
        },
        {
          "type": "null"
        }
      ]
    },
    "ssh_public_key": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    },
    "firewall_policy_id": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        {
          "type": "string",
          "const": "__DEFAULT__",
          "enum": [
            "__DEFAULT__"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "os_name": {
      "type": "string",
      "minLength": 1
    },
    "os_version": {
      "type": "string",
      "minLength": 1
    },
    "os_arch": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "os_code"
  ],
  "additionalProperties": false
}
```

Response 202: Queued reinstall receipt.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002",
  "queued": true,
  "status": "queued",
  "operation_id": "op_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "operation_url": "/v1/operations/op_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/vps/{serviceId}/sshkey

Update VPS SSH key

Operation ID: vpsSshkeySet

Applies a public SSH key or a saved SSH key reference to the target VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "ssh_key_id": {
      "type": "string",
      "format": "uuid"
    },
    "public_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 8192
    }
  },
  "additionalProperties": false
}
```

Response 200: SSH key assignment result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/snapshots

Browse snapshots

Operation ID: listVpsSnapshots

Returns existing snapshots for the target VPS.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Snapshot list.

Illustrative response:

```json
{
  "ok": true,
  "snapshots": [
    {
      "name": "before-upgrade",
      "description": "Before upgrade",
      "running": 0
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/snapshots

Take snapshot

Operation ID: vpsSnapshotCreate

Creates a new snapshot for the target VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "include_ram": {
      "type": "boolean"
    }
  },
  "additionalProperties": false
}
```

Response 200: Snapshot creation result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002",
  "snapname": "before-upgrade"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/snapshots/progress

Check snapshot progress

Operation ID: vpsSnapshotsProgress

Returns the current progress state for an in-flight snapshot operation.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Snapshot progress.

Illustrative response:

```json
{
  "ok": true,
  "inProgress": false,
  "actionId": null,
  "lastRequestedAt": null,
  "lastResult": null,
  "action": null,
  "target": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/snapshots/{name}/rollback

Restore snapshot

Operation ID: vpsSnapshotRollback

Restores the VPS from the named snapshot.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- path name (required): Snapshot name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Snapshot rollback result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/vps/{serviceId}/snapshots/{name}

Remove snapshot

Operation ID: vpsSnapshotDelete

Deletes the named VPS snapshot.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- path name (required): Snapshot name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Snapshot deletion result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/backup

Check backup status

Operation ID: getVpsBackup

Returns current backup information for the VPS.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Current backup state.

Illustrative response:

```json
{
  "ok": true,
  "storageId": "example-backup-storage",
  "usedBytes": 0,
  "backupCount": 0,
  "poolUsedBytes": 0,
  "poolBackupCount": 0,
  "quota": {
    "freeGiB": 10,
    "purchasedGiB": 0,
    "limitBytes": 10737418240,
    "freeBytes": 10737418240
  },
  "files": [],
  "backup": null,
  "os": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/vps/{serviceId}/backup

Delete backup files

Operation ID: vpsBackupDelete

Deletes the current backup record or configured backup object for the VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup deletion result.

Illustrative response:

```json
{
  "ok": true,
  "deleted": 1
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/backup/schedule

View backup schedule

Operation ID: getVpsBackupSchedule

Returns current backup schedule settings for the VPS.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup schedule settings.

Illustrative response:

```json
{
  "ok": true,
  "schedule": {
    "enabled": false
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/vps/{serviceId}/backup/schedule

Change backup schedule

Operation ID: vpsBackupSchedulePut

Creates or updates the backup schedule for the VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "cadence": {
      "type": "string",
      "enum": [
        "daily",
        "weekly"
      ]
    },
    "at_hour": {
      "type": "integer",
      "minimum": 0,
      "maximum": 23
    },
    "at_minute": {
      "type": "integer",
      "minimum": 0,
      "maximum": 59
    },
    "day_of_week": {
      "type": "integer",
      "minimum": 0,
      "maximum": 6
    }
  },
  "additionalProperties": false
}
```

Response 200: Updated backup schedule.

Illustrative response:

```json
{
  "ok": true,
  "schedule": {
    "enabled": false
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/backup/run

Start backup

Operation ID: vpsBackupRun

Starts an on-demand backup for the selected VPS.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup run result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/backup/progress

Check backup progress

Operation ID: vpsBackupProgress

Returns current progress for an active backup job.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup progress.

Illustrative response:

```json
{
  "ok": true,
  "inProgress": false,
  "actionId": null,
  "lastRequestedAt": null,
  "lastResult": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/backup/cancel

Cancel backup run

Operation ID: vpsBackupCancel

Requests cancellation of an active backup job.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup cancellation result.

Illustrative response:

```json
{
  "ok": true,
  "cancelled": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/backup/restore

Start backup restore

Operation ID: vpsBackupRestore

Starts a restore from the current or selected VPS backup artifact.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-bf-response-format (optional): Opt into the canonical Operation receipt for this tracked write. Requires canonical_operation_responses enabled. Omit for the legacy response. Retried requests may replay their initial response format; use its operation_id or operation.id to poll.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "auto_start": {
      "type": "boolean"
    },
    "file": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "additionalProperties": false
}
```

Response 200: Backup restore result.

Illustrative response:

```json
{
  "ok": true,
  "actionId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/backup/restore/progress

Check restore progress

Operation ID: vpsBackupRestoreProgress

Returns progress for an active backup restore.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Backup restore progress.

Illustrative response:

```json
{
  "ok": true,
  "inProgress": false,
  "actionId": null,
  "lastRequestedAt": null,
  "lastResult": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/templates

Browse DNS templates

Operation ID: listDnsTemplates

Returns reusable DNS templates that can be applied during zone creation.

Scopes: dns.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS template list.

Illustrative response:

```json
{
  "ok": true,
  "templates": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example template",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-01T00:00:00.000Z",
      "system": false,
      "visibility": "private",
      "isHidden": false
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dns/templates

Save DNS template

Operation ID: dnsTemplateCreate

Creates a reusable DNS template from a zone-file fragment.

Scopes: dns.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "zone_file": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500000
    }
  },
  "required": [
    "name",
    "zone_file"
  ],
  "additionalProperties": false
}
```

Response 200: Created DNS template.

Illustrative response:

```json
{
  "ok": true,
  "template": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example template",
    "zoneFile": "@ 300 IN A 192.0.2.10",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z",
    "system": false,
    "visibility": "private"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/templates/{id}

Open DNS template

Operation ID: getDnsTemplate

Returns an owned or public system template by name or UUID. Name matching is case-insensitive and checks your templates first; public system defaults are a fallback. Other accounts are excluded. Only duplicate names within the selected scope return template_identifier_ambiguous. Edit/delete routes still require UUIDs.

Scopes: dns.read

- path id (required): Your template name (cpanel2 or My template) or UUID; URL-encode spaces and Unicode.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS template detail.

Illustrative response:

```json
{
  "ok": true,
  "template": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example template",
    "zoneFile": "@ 300 IN A 192.0.2.10",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z",
    "system": false,
    "visibility": "private"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/dns/templates/{id}

Edit DNS template

Operation ID: dnsTemplateUpdate

Updates the name or zone-file content of an existing template.

Scopes: dns.write

- path id (required): DNS template UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "zone_file": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500000
    }
  },
  "additionalProperties": false
}
```

Response 200: Updated DNS template.

Illustrative response:

```json
{
  "ok": true,
  "template": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example template",
    "zoneFile": "@ 300 IN A 192.0.2.10",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z",
    "system": false,
    "visibility": "private"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/dns/templates/{id}

Remove DNS template

Operation ID: dnsTemplateDelete

Deletes a DNS template.

Scopes: dns.write

- path id (required): DNS template UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS template deletion result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones

Browse DNS zones

Operation ID: listDnsZones

Returns owned customer DNS zones. Use view=summary for a lightweight, read-only inventory with name search before pagination; it returns total, limit, offset and zones. The default legacy view remains unchanged. Summary results sort by zone name and do not contact nameservers or change billing links.

Scopes: dns.read

- query q (optional): Optional zone name search filter.
- query sort (optional): Optional legacy-view sort key; summary always sorts by name.
- query view (optional): Use summary for lightweight paginated zone cards.
- query limit (optional): Summary only: maximum zones returned.
- query offset (optional): Summary only: number of matching zones to skip.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS zone list. Summary adds total, limit and offset; zones contain name, status and createdAt only.

Illustrative response:

```json
{
  "ok": true,
  "zones": [
    {
      "name": "example.com",
      "status": "active",
      "createdAt": "2026-10-01T00:00:00.000Z"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dns/zones

Create or preview DNS zone

Operation ID: createDnsZone

Body: name; at most one of templateId UUID, zoneFile text (100000 characters max), or records array ({name,type,ttl,values}, max 200 sets, 50 values/set, TTL 1–86400 seconds). Omit all sources for an empty zone. dryRun:true validates and returns records/notes without creating or reserving a zone; requires an existing active DNS service. Use separate Idempotency-Keys for preview and creation. Platform apex NS replaces imported NS and SOA is managed automatically. Zone files support IN records, relative names, $ORIGIN, $TTL and multiline records; external includes/generation and foreign owners are rejected. Resolve template names via GET /v1/dns/templates and inspect their details; templates must be owned or public. Existing zones are never overwritten. A records may be proxied by the existing protection policy. Does not register domains or change registrar delegation.

Scopes: dns.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253
    },
    "template_id": {
      "type": "string",
      "format": "uuid"
    },
    "zone_file": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100000
    },
    "records": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 253
          },
          "type": {
            "type": "string",
            "enum": [
              "A",
              "AAAA",
              "CNAME",
              "MX",
              "TXT",
              "NS",
              "SOA",
              "PTR",
              "SRV",
              "CAA",
              "SSHFP",
              "TLSA",
              "NAPTR",
              "LOC",
              "DS",
              "DNSKEY"
            ]
          },
          "ttl": {
            "type": "integer",
            "minimum": 1,
            "maximum": 86400
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4096
            },
            "minItems": 1,
            "maxItems": 50
          }
        },
        "required": [
          "name",
          "type",
          "values"
        ],
        "additionalProperties": false
      },
      "maxItems": 200
    },
    "dry_run": {
      "type": "boolean"
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false,
  "description": "At most one of templateId, zoneFile or records. Omit all three for an empty zone. Names and record ownership are validated by the backend."
}
```

Response 200: Created zone, or normalized records and notes for dryRun.

Illustrative response:

```json
{
  "ok": true,
  "zoneId": "00000000-0000-4000-8000-000000000001",
  "zone": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}

Open DNS zone

Operation ID: getDnsZone

Returns one DNS zone and its customer-facing detail view.

Scopes: dns.read

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS zone detail.

Illustrative response:

```json
{
  "ok": true,
  "domain": {
    "name": "example.com",
    "zoneId": "00000000-0000-4000-8000-000000000001",
    "status": "active",
    "adminLock": false,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/dns/zones/{name}

Remove DNS zone

Operation ID: dnsZoneDelete

Deletes a DNS zone.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: DNS zone deletion result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/records/simple

Browse simple records

Operation ID: listDnsRecordsSimple

Returns simplified DNS records for a zone.

Scopes: dns.read

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Simple DNS records.

Illustrative response:

```json
{
  "ok": true,
  "service": {
    "id": "00000000-0000-4000-8000-000000000001",
    "status": "active",
    "suspendedReason": null
  },
  "records": [
    {
      "name": "@",
      "type": "A",
      "ttl": 300,
      "values": [
        "192.0.2.10"
      ],
      "proxied": false,
      "originValues": null,
      "protection": false,
      "wafEligible": false,
      "protectionMode": "none"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/dns/zones/{name}/records/simple

Save simple record

Operation ID: dnsRecordsSimpleSet

Creates or replaces a simplified DNS record set.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "mode": {
      "type": "string",
      "enum": [
        "append",
        "replace"
      ]
    },
    "record": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 253
        },
        "type": {
          "type": "string",
          "minLength": 1,
          "maxLength": 16
        },
        "ttl": {
          "type": "integer",
          "minimum": 1,
          "maximum": 86400
        },
        "values": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "maxItems": 50
        },
        "protect": {
          "type": "boolean"
        }
      },
      "required": [
        "name",
        "type",
        "values"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "record"
  ],
  "additionalProperties": false
}
```

Response 200: Simple record upsert result.

Illustrative response:

```json
{
  "ok": true,
  "appliedTo": "powerdns",
  "changeId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/dns/zones/{name}/records/simple

Remove simple record

Operation ID: dnsRecordsSimpleDelete

Deletes a simplified DNS record set from the zone.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253
    },
    "type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 16
    }
  },
  "required": [
    "name",
    "type"
  ],
  "additionalProperties": false
}
```

Response 200: Simple record deletion result.

Illustrative response:

```json
{
  "ok": true,
  "appliedTo": "powerdns",
  "changeId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/dns/zones/{name}/records

Browse raw rrsets

Operation ID: getDnsRrsets

Returns advanced rrset data for customers that need lower-level DNS editing.

Scopes: dns.read

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Raw rrset list.

Illustrative response:

```json
{
  "ok": true,
  "source": "powerdns",
  "rrsets": [
    {
      "name": "example.com.",
      "type": "A",
      "ttl": 300,
      "records": [
        {
          "content": "192.0.2.10",
          "disabled": false
        }
      ]
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/dns/zones/{name}/records

Apply rrset changes

Operation ID: dnsRrsetsPatch

Applies advanced rrset changes using REPLACE or DELETE style operations.

Scopes: dns.write

- path name (required): Zone or domain name.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "rrsets": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 253
          },
          "type": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16
          },
          "ttl": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647
          },
          "changetype": {
            "type": "string",
            "enum": [
              "REPLACE",
              "DELETE"
            ]
          },
          "records": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "content": {
                  "type": "string"
                },
                "disabled": {
                  "type": "boolean"
                }
              },
              "required": [
                "content"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "name",
          "type"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "rrsets"
  ],
  "additionalProperties": false
}
```

Response 200: Raw rrset patch result.

Illustrative response:

```json
{
  "ok": true,
  "appliedTo": "powerdns",
  "changeId": "00000000-0000-4000-8000-000000000002"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/tlds

Browse supported TLDs

Operation ID: domainTlds

Returns customer-searchable TLD data for domain purchase and transfer flows.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Supported TLD list.

Illustrative response:

```json
{
  "ok": true,
  "tlds": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/check

Check availability

Operation ID: domainCheck

Checks one or more domains for availability.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "domains": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 3
      },
      "minItems": 1,
      "maxItems": 50
    }
  },
  "required": [
    "domains"
  ],
  "additionalProperties": false
}
```

Response 200: Availability results.

Illustrative response:

```json
{
  "ok": true,
  "results": [
    {
      "domain": "example.com",
      "available": false,
      "premium": false,
      "price": null,
      "renewalPrice": null,
      "renewalCurrency": null,
      "currency": null,
      "transferPrice": null,
      "transferCurrency": null,
      "is_private_whois_allowed": false
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/search

Search domains

Operation ID: domainSearch

Searches available domains by keyword with paging support.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "keyword": {
      "type": "string",
      "minLength": 1,
      "maxLength": 63
    },
    "page": {
      "type": "integer",
      "minimum": 0,
      "default": 0
    },
    "page_size": {
      "type": "integer",
      "minimum": 5,
      "maximum": 50,
      "default": 20
    }
  },
  "required": [
    "keyword"
  ],
  "additionalProperties": false
}
```

Response 200: Domain search results.

Illustrative response:

```json
{
  "ok": true,
  "results": [],
  "hasMore": false,
  "page": 0,
  "total": 0
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/suggest

Suggest domains

Operation ID: domainSuggest

Returns suggestion-style domain options derived from a keyword.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "keyword": {
      "type": "string",
      "minLength": 1,
      "maxLength": 253
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "keyword"
  ],
  "additionalProperties": false
}
```

Response 200: Domain suggestions.

Illustrative response:

```json
{
  "ok": true,
  "suggestions": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains

Browse domains

Operation ID: listDomains

Returns domain services already attached to the customer account.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Customer domain service list.

Illustrative response:

```json
{
  "ok": true,
  "domains": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/{serviceId}

Open domain detail

Operation ID: getDomain

Returns the current detail view for one domain service.

Scopes: domains.read

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Domain service detail.

Illustrative response:

```json
{
  "ok": true,
  "service_id": "00000000-0000-4000-8000-000000000001",
  "domain_name": "example.com",
  "service": {
    "id": "00000000-0000-4000-8000-000000000001",
    "status": "active"
  },
  "domain": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/{serviceId}/status

Check domain status

Operation ID: domainStatus

Returns current domain lifecycle or verification status for one domain service.

Scopes: domains.read

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Domain status details.

Illustrative response:

```json
{
  "ok": true,
  "status": null
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/domains/{serviceId}/nameservers

Update nameservers

Operation ID: domainNameserversUpdate

Replaces nameserver configuration for a domain service.

Scopes: domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "nameservers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "ip": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "minItems": 2,
      "maxItems": 13
    }
  },
  "required": [
    "nameservers"
  ],
  "additionalProperties": false
}
```

Response 200: Nameserver update result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/domains/{serviceId}/lock

Change transfer lock

Operation ID: domainLock

Enables or disables the domain lock state.

Scopes: domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "locked": {
      "type": "boolean"
    }
  },
  "required": [
    "locked"
  ],
  "additionalProperties": false
}
```

Response 200: Updated domain lock state.

Illustrative response:

```json
{
  "ok": true,
  "locked": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/domains/{serviceId}/whois-privacy

Change WHOIS privacy

Operation ID: domainWhoisPrivacy

Enables or disables WHOIS privacy when the domain and registrar flow allow it.

Scopes: domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "additionalProperties": false
}
```

Response 200: Updated WHOIS privacy state.

Illustrative response:

```json
{
  "ok": true,
  "enabled": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/{serviceId}/auth-code

View transfer code

Operation ID: domainAuthCode

Returns the current transfer authorization code when available.

Scopes: domains.read

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Transfer auth code.

Illustrative response:

```json
{
  "ok": true,
  "auth_code": "<transfer-code>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/{serviceId}/transfer-status

Check transfer status

Operation ID: domainTransferStatus

Returns the current transfer state for a domain service.

Scopes: domains.read

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Transfer status details.

Illustrative response:

```json
{
  "ok": true,
  "transferStatus": "unknown",
  "isActive": false
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/{serviceId}/resend-verification

Resend verification

Operation ID: domainResendVerification

Resends a verification step for a domain when the registrar flow requires it.

Scopes: domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Verification resend result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/domains/{serviceId}/contacts

Assign contacts

Operation ID: domainAssignContacts

Assigns registrant, admin, tech, or billing contacts to a domain service.

Scopes: domains.write

- path serviceId (required): Your registered domain name (example.com) or service UUID. Names are case-insensitive and normalized to IDNA ASCII; one trailing dot is accepted. Exact matches are restricted to your non-terminated domain services. Multiple matches return domain_identifier_ambiguous; use the UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "contact_ids": {
      "type": "object",
      "properties": {
        "registrant": {
          "type": "string",
          "format": "uuid"
        },
        "admin": {
          "type": "string",
          "format": "uuid"
        },
        "tech": {
          "type": "string",
          "format": "uuid"
        },
        "billing": {
          "type": "string",
          "format": "uuid"
        }
      },
      "additionalProperties": false
    }
  },
  "required": [
    "contact_ids"
  ],
  "additionalProperties": false
}
```

Response 200: Updated domain contacts.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/domains/contacts

Browse domain contacts

Operation ID: listDomainContacts

Returns saved domain contact records available for assignment.

Scopes: domains.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Domain contact list.

Illustrative response:

```json
{
  "ok": true,
  "contacts": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/domains/contacts

Save domain contact

Operation ID: domainContactCreate

Creates a reusable domain contact record.

Scopes: domains.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "first_name": {
      "type": "string",
      "minLength": 1
    },
    "last_name": {
      "type": "string",
      "minLength": 1
    },
    "company_name": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "phone": {
      "type": "string",
      "minLength": 1
    },
    "address": {
      "type": "object",
      "properties": {
        "street": {
          "type": "string",
          "minLength": 1
        },
        "number": {
          "type": "string",
          "minLength": 1
        },
        "city": {
          "type": "string",
          "minLength": 1
        },
        "zipcode": {
          "type": "string",
          "minLength": 1
        },
        "state": {
          "type": "string"
        },
        "country": {
          "type": "string",
          "maxLength": 2,
          "minLength": 2
        }
      },
      "required": [
        "street",
        "number",
        "city",
        "zipcode",
        "country"
      ],
      "additionalProperties": false
    },
    "tag": {
      "type": "string"
    },
    "vat": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\-. ]*$"
    },
    "passport_number": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\- ]*$"
    },
    "tax_id": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\-. ]*$"
    },
    "additional_data": {
      "type": "object",
      "additionalProperties": {}
    }
  },
  "required": [
    "first_name",
    "last_name",
    "email",
    "phone",
    "address"
  ],
  "additionalProperties": false
}
```

Response 200: Created domain contact.

Illustrative response:

```json
{
  "ok": true,
  "contact": {
    "id": "00000000-0000-4000-8000-000000000001",
    "firstName": "Example",
    "lastName": "Customer",
    "country": "NL"
  },
  "handle": "EXAMPLE-HANDLE"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/domains/contacts/{contactId}

Edit domain contact

Operation ID: domainContactUpdate

Replaces a saved domain contact record.

Scopes: domains.write

- path contactId (required): Domain contact UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "first_name": {
      "type": "string",
      "minLength": 1
    },
    "last_name": {
      "type": "string",
      "minLength": 1
    },
    "company_name": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "phone": {
      "type": "string",
      "minLength": 1
    },
    "address": {
      "type": "object",
      "properties": {
        "street": {
          "type": "string",
          "minLength": 1
        },
        "number": {
          "type": "string",
          "minLength": 1
        },
        "city": {
          "type": "string",
          "minLength": 1
        },
        "zipcode": {
          "type": "string",
          "minLength": 1
        },
        "state": {
          "type": "string"
        },
        "country": {
          "type": "string",
          "maxLength": 2,
          "minLength": 2
        }
      },
      "required": [
        "street",
        "number",
        "city",
        "zipcode",
        "country"
      ],
      "additionalProperties": false
    },
    "tag": {
      "type": "string"
    },
    "vat": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\-. ]*$"
    },
    "passport_number": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\- ]*$"
    },
    "tax_id": {
      "type": "string",
      "maxLength": 30,
      "pattern": "^[A-Za-z0-9\\-. ]*$"
    },
    "additional_data": {
      "type": "object",
      "additionalProperties": {}
    }
  },
  "required": [
    "first_name",
    "last_name",
    "email",
    "phone",
    "address"
  ],
  "additionalProperties": false
}
```

Response 200: Updated domain contact.

Illustrative response:

```json
{
  "ok": true,
  "contact": {
    "id": "00000000-0000-4000-8000-000000000001",
    "firstName": "Example",
    "lastName": "Customer",
    "country": "NL"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/domains/contacts/{contactId}

Remove domain contact

Operation ID: domainContactDelete

Deletes a saved domain contact record.

Scopes: domains.write

- path contactId (required): Domain contact UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Domain contact deletion result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/ssh/keys

Browse SSH keys

Operation ID: listSshKeys

Returns saved SSH keys for the customer account.

Scopes: ssh.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: SSH key list.

Illustrative response:

```json
{
  "ok": true,
  "keys": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example key",
      "algorithm": "ed25519",
      "fingerprint": "SHA256:example-fingerprint",
      "isPrimary": false,
      "hasPrivateKey": false,
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-01T00:00:00.000Z"
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/ssh/keys

Save SSH key

Operation ID: sshKeyImport

Stores a new public SSH key for later provisioning or VPS assignment.

Scopes: ssh.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "public_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 8192
    }
  },
  "required": [
    "name",
    "public_key"
  ],
  "additionalProperties": false
}
```

Response 201: Created SSH key.

Illustrative response:

```json
{
  "ok": true,
  "key": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example key",
    "algorithm": "ed25519",
    "fingerprint": "SHA256:example-fingerprint",
    "isPrimary": false,
    "hasPrivateKey": false,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/ssh/keys/generate

Generate SSH keypair

Operation ID: sshKeyGenerate

Generates a new SSH keypair and returns the private key once.

Scopes: ssh.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "algorithm": {
      "type": "string",
      "minLength": 1
    },
    "format": {
      "type": "string",
      "minLength": 1
    },
    "passphrase": {
      "type": "string",
      "minLength": 8,
      "maxLength": 200
    }
  },
  "required": [
    "name",
    "passphrase"
  ],
  "additionalProperties": false
}
```

Response 201: Generated SSH keypair.

Illustrative response:

```json
{
  "ok": true,
  "key": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example key",
    "algorithm": "ed25519",
    "fingerprint": "SHA256:example-fingerprint",
    "isPrimary": false,
    "hasPrivateKey": true,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  },
  "privateKey": "<private-key-returned-once>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/ssh/keys/{id}/public

View public key

Operation ID: sshKeyPublic

Returns the public portion of one saved SSH key.

Scopes: ssh.read

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Public SSH key material.

Illustrative response:

```json
{
  "ok": true,
  "id": "00000000-0000-4000-8000-000000000001",
  "publicKey": "<public-ssh-key>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/ssh/keys/{id}/private

Export private key

Operation ID: sshKeyPrivateExport

Exports the private portion of a generated SSH key when the correct passphrase is supplied.

Scopes: ssh.write

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "passphrase": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    }
  },
  "required": [
    "passphrase"
  ],
  "additionalProperties": false
}
```

Response 200: Private SSH key export result.

Illustrative response:

```json
{
  "ok": true,
  "privateKey": "<private-key>"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/ssh/keys/{id}

Edit SSH key

Operation ID: sshKeyUpdate

Replaces the name and public key material of an existing SSH key record.

Scopes: ssh.write

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "public_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 8192
    }
  },
  "required": [
    "name",
    "public_key"
  ],
  "additionalProperties": false
}
```

Response 200: Updated SSH key.

Illustrative response:

```json
{
  "ok": true,
  "key": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example key",
    "algorithm": "ed25519",
    "fingerprint": "SHA256:example-fingerprint",
    "isPrimary": false,
    "hasPrivateKey": false,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/ssh/keys/{id}

Rename SSH key

Operation ID: sshKeyRename

Changes only the display name of an SSH key.

Scopes: ssh.write

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: Renamed SSH key.

Illustrative response:

```json
{
  "ok": true,
  "key": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example key",
    "algorithm": "ed25519",
    "fingerprint": "SHA256:example-fingerprint",
    "isPrimary": false,
    "hasPrivateKey": false,
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-01T00:00:00.000Z"
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/ssh/keys/{id}

Remove SSH key

Operation ID: sshKeyDelete

Deletes an SSH key from the customer account.

Scopes: ssh.write

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: SSH key deletion result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PUT /v1/ssh/keys/{id}/primary

Set primary SSH key

Operation ID: sshKeySetPrimary

Marks one SSH key as the primary default choice for relevant workflows.

Scopes: ssh.write

- path id (required): SSH key UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Updated primary SSH key.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/firewall/policies

Browse firewall policies

Operation ID: listFirewallPolicies

Returns reusable firewall policies available to the customer.

Scopes: firewall.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Firewall policy list.

Illustrative response:

```json
{
  "ok": true,
  "policies": [
    {
      "id": "00000000-0000-4000-8000-000000000001",
      "name": "Example policy",
      "description": null,
      "isPrimary": false,
      "policyIn": "DROP",
      "policyOut": "ACCEPT",
      "rules": []
    }
  ]
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/firewall/policies

Save firewall policy

Operation ID: firewallPolicyCreate

Creates a reusable firewall policy with default actions and optional rules.

Scopes: firewall.write

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "description": {
      "type": "string",
      "maxLength": 500
    },
    "policy_in": {
      "type": "string",
      "enum": [
        "DROP",
        "ACCEPT"
      ]
    },
    "policy_out": {
      "type": "string",
      "enum": [
        "DROP",
        "ACCEPT"
      ]
    },
    "rules": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string",
            "enum": [
              "IN",
              "OUT"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "action": {
            "type": "string",
            "enum": [
              "ACCEPT",
              "DROP",
              "REJECT"
            ]
          },
          "proto": {
            "type": "string",
            "enum": [
              "tcp",
              "udp",
              "icmp",
              "TCP",
              "UDP",
              "ICMP",
              "any",
              "all",
              "ANY",
              "ALL"
            ]
          },
          "dport": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "sport": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "destination": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "dest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "comment": {
            "type": "string",
            "maxLength": 200
          },
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "enable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "iface": {
            "type": "string",
            "maxLength": 64
          },
          "log": {
            "type": "string",
            "maxLength": 64
          }
        },
        "required": [
          "action"
        ],
        "additionalProperties": false
      }
    },
    "is_primary": {
      "type": "boolean"
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: Created firewall policy.

Illustrative response:

```json
{
  "ok": true,
  "policy": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example policy",
    "description": null,
    "isPrimary": false,
    "policyIn": "DROP",
    "policyOut": "ACCEPT",
    "rules": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### PATCH /v1/firewall/policies/{policyId}

Edit firewall policy

Operation ID: firewallPolicyUpdate

Updates policy metadata or replaces rules when a new rule list is provided.

Scopes: firewall.write

- path policyId (required): Firewall policy UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "description": {
      "type": "string",
      "maxLength": 500
    },
    "policy_in": {
      "type": "string",
      "enum": [
        "DROP",
        "ACCEPT"
      ]
    },
    "policy_out": {
      "type": "string",
      "enum": [
        "DROP",
        "ACCEPT"
      ]
    },
    "rules": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string",
            "enum": [
              "IN",
              "OUT"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "action": {
            "type": "string",
            "enum": [
              "ACCEPT",
              "DROP",
              "REJECT"
            ]
          },
          "proto": {
            "type": "string",
            "enum": [
              "tcp",
              "udp",
              "icmp",
              "TCP",
              "UDP",
              "ICMP",
              "any",
              "all",
              "ANY",
              "ALL"
            ]
          },
          "dport": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "sport": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "destination": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "dest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "comment": {
            "type": "string",
            "maxLength": 200
          },
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "enable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "iface": {
            "type": "string",
            "maxLength": 64
          },
          "log": {
            "type": "string",
            "maxLength": 64
          }
        },
        "required": [
          "action"
        ],
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
```

Response 200: Updated firewall policy.

Illustrative response:

```json
{
  "ok": true,
  "policy": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "Example policy",
    "description": null,
    "isPrimary": false,
    "policyIn": "DROP",
    "policyOut": "ACCEPT",
    "rules": []
  }
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### DELETE /v1/firewall/policies/{policyId}

Remove firewall policy

Operation ID: firewallPolicyDelete

Deletes a reusable firewall policy.

Scopes: firewall.write

- path policyId (required): Firewall policy UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Firewall policy deletion result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/firewall/policies/{policyId}/primary

Set primary firewall policy

Operation ID: firewallPolicySetPrimary

Marks a firewall policy as the primary default policy.

Scopes: firewall.write

- path policyId (required): Firewall policy UUID.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Primary policy update result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/vps/{serviceId}/firewall/policy

View VPS firewall policy

Operation ID: getVpsFirewallPolicy

Returns the effective firewall policy selection for a VPS.

Scopes: vps.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Effective firewall policy.

Illustrative response:

```json
{
  "ok": true,
  "requestedPolicyId": null,
  "primaryPolicyId": "00000000-0000-4000-8000-000000000001",
  "effectivePolicyId": "00000000-0000-4000-8000-000000000001",
  "effectiveMode": "primary"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/vps/{serviceId}/firewall/policy/apply

Apply policy to VPS

Operation ID: vpsFirewallPolicyApply

Applies a selected firewall policy to a VPS service.

Scopes: vps.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "policy_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    }
  },
  "required": [
    "policy_id"
  ],
  "additionalProperties": false
}
```

Response 200: Firewall policy apply result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/storage/volumes

Browse storage volumes

Operation ID: listStorageVolumes

Returns customer-visible storage volumes.

Scopes: storage.read

- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Storage volume list.

Illustrative response:

```json
{
  "ok": true,
  "items": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### GET /v1/storage/volumes/{serviceId}/attach-options

View attach options

Operation ID: storageVolumeAttachOptions

Returns eligible target services or VMs that can accept the selected volume.

Scopes: storage.read

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Volume attach options.

Illustrative response:

```json
{
  "ok": true,
  "items": []
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/storage/volumes/{serviceId}/attach

Attach volume

Operation ID: storageVolumeAttach

Attaches the selected volume to a target service.

Scopes: storage.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "target_service_id": {
      "type": "string",
      "format": "uuid"
    }
  },
  "required": [
    "target_service_id"
  ],
  "additionalProperties": false
}
```

Response 200: Volume attach result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/storage/volumes/{serviceId}/detach

Detach volume

Operation ID: storageVolumeDetach

Detaches the selected volume from its current target.

Scopes: storage.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

Response 200: Volume detach result.

Illustrative response:

```json
{
  "ok": true
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```

### POST /v1/storage/volumes/{serviceId}/rename

Rename volume

Operation ID: storageVolumeRename

Changes the customer-visible volume name.

Scopes: storage.write

- path serviceId (required): Customer-visible UUID of the service you want to inspect or change.
- header x-client-request-id (optional): Optional client correlation label, 1–120 letters/digits/dots/underscores/colons/hyphens. Logged alongside the server request ID; never an idempotency key.
- header x-ts (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Unix timestamp in seconds; refresh it for every HTTP attempt. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-nonce (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Fresh nonce for every HTTP attempt; never reuse it when retrying. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-content-sha256 (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 SHA-256 of the exact transmitted body bytes; hash the empty body for bodyless requests. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.
- header x-signature (optional): Required when using SignedAuth with x-api-key; omitted for BearerAuth. Base64 HMAC-SHA256 signature produced by the documented signing algorithm. Generic OpenAPI clients do not compute HMAC signatures; use an official SDK or implement signing manually.

JSON body (required)

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
```

Response 200: Volume rename result.

Illustrative response:

```json
{
  "ok": true,
  "billingServiceId": "00000000-0000-4000-8000-000000000001",
  "name": "Example volume"
}
```

Response default: Canonical nested error envelope: use error.code, error.message, error.request_id and error.field_errors. Deprecated flat fields may be included for legacy clients. Generic server failures use service_unavailable without internal details. An interrupted connection may leave a write outcome unknown.

Illustrative response:

```json
{
  "ok": false,
  "error": {
    "code": "scope_denied",
    "message": "Required scope is missing",
    "request_id": "00000000-0000-4000-8000-000000000001",
    "field_errors": []
  }
}
```


---

# Orders, invoices, and payments



Source: https://docs.blazingfast.io/howto/billing/orders-invoices-and-payment-methods



Review orders and invoices, then pay with an available payment method.



## Review the order before you pay

You can browse products, preview pricing, create a draft order, review invoices and transactions, and pay with the supported wallet, card, or crypto options.

[Renewals and refunds](https://docs.blazingfast.io/howto/billing/renewals-upgrades-refunds-and-overdue-lifecycle)
[Earned balance](https://docs.blazingfast.io/howto/affiliate-program/referrals-rewards-and-earned-balance)

# Orders, invoices, and payment methods

The billing flow starts before an invoice is issued. You can browse products, preview pricing, create a draft order, and then move into invoice payment and service activation through the supported checkout paths.

## What customers can do today

- Browse the product catalog and review product pricing.
- Preview order totals before checkout.
- Create draft orders before committing to payment.
- Review wallet balance, invoices, orders, services, and transaction history.
- Pay eligible invoices from wallet balance.
- Use card or crypto checkout where those gateways are enabled for the environment.

## Payment methods in the current platform

- Wallet balance when the invoice is eligible for balance payment.
- Stripe Checkout for card-based payment flows.
- CoinPayments checkout for crypto-based payment flows where it is enabled.

## What the invoice view is for

Invoices show what was ordered, what is due, what has been paid, and what is still outstanding. Billing views also show transaction history and order state, which makes reconciliation easier for your team.

## Drafts and previews

Preview and draft flows are important because they let customers confirm pricing and billing structure before they commit to payment. That is especially useful when the same team is responsible for both infrastructure ordering and invoice approval.

## A clean customer workflow

1. Review the product and pricing.
2. Use preview or draft order flows before final checkout.
3. Confirm who is paying and which payment method is appropriate.
4. Pay the invoice through wallet, card, or crypto as allowed.
5. Keep the invoice and transaction history for your records.

## Practical advice

If one team manages services and another team pays invoices, document that responsibility clearly. Many billing delays happen because ownership is unclear, not because the service is broken.

---

# Renewals, upgrades, and overdue invoices



Source: https://docs.blazingfast.io/howto/billing/renewals-upgrades-refunds-and-overdue-lifecycle



Keep services active and understand renewals, upgrades, refunds, and overdue invoices.



## Keep billing aligned with the service lifecycle

Renewals, upgrades, billing-period changes, wallet autopay, and overdue invoices all affect whether a service continues without interruption.

[Service lifecycle](https://docs.blazingfast.io/howto/services/service-operations-overview)

## Plan ahead

Use renewal, upgrade, billing-change, and autopay controls before a service reaches a deadline. Missed invoices can affect service continuity.

# Renewals, upgrades, refunds, and overdue lifecycle

Once a service is live, billing becomes part of normal service management. The portal shows renewal options, upgrade paths, billing-period changes, autopay settings, and overdue invoice state for supported services.

## What customers can manage

- Renewal options and renewal checkout for supported services.
- Upgrade options and upgrade checkout where the product exposes an upgrade path.
- Billing-period change options and related checkout flows where supported.
- Wallet-based autopay settings on supported services.
- Payment of overdue invoices before enforcement goes further.
- Service cancellation flows where the service type supports customer cancellation.

## Upgrade handling

Where upgrade paths exist, you can review available options and complete checkout for the new tier or resource profile.

## Renewal and billing changes

Renewals are not the same thing as upgrades. Renewals keep the service running on the current plan. Billing changes adjust the billing period or related billing settings on supported services. Keeping these actions separate makes invoices easier to understand later.

## Autopay and wallet behavior

The portal supports autopay from wallet balance on supported services. This can reduce missed renewals, but it still depends on having enough wallet balance at the right time.

## Credits, refunds, and reversals

Refunds and related adjustments should be treated as formal billing events, not silent corrections. The current billing model clearly tracks refunded states, and some cancellation or reversal flows return value to wallet balance instead of hiding the financial change.

## Overdue lifecycle

If an invoice remains unpaid, the service can enter an overdue path that may affect continuity according to policy. Billing ownership matters as much as service ownership because overdue handling is part of the service lifecycle.

## A safer way to run this

- Track due dates and wallet balance as part of service ownership.
- Decide who approves renewals, upgrades, and billing changes before the service reaches a deadline.
- Use checkout flows instead of informal billing changes.
- Escalate disputed invoices early so the service team does not discover billing issues after the service is already at risk.

---

# Manage your services



Source: https://docs.blazingfast.io/howto/services/service-operations-overview



Find the right place to manage each product in your customer portal.



## Start with the service you want to manage

Find a service in the Manage menu, then open its details to review its status, billing and available actions.

[VPS guide](https://docs.blazingfast.io/howto/services/vps-lifecycle-network-access-and-backups)
[Website Protection guide](https://docs.blazingfast.io/howto/services/dns-waf-and-proxy-management)
[Dedicated server guide](https://docs.blazingfast.io/howto/services/manage-dedicated-server)
[TCP Proxy guide](https://docs.blazingfast.io/howto/services/manage-tcp-proxy)
[Domains guide](https://docs.blazingfast.io/howto/services/domains-and-dns-zone-operations)
[Storage guide](https://docs.blazingfast.io/howto/services/storage-volumes-backups-and-object-roadmap)

# Service operations overview

Open the **Manage** menu and select the type of service you want to use. Open a service card to review its status, IP addresses where applicable, billing and available actions.

## Dedicated servers

[Manage a dedicated server](https://docs.blazingfast.io/howto/services/manage-dedicated-server): check installation progress, power, IP addresses, compatible operating systems, rescue mode and task history.

## TCP Proxy

[Manage TCP Proxy](https://docs.blazingfast.io/howto/services/manage-tcp-proxy): review the proxy IP, backend, port mappings, traffic and source access settings.

## VPS compute

- Order VPS services through the normal product and billing flow.
- Check runtime status, power state, uptime, and basic usage metrics.
- Start, stop, reboot, reinstall, reset the root password, and update the applied SSH key.
- Manage snapshots and backup operations for supported services.
- Apply firewall policies and review service identifiers and assigned network details.

## DNS and service protection

- Create and manage DNS zones.
- Use templates, simple record editing, raw zone-style changes, or rrset updates depending on the task.
- For eligible services, check DNS/WAF status, toggle proxy mode or protection, run origin sync, and manage proxy settings such as SSL mode or custom loader behavior.
- Upload or inspect custom SSL material where that protected-record workflow is enabled.

## Domains

- Search domains, check availability, and review TLD pricing.
- Order new registrations or transfers through the customer order flow.
- Review domain status, transfer state, and authorization-code related actions.
- Manage nameservers, contact assignments, and WHOIS privacy or lock settings where supported by the registry and TLD.

## Storage

- Use backups today for supported VPS services, including schedule, run, restore, cancel, and cleanup actions.
- Manage provisioned storage volume services by listing them, checking eligible attach targets, and performing attach, detach, or rename operations.
- Treat object storage as planned until customer documentation is available.

## cPanel web hosting

[Use cPanel web hosting](https://docs.blazingfast.io/howto/services/manage-web-hosting) for website, mail and PHP administration. Public automation currently covers generic hosting service and billing information, not cPanel administration.

## Operational building blocks

- SSH key management is available in the portal: import, generate, export, rename, delete, and set a primary key.
- Firewall policy management is available in the portal: create policies, update rules, choose a primary policy, and apply a policy to a VPS.

## How to use this section

1. Start with the product article that matches the service you already own.
2. Use the API reference when you need endpoint-level behavior, scopes, or request formats.
3. Treat planned features carefully. If the guide says a feature is planned, do not build production workflows around it yet.

---

# Manage a VPS



Source: https://docs.blazingfast.io/howto/services/vps-lifecycle-network-access-and-backups



Control power, access, reinstall, snapshots, backups, and firewall settings.



## Manage the full VPS lifecycle from one place

After a VPS is provisioned, you can check status, control power state, recover access, change SSH keys, manage snapshots and backups, reinstall the server, and apply firewall policies.

[Service credentials](https://docs.blazingfast.io/howto/account/service-credentials-console-and-vm-operations)

## First troubleshooting step

Check whether the VPS is still provisioning before treating it as an outage. A service that is not finished provisioning needs a different response than a running service with a network problem.

# VPS lifecycle, network access, and backups

After a VPS is provisioned, you can track its state, change power state, recover access, update SSH keys, and manage snapshots or backups from the portal.

## What customers can do today

- Check VPS runtime status, power state, uptime, CPU, memory, and network counters.
- Start, stop, and reboot a VPS.
- Reset the root password and receive the new password once.
- Reinstall with a supported operating system selection and optionally specify hostname, SSH key, or firewall policy.
- Update the VPS SSH key after provisioning.
- List, create, roll back, and delete snapshots.
- View backup state, configure backup schedules, run backups, cancel running backup jobs, delete backup files, and restore from backup.
- Review and apply the effective firewall policy for the service.

## What to check first after provisioning

1. Confirm the service status is active.
2. Confirm the expected IP assignment is present in the service details.
3. Confirm the access path you plan to use first: SSH key, password, or console workflow.
4. Confirm whether backup coverage is already enabled for that workload.

## How to think about recovery features

Snapshots and backups solve different problems. Snapshots are useful around short-lived change windows. Backups are the recovery mechanism you should plan around for service loss, rollback, or scheduled protection.

## Practical operating advice

1. Record the service ID, host or IP details, and owner.
2. Set the SSH key and firewall policy before the VPS becomes a shared production dependency.
3. Use snapshot actions before risky maintenance.
4. Treat backup schedule review as part of service acceptance, not as an afterthought.

---

# Manage a dedicated server



Source: https://docs.blazingfast.io/howto/services/manage-dedicated-server



Check installation progress, IP addresses, power, operating systems and task history.



Open [Manage → Dedicated servers](https://my.blazingfast.io/manage/dedicated) and select your server. Actions depend on its current state and your account or project permissions.

## Check the server before changing it

Review the hostname, IP addresses, installed operating system when available, power state, installation progress and paid-through date. A service can be active for billing while its server is still installing or powered off; these are different states.

For a new order, check its invoice first. An unpaid order is not an installed server. After payment and any required review, follow the installation progress on the service page. Do not restart or reinstall repeatedly while an installation is in progress.

## Power controls

Confirm the intended server and save your work before using a power action. Start brings a powered-off server online. Stop and restart interrupt running applications and connections. Wait for the returned action to finish, then refresh the status.

## Reinstall an operating system

Reinstallation erases data on the server's disks. It is not a reboot.

1. Back up anything you need and verify the backup can be restored.
2. Open the server's reinstall action and select an operating system from its compatible options.
3. Review the hostname and supported access options, such as an SSH key already saved on your account.
4. Confirm the target and the erase warning.
5. Track installation progress and task history. Use the newly installed operating system's access details after completion.

Do not choose an OS profile from a different server or guess an installation code. Compatible images can differ by server.

## Rescue and recovery

Rescue boots a temporary maintenance environment. It interrupts applications, but does not itself reinstall the operating system. Select a supported rescue image and follow the service's instructions to return to normal boot when maintenance is finished.

Use password reset only when needed, and retrieve its result privately. Do not paste service passwords or private keys into an AI conversation.

## Billing and termination

Review billing settings and invoices from the service details. Termination is different from stopping a server: it ends the service and releases its allocated resources after cleanup. Back up your data and read the confirmation carefully before requesting it.

## If an action stalls

Check the latest task and installation status before retrying. An accepted request is not proof that installation completed. Contact support with the service identifier, task reference, time/timezone and visible error; do not send passwords or API secrets.

For automation, see [API, SDKs and AI assistants](https://docs.blazingfast.io/howto/api/api-overview-related-guides-and-next-steps).

---

# Use cPanel web hosting



Source: https://docs.blazingfast.io/howto/services/manage-web-hosting



Find hosting access, manage websites and email in cPanel, and understand automation limits.



Open [Manage → Web hosting](https://my.blazingfast.io/manage/web) and select your hosting service. Review its service status, hosting access and billing details before making changes.

## Websites and email

Use the offered cPanel access to manage website files, databases, email accounts, domains and supported PHP settings. Features, quotas, PHP versions and extensions depend on your selected plan and hosting node; check cPanel rather than assuming all nodes are identical.

Before changing PHP or application files, check your application's requirements and keep a restorable copy. A server-side error can come from the application, permissions, PHP version or missing extensions; report the domain, time and visible error to support without sending passwords.

## DNS and Website Protection

Domain registration, DNS zones and hosting are separate resources. Confirm the domain points to the intended hosting service. An external DNS provider remains authoritative until its registrar delegation is changed. Proxy/protection settings do not replace cPanel website configuration.

## Automation

The public API exposes the hosting service through generic service and billing endpoints. The CLI can inspect it with `bf-api service show SERVICE_UUID`; hosted MCP uses `get_service`, and local MCP uses `bf_service_show`.

There is no customer cPanel-administration endpoint in this API. Do not assume that these tools can create mailboxes, modify website files or change PHP modules. Use cPanel for those tasks. Product ordering support must be checked from the returned order options; use dashboard checkout if configuration is unsupported.

See the [product coverage matrix](https://docs.blazingfast.io/howto/api/product-automation-coverage) and [plain-text hosting brief](https://docs.blazingfast.io/docs/products/03-web-hosting.txt).

---

# Manage DNS and website protection



Source: https://docs.blazingfast.io/howto/services/dns-waf-and-proxy-management



Manage DNS records, proxying, website protection, origins, and SSL settings.



## Know whether you are changing DNS or protection settings

DNS records and protected-record settings are related, but they are different controls. This guide helps you choose the right place to make each change.

[Domains and DNS zones](https://docs.blazingfast.io/howto/services/domains-and-dns-zone-operations)

# DNS, WAF, and proxy management

This area combines DNS zone management with service-level proxy and protection actions. DNS records and protection settings are related, but they are not the same workflow.

## DNS capabilities available now

- Create, view, and delete DNS zones.
- Use DNS templates when you want a repeatable starting point.
- Manage records through simple record helpers or lower-level rrset updates.
- Read or update raw zone content when a full zone-file style workflow is the right fit.

## Service protection capabilities available now

- Check whether a specific service is eligible for DNS proxy or WAF-related actions.
- Read the current protected-record state for a service-scoped record.
- Toggle proxy mode for that record.
- Toggle protection for that record.
- Run origin sync so the protected record follows the service's current origin IP.
- Read and change supported proxy settings such as SSL mode, force SSL, or custom loader behavior.
- View or upload SSL material and custom loader content where that protected-record workflow is enabled.

## What this does not cover

The portal exposes record-level protection and proxy configuration. It is not a general custom WAF rule builder, so incident runbooks should be based on the controls that are actually available here.

## Operating guidance

- Decide whether a change belongs in DNS, in the protected record configuration, or in the origin service itself before you touch production traffic.
- Use templates for repeated DNS layouts.
- Re-run origin sync after service rebuilds, migrations, or IP changes.
- Treat custom SSL or loader uploads as controlled changes with rollback notes.

---

# Manage TCP Proxy



Source: https://docs.blazingfast.io/howto/services/manage-tcp-proxy



Configure your backend and ports, review traffic, and change access rules safely.



TCP Proxy forwards connections from your service's public proxy IP and listening ports to an IPv4 backend. It is separate from DNS-record Website Protection.

Open [Manage → TCP Proxy](https://my.blazingfast.io/manage/tcp-proxy), select a service, and review its Overview before editing Configuration.

## Set a backend and port mapping

1. Confirm your application is running and reachable on the intended backend IPv4 address and port.
2. In Configuration, set the default backend IP.
3. Add a listening port and its backend port. A mapping such as 443 → 8443 forwards traffic arriving on proxy port 443 to backend port 8443.
4. Use a per-port backend override only when that port must route to a different IPv4 address.
5. Review the complete configuration, save it, and test the public proxy IP and port from an authorized client.

Do not expose backend administration ports unintentionally. Enable PROXY protocol v2 only if the backend application supports it; otherwise connections may fail.

## Port entitlement and limits

Your service shows its configured and available ports. Adding a mapping does not purchase additional ports. Use the offered port-upgrade checkout when more paid ports are needed, and review its price before ordering.

Connection and packet limits can reduce unwanted traffic, but overly restrictive values can block legitimate clients. Read the existing configuration, change only what you intend, and test after saving.

## Source and country access rules

Review allowed and blocked source CIDRs and country rules before changing them. Keep the access required by your users, monitoring and management tools. Country rules use two-letter country codes and the modes disabled, allow or block.

When using the API, supplied arrays replace the full existing array; omitted fields remain unchanged. A replacement that omits an existing allow rule may remove access. Read back the saved configuration and verify connectivity.

## Interpret traffic statistics

Stats shows traffic and observed events for a selected time window. Byte totals are not an instantaneous transfer rate, and observed connection events are not a count of currently open connections. Missing data means unavailable, not zero.

## If connections fail

Check the proxy IP and listening port, backend address and port, backend firewall, source/country rules and per-port limits. Confirm the application accepts the configured protocol. Review one change at a time rather than repeatedly replacing the complete policy.

For automation, see [DNS, Website Protection and TCP Proxy](https://docs.blazingfast.io/howto/api/dns-and-protection-automation).

---

# Domains and nameservers



Source: https://docs.blazingfast.io/howto/services/domains-and-dns-zone-operations



Register or transfer domains and manage contacts, nameservers, and DNS zones.



## Domains affect more than branding

Your domain choices influence billing, renewal timing, DNS changes, certificates, and how quickly a public service can go live.

[DNS and WAF controls](https://docs.blazingfast.io/howto/services/dns-waf-and-proxy-management)

## What the customer flow covers

The portal covers discovery, ordering, nameserver changes, contact management, transfer-sensitive actions, and DNS settings where the registry and TLD allow it.

Open **Manage → Domains** for registration, renewal, contacts, nameservers, lock, privacy and DNSSEC. Open **Manage → DNS** for DNS records. They are different resources even when the domain is registered with us.

## Register, transfer or renew

Search availability and review the TLD's allowed periods, price and required contact information. Select the offered DNS starting point and check the order before paying. An available name is not reserved by a search.

For an existing domain, use **Renew** when offered. It creates a renewal invoice; payment dispatches the eligible renewal. Confirm the resulting expiry rather than assuming a paid invoice already proves registrar completion. After a timeout, check the existing order and domain before requesting another renewal.

## Nameservers and DNS changes

The registrar's nameservers determine which DNS provider is authoritative. Creating a zone here does not switch delegation automatically. Changing Website Protection settings is not the same as changing live DNS records.

If the DNS page detects our legacy ns1/ns2 nameservers, review the panel's records and use **Fix nameservers** to switch to dns1/dns2 when eligible. Other legacy records are not copied. A successful registrar update may need time to propagate; do not repeatedly submit it while waiting.

## DNSSEC

Use the **DNSSEC** tab on the registered domain, not the DNS-service page. When the TLD and domain state permit activation, review the enabled/disabled status and use the offered action.

For our hosted DNS, activation prepares zone signing and submits its public key for parent delegation. For external DNS, enable signing with that provider first and supply its public KSK/CSK DNSKEY when requested: flags 257, protocol 3, supported algorithm and public key. Never submit a private key or add an apex DS record to your own zone.

Enabling/disabling may run in the background; follow its saved status and any offered status check instead of repeating the request. Registrar status does not independently prove parent propagation. When disabling, keep external signing enabled until the parent DS and cached copies expire.

### Public API and automation

Registered-domain DNSSEC is available through the public HTTP API. Domain registration and DNS hosting are separate resources: use your registered-domain service UUID or domain name, not a DNS-zone ID. Read GET /v1/domains/{serviceId}/dnssec with domains.read. A saved status is not a new registrar check.

| POST action | Scope | JSON body | Retry key | Success |
| --- | --- | --- | --- | --- |
| refresh | domains.read | {"action":"refresh"} | Not required | HTTP 200 current or ongoing state |
| enable, managed DNS | domains.write | {"action":"enable","mode":"managed","acknowledge":true} | Required | HTTP 202 accepted |
| enable, external DNS | domains.write | action=enable, mode=external, acknowledge=true, keys | Required | HTTP 202 accepted |
| disable | domains.write | {"action":"disable","acknowledge":true} | Required | HTTP 202 accepted |

External keys are 1–4 public DNSKEY records with flags=257, protocol=3, alg in 8/10/13/14/15/16 and Base64 pub_key. Never submit private DNSSEC keys. Algorithm and TLD support must be discovered; unsupported or unknown support is an error. Managed enable also requires your ready, unlocked DNS zone. Check support, dnsProvider, canEnable and canDisable before requesting changes. Changes require an active registration.

For enable/disable, Idempotency-Key is 8–128 letters/digits/._:-. Reuse the original key with the exact payload after interruption. HTTP 202 means accepted, not completed. Poll GET on the same DNSSEC endpoint with domains.read and inspect operation, status and errorCode. operationId is a DNSSEC UUID, not a /v1/operations handle. pending/queued/running are ongoing; unconfirmed requires reconciliation and failed is not success. Use refresh to reconcile when appropriate rather than submitting a new write key. idle with the intended registrar_configured/not_configured status confirms registrar configuration; delegationStatus=not_verified means parent propagation has not been verified. Disable removes registrar delegation without deleting signing keys: retire delegation safely before deleting a signed zone.

SDK/CLI 0.1.17 includes domain_dnssec/domain_dnssec_update in Python, Node.js and PHP, and DomainDNSSEC/DomainDNSSECUpdate in Go. Python read: client.domain_dnssec("example.com"); refresh: client.domain_dnssec_update("example.com", {"action":"refresh"}). Enable/disable use the stable idempotency key argument.

CLI (replace DOMAIN_SERVICE_UUID with your registered domain):

```bash
bf domain dnssec show DOMAIN_SERVICE_UUID
bf domain dnssec check DOMAIN_SERVICE_UUID
bf domain dnssec enable DOMAIN_SERVICE_UUID --mode managed --confirm --request-key dnssec-enable-001
bf domain dnssec enable DOMAIN_SERVICE_UUID --mode external --keys-file dnskeys.json --confirm --request-key dnssec-external-001
bf domain dnssec disable DOMAIN_SERVICE_UUID --confirm --request-key dnssec-disable-001
```

External dnskeys.json contains only the public DNSKEY array. These writes require an explicit request key, unlike commands that generate an omitted key.

Local MCP: bf_domain_dnssec and bf_domain_dnssec_check; bf_domain_dnssec_update requires BF_API_MCP_ENABLE_MUTATIONS=1, acknowledge=true and request_key. Hosted MCP has no DNSSEC tool; do not invent one.

## Contacts and transfers

Keep registration contacts current and complete required email verification. Lock/privacy availability depends on the TLD. Transfer authorization codes are secrets; retrieve them privately and do not paste them into an AI conversation.

See [automation coverage](https://docs.blazingfast.io/howto/api/product-automation-coverage) for the available domain tools.

---

# Storage volumes and backups



Source: https://docs.blazingfast.io/howto/services/storage-volumes-backups-and-object-roadmap



Attach storage, manage backup capacity, and understand what each storage type is for.



## Choose the right storage feature for the job

Use backups for recovery. Use storage volumes when you need persistent capacity attached to a workload. Object storage is still planned and should not be treated as generally available yet.

[VPS and backups](https://docs.blazingfast.io/howto/services/vps-lifecycle-network-access-and-backups)

## Availability note

Backups and provisioned storage volumes are available today. Object storage remains planned until it is documented as available.

# Storage volumes, backups, and planned object storage

Storage has two main workflows available today: backups for supported VPS services, and provisioned storage volumes that can be attached to workloads. Object storage is still planned.

## Available now: VPS backup operations

- View backup state for a supported VPS.
- Configure backup schedule settings.
- Start or cancel backup runs.
- Track backup progress and restore progress.
- Restore from backup.
- Delete backup files when cleanup is required.

## Available now: provisioned storage volumes

- List storage volume services assigned to your account.
- Check which VPS services are eligible attach targets.
- Attach a detached volume to a VPS.
- Detach a volume from its current VPS.
- Rename volume metadata for clearer ownership and purpose.

## Planned

- Volume growth and additional storage options should be treated as release-specific until they are documented.
- Object storage is planned and is not yet a documented generally available customer workflow.

## How to choose the right storage feature

- Use backups when the goal is recovery.
- Use volume services when the goal is persistent capacity that can move with the workload lifecycle.
- Use an external object store today if your application already depends on object-storage behavior.

## Customer expectation setting

Use the feature that matches the job. Backups are for recovery. Volumes are for attached capacity. Planned object storage should not be used in production plans until it is available.

---

# Affiliate links and rewards



Source: https://docs.blazingfast.io/howto/affiliate-program/referrals-rewards-and-earned-balance



Share your link and track visits, customers, purchases, and rewards.



## Track referrals and rewards in the portal

You get a personal referral code, a shareable link, and a clear view of referrals, paying referrals, affiliate funds, and recent reward activity.

[Billing and balance](https://docs.blazingfast.io/howto/billing/orders-invoices-and-payment-methods)

# Referrals, rewards, and earned balance

The affiliate program gives you a referral code, a shareable link, referral statistics, affiliate funds, and recent reward history so you can see whether attribution worked.

## What the customer can see

- A personal referral link that can be copied or shared.
- Total referral count.
- Paying referral count.
- Cumulative commission.
- Recent reward history, including invoice or order references where available.

## Reward behavior

When a referred customer completes payable activity, the reward is credited into earned balance or account credit. If the underlying transaction is later reversed or refunded, the history can reflect that as a matching reversal event.

The customer UI also makes it clear that attribution begins when a visitor arrives through the referral link and the platform stores the referral marker before signup.

## How to use it well

- Treat affiliate rewards as credits tied to customer activity, not as guaranteed future cash flow.
- Use the recent reward list to reconcile notable changes.
- Keep referral ownership aligned with the account that should receive the rewards.

## Practical boundary

Affiliate information is currently managed through the customer portal. Use the portal views for referral accounting unless a public affiliate API is added later.
