{"openapi":"3.1.0","info":{"title":"Hosting API","version":"2.3.2","summary":"The hosting.com account API: services, billing, domains, websites, email, servers and support, for the CLI, for scripts and for AI agents over MCP.","description":"The hosting.com account API. Everything here acts on one account, the one behind the bearer token, and reaches the account service, the hosting control panel and the email control panel as that customer; no request can touch another account.\n\n**Signing in.** A CLI or a script signs in with `POST /v1/auth/login` (and `POST /v1/auth/mfa` when the account has a second factor), keeps the refresh token, and rotates the pair with `POST /v1/auth/refresh` before the access token expires. A Connector (Claude, ChatGPT, an MCP client) signs in through the OAuth authorization code flow starting at `/oauth/authorize`, discovered from `/.well-known/oauth-authorization-server`, and then talks to `POST /mcp`, where every operation below is also a tool.\n\n**Reading and writing.** Reads are `GET`. Every change is a `POST` carrying its arguments in a JSON body, because each one runs something at a registrar, on the hosting or on the email service; a delete repeats what it removes (`confirm_domain`, `confirm_address`) as the caller's confirmation. Lists take `limit` and `offset` and answer `total`.\n\n**Errors.** Every failure is `{\"error\", \"error_description\"}`: a stable code and a sentence. `401` is the bearer, `403` a scope, client or consent the connection lacks, `404` a thing not on this account, `409` a change already in progress on the same target or a file that changed since it was read, `413` a file or request over the size the file routes carry, `422` a field that did not validate or a change the upstream refused (`rejected`, `not_confirmed`, `not_supported`), `429` a rate limit with `Retry-After`, `502`/`503` an upstream fault or outage.\n\n**The contract.** `/v1` is versioned by prefix: fields are only ever added. Detail records are shaped here, never relayed from an upstream, and no body names an upstream vendor or carries an upstream credential."},"servers":[{"url":"https://staging-api.hosting.com","description":"This host"}],"tags":[{"name":"Ops","description":"The liveness probe."},{"name":"Auth","description":"Signing in as the first-party CLI does: a token pair from an email address and password, a second factor when the account has one, refresh and sign-out. Connectors sign in through the OAuth flow instead."},{"name":"Account","description":"The account behind the bearer, its profile and its services."},{"name":"Billing","description":"Invoices, orders, saved payment methods and credit, and paying an invoice."},{"name":"Domains","description":"The account's domain registrations, availability search and the registrar functions on a domain."},{"name":"Websites","description":"Websites on the account's hosting and managed WordPress, reached on each platform as the customer: sites, shell access, applications, runtime, databases, mapped domains, certificates, and the site features only managed WordPress has. Every row carries platform."},{"name":"Mwp","description":"Managed WordPress plans: the plans an account holds, their usage and limits, the data centres a site can be built in, and building a site. The sites themselves are websites."},{"name":"Email","description":"The account's email services, reached on the email control panel as the customer: mailboxes, forwarders, DNS, DKIM and the catch-all."},{"name":"Servers","description":"The account's unmanaged servers, reached on the server management service as the customer: power, console, reverse DNS, hostname, usage, backups and reinstalling the operating system."},{"name":"Support","description":"Support tickets and their conversations, read only."},{"name":"Sessions","description":"The account's live sessions, for the first-party CLI."},{"name":"OAuth","description":"Discovery, registration, token and revocation endpoints for Connectors (Claude, ChatGPT and other MCP clients). The browser part of the flow starts at /oauth/authorize."},{"name":"MCP","description":"The Model Context Protocol server: every operation of this API as a tool for an AI client."}],"paths":{"/health":{"get":{"operationId":"health","tags":["Ops"],"summary":"Liveness probe","description":"Answers that this release is serving requests, and which release it is. Shallow on purpose: no database, cache or upstream call is made, so a dependency outage never reads as a dead node. Exempt from the per-client rate limit and from maintenance mode.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The release serving requests.","properties":{"status":{"type":"string","description":"Always ok.","enum":["ok"]},"version":{"type":"string","description":"The deployed release, the git tag without its v; dev outside a deployment."}},"required":["status","version"],"additionalProperties":false}}}}},"security":[]}},"/.well-known/oauth-authorization-server":{"get":{"operationId":"oauth_authorization_server_metadata","tags":["OAuth"],"summary":"Authorization server metadata","description":"RFC 8414 discovery for the Connector OAuth flow: the authorize, token, registration and revocation endpoints, the one scope, PKCE with S256 only, and that clients may identify themselves by a Client ID Metadata Document URL. Cacheable for five minutes.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"RFC 8414 authorization server metadata.","properties":{"issuer":{"type":"string","description":"This server.","format":"uri"},"authorization_endpoint":{"type":"string","description":"Where the browser part of the flow starts.","format":"uri"},"token_endpoint":{"type":"string","description":"POST /oauth/token.","format":"uri"},"registration_endpoint":{"type":"string","description":"POST /oauth/register.","format":"uri"},"revocation_endpoint":{"type":"string","description":"POST /oauth/revoke.","format":"uri"},"response_types_supported":{"type":"array","description":"code.","items":{"type":"string"}},"response_modes_supported":{"type":"array","description":"query.","items":{"type":"string"}},"grant_types_supported":{"type":"array","description":"authorization_code and refresh_token.","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","description":"S256 only.","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","description":"How a client authenticates at the token endpoint.","items":{"type":"string"}},"revocation_endpoint_auth_methods_supported":{"type":"array","description":"How a client authenticates at the revocation endpoint.","items":{"type":"string"}},"scopes_supported":{"type":"array","description":"The one scope, mcp:use.","items":{"type":"string"}},"client_id_metadata_document_supported":{"type":"boolean","description":"true: a client may identify itself by the URL of its metadata document."}},"required":["issuer","authorization_endpoint","token_endpoint","registration_endpoint","revocation_endpoint","response_types_supported","response_modes_supported","grant_types_supported","code_challenge_methods_supported","token_endpoint_auth_methods_supported","revocation_endpoint_auth_methods_supported","scopes_supported","client_id_metadata_document_supported"],"additionalProperties":false}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/.well-known/oauth-protected-resource":{"get":{"operationId":"oauth_protected_resource_metadata","tags":["OAuth"],"summary":"Protected resource metadata","description":"RFC 9728 metadata for the MCP resource: which authorization server issues its tokens, the scope it needs and that the bearer travels in the Authorization header. Cacheable for five minutes.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"RFC 9728 protected resource metadata.","properties":{"resource":{"type":"string","description":"The MCP resource these tokens are for.","format":"uri"},"authorization_servers":{"type":"array","description":"The authorization servers that issue its tokens: this host.","items":{"type":"string","format":"uri"}},"scopes_supported":{"type":"array","description":"The one scope, mcp:use.","items":{"type":"string"}},"bearer_methods_supported":{"type":"array","description":"header: the bearer travels in the Authorization header.","items":{"type":"string"}}},"required":["resource","authorization_servers","scopes_supported","bearer_methods_supported"],"additionalProperties":false}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/.well-known/oauth-protected-resource/mcp":{"get":{"operationId":"oauth_protected_resource_metadata_mcp","tags":["OAuth"],"summary":"Protected resource metadata (MCP path)","description":"The same RFC 9728 document under the path-specific location an MCP client derives from the resource URL.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"RFC 9728 protected resource metadata.","properties":{"resource":{"type":"string","description":"The MCP resource these tokens are for.","format":"uri"},"authorization_servers":{"type":"array","description":"The authorization servers that issue its tokens: this host.","items":{"type":"string","format":"uri"}},"scopes_supported":{"type":"array","description":"The one scope, mcp:use.","items":{"type":"string"}},"bearer_methods_supported":{"type":"array","description":"header: the bearer travels in the Authorization header.","items":{"type":"string"}}},"required":["resource","authorization_servers","scopes_supported","bearer_methods_supported"],"additionalProperties":false}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/oauth/token":{"post":{"operationId":"oauth_token","tags":["OAuth"],"summary":"Token endpoint","description":"RFC 6749 token endpoint for Connectors: exchanges an authorization code (with its PKCE verifier) for a token pair, or rotates a pair with a refresh token. Form-encoded. Public clients send client_id alone; confidential clients authenticate with their secret. The refresh token is single-use with a short grace period; a reuse beyond it closes the whole session family.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"],"description":"Which exchange this is."},"client_id":{"type":"string","description":"The registered client id, or the Client ID Metadata Document URL."},"client_secret":{"type":"string","description":"Confidential clients only."},"code":{"type":"string","description":"The authorization code (grant_type authorization_code)."},"redirect_uri":{"type":"string","description":"The redirect URI the code was issued to.","format":"uri"},"code_verifier":{"type":"string","description":"The PKCE verifier for the S256 challenge sent at authorization."},"refresh_token":{"type":"string","description":"The refresh token to rotate (grant_type refresh_token)."},"resource":{"type":"string","description":"RFC 8707 resource indicator; must be this server's MCP resource when given.","format":"uri"}},"required":["grant_type","client_id"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"An RFC 6749 token response. Store the refresh token; the access token expires after expires_in seconds.","properties":{"token_type":{"type":"string","description":"Always Bearer.","enum":["Bearer"]},"expires_in":{"type":"integer","description":"Seconds until the access token expires."},"access_token":{"type":"string","description":"The bearer to send as Authorization: Bearer on every /v1 and /mcp request."},"refresh_token":{"type":"string","description":"Rotated on every refresh; the previous one stays valid for a short grace period only."}},"required":["token_type","expires_in","access_token","refresh_token"],"additionalProperties":false}}}},"400":{"description":"`invalid_request`: A parameter is missing or malformed.\n`invalid_grant`: The code or refresh token is unknown, expired, already used past its grace period, or the session family is closed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_request","invalid_grant"]}}}]}}}},"401":{"description":"`invalid_client`: Client authentication failed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_client"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/oauth/register":{"post":{"operationId":"oauth_register_client","tags":["OAuth"],"summary":"Register a client","description":"RFC 7591 dynamic client registration for Connectors that do not identify themselves by URL. Redirect URIs must be on the allowlist of known Connector hosts. Rate-limited per address. The client secret, when one is issued, appears in this response only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string","description":"A display name; defaults to the server's default client name."},"redirect_uris":{"type":"array","items":{"type":"string","format":"uri"},"description":"https URIs on an allowlisted Connector host, or loopback."},"token_endpoint_auth_method":{"type":"string","enum":["none","client_secret_basic","client_secret_post"],"description":"none for a public client (the default)."},"grant_types":{"type":"array","items":{"type":"string","enum":["authorization_code","refresh_token"]},"description":"authorization_code, refresh_token."},"response_types":{"type":"array","items":{"type":"string","enum":["code"]},"description":"code."},"scope":{"type":"string","description":"Space-separated; only mcp:use and offline_access exist."}},"required":["redirect_uris"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"RFC 7591 client information.","properties":{"client_id":{"type":"string","description":"The client id to send at the authorization and token endpoints."},"client_id_issued_at":{"type":"integer","description":"Unix time."},"client_secret":{"type":["string","null"],"description":"Confidential clients only; shown once."},"client_secret_expires_at":{"type":["integer","null"],"description":"0: the secret does not expire."},"client_name":{"type":"string","description":"The display name registered."},"redirect_uris":{"type":"array","description":"The redirect URIs registered.","items":{"type":"string"}},"grant_types":{"type":"array","description":"The grant types registered.","items":{"type":"string"}},"response_types":{"type":"array","description":"The response types registered.","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string","description":"How the client authenticates at the token endpoint."},"scope":{"type":"string","description":"The scopes registered."}},"required":["client_id","client_id_issued_at","client_secret","client_secret_expires_at","client_name","redirect_uris","grant_types","response_types","token_endpoint_auth_method","scope"],"additionalProperties":false}}}},"400":{"description":"`invalid_redirect_uri`: A redirect URI is not https on an allowlisted host.\n`invalid_client_metadata`: A metadata value is not one this server supports.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_redirect_uri","invalid_client_metadata"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: Too many registrations from this address.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/oauth/revoke":{"post":{"operationId":"oauth_revoke_token","tags":["OAuth"],"summary":"Revoke a token","description":"RFC 7009 revocation: ends the whole session family behind a refresh or access token issued to the authenticating client. Form-encoded. Answers 200 whatever the token was, so nothing is learned about tokens the client does not hold.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The refresh or access token to revoke."},"token_type_hint":{"type":"string","enum":["refresh_token","access_token"],"description":"Which kind the token is, when known."},"client_id":{"type":"string","description":"The client the token was issued to."},"client_secret":{"type":"string","description":"Confidential clients only."}},"required":["token","client_id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"`invalid_request`: The token parameter is missing.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_request"]}}}]}}}},"401":{"description":"`invalid_client`: Client authentication failed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_client"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/mcp":{"post":{"operationId":"mcp","tags":["MCP"],"summary":"MCP endpoint","description":"The Model Context Protocol server over Streamable HTTP, for AI clients (Claude, ChatGPT and agents): every operation of this API as a tool, with the same arguments and results. JSON-RPC 2.0 in the body, a bearer with the mcp:use scope, and an Accept header of application/json, text/event-stream. The server never opens a stream and keeps no session, so GET and DELETE on this path answer 405; initialize, tools/list, tools/call and prompts/list are the methods it serves. A missing or rejected bearer is answered with WWW-Authenticate naming the protected resource metadata.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","enum":["2.0"],"description":"Always 2.0."},"id":{"type":["integer","string"],"description":"The request id, echoed in the response."},"method":{"type":"string","description":"initialize, tools/list, tools/call, prompts/list, prompts/get."},"params":{"type":"object","description":"The method's parameters.","additionalProperties":true}},"required":["jsonrpc","id","method"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A JSON-RPC 2.0 response: result for a served call, error for a protocol failure. Tool refusals the model can act on are 200 results with isError true; upstream outages and closed sessions leave as HTTP statuses.","properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["integer","string"]},"result":{"type":"object","additionalProperties":true},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}},"required":["jsonrpc","id"]}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"405":{"description":"`method_not_allowed`: GET and DELETE: the server opens no stream and holds no session.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["method_not_allowed"]}}}]}}}},"406":{"description":"`not_acceptable`: The Accept header does not name both application/json and text/event-stream.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_acceptable"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/auth/login":{"post":{"operationId":"login","tags":["Auth"],"summary":"Sign in","description":"Signs in with the account's email address and password, as the first-party CLI does. Answers a token pair when the account has no second factor, else an MFA challenge to complete with POST /v1/auth/mfa. When a second factor is required, provider is totp (the authenticator app) or email (a code sent to the account email) and instruction says where to find the code. Throttled per address and per account; nothing about the upstream account service leaves in the body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","description":"The account's email address."},"password":{"type":"string","maxLength":1024,"description":"The account's password; never echoed back."}},"required":["email","password"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"An RFC 6749 token response. Store the refresh token; the access token expires after expires_in seconds.","properties":{"token_type":{"type":"string","description":"Always Bearer.","enum":["Bearer"]},"expires_in":{"type":"integer","description":"Seconds until the access token expires."},"access_token":{"type":"string","description":"The bearer to send as Authorization: Bearer on every /v1 and /mcp request."},"refresh_token":{"type":"string","description":"Rotated on every refresh; the previous one stays valid for a short grace period only."}},"required":["token_type","expires_in","access_token","refresh_token"],"additionalProperties":false},{"type":"object","description":"A second factor is required: complete the challenge within expires_in seconds. provider and instruction say whether the code is in an authenticator app or was emailed.","properties":{"mfa_required":{"type":"boolean","description":"Always true.","enum":[true]},"challenge_id":{"type":"string","description":"The challenge to complete with POST /v1/auth/mfa."},"provider":{"type":"string","description":"Where the code is: totp is the authenticator app; email is a code sent to the account email.","enum":["totp","email"]},"instruction":{"type":"string","description":"Where to find the code, in the same words as the customer panel."},"expires_in":{"type":"integer","description":"Seconds the challenge stays open."}},"required":["mfa_required","challenge_id","provider","instruction","expires_in"],"additionalProperties":false}],"description":"A token pair, or the second-factor challenge to complete first."}}}},"401":{"description":"`invalid_credentials`: The email address or password is incorrect.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_credentials"]}}}]}}}},"403":{"description":"`forbidden`: The account has an IP allowlist that does not include this service. Add it in the account security settings or remove the allowlist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["forbidden"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: Too many sign-in attempts; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}}},"security":[]}},"/v1/auth/mfa":{"post":{"operationId":"complete_mfa","tags":["Auth"],"summary":"Complete a second factor","description":"Completes the MFA challenge a sign-in opened and answers the token pair. Use the code from the authenticator app when login answered provider totp, or the code emailed to the account when it answered email. A challenge allows a limited number of attempts and expires; sign in again for a new one.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"challenge_id":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"The challenge the sign-in answered."},"code":{"type":"string","maxLength":64,"description":"The second-factor code: from the authenticator app when login answered provider totp, or from the email sent to the account when it answered email."}},"required":["challenge_id","code"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"An RFC 6749 token response. Store the refresh token; the access token expires after expires_in seconds.","properties":{"token_type":{"type":"string","description":"Always Bearer.","enum":["Bearer"]},"expires_in":{"type":"integer","description":"Seconds until the access token expires."},"access_token":{"type":"string","description":"The bearer to send as Authorization: Bearer on every /v1 and /mcp request."},"refresh_token":{"type":"string","description":"Rotated on every refresh; the previous one stays valid for a short grace period only."}},"required":["token_type","expires_in","access_token","refresh_token"],"additionalProperties":false}}}},"401":{"description":"`invalid_code`: The code is incorrect.\n`invalid_challenge`: The challenge is unknown, expired or closed. Sign in again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_code","invalid_challenge"]}}}]}}}},"403":{"description":"`forbidden`: The account has an IP allowlist that does not include this service. Add it in the account security settings or remove the allowlist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["forbidden"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: Too many attempts on this challenge.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"503":{"description":"`mfa_unavailable`: The attempt could not be recorded. Retry shortly.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["mfa_unavailable"]}}}]}}}}},"security":[]}},"/v1/auth/refresh":{"post":{"operationId":"refresh","tags":["Auth"],"summary":"Refresh the token pair","description":"Rotates a CLI token pair: a new access token and a new refresh token. The refresh token is single-use beyond a short grace period; reusing one past it, or presenting one from a closed session, is invalid_grant and the stored pair should be discarded. A rotation of the same token already in flight answers 503; retry.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"refresh_token":{"type":"string","maxLength":4096,"description":"The refresh token of the pair to rotate."}},"required":["refresh_token"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"An RFC 6749 token response. Store the refresh token; the access token expires after expires_in seconds.","properties":{"token_type":{"type":"string","description":"Always Bearer.","enum":["Bearer"]},"expires_in":{"type":"integer","description":"Seconds until the access token expires."},"access_token":{"type":"string","description":"The bearer to send as Authorization: Bearer on every /v1 and /mcp request."},"refresh_token":{"type":"string","description":"Rotated on every refresh; the previous one stays valid for a short grace period only."}},"required":["token_type","expires_in","access_token","refresh_token"],"additionalProperties":false}}}},"400":{"description":"`invalid_grant`: The refresh token is unknown, reused past its grace period, idle too long, or its session is closed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["invalid_grant"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-address rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"503":{"description":"`temporarily_unavailable`: Another rotation of the same token is in flight. Retry shortly.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["temporarily_unavailable"]}}}]}}}}},"security":[]}},"/v1/auth/logout":{"post":{"operationId":"logout","tags":["Auth"],"summary":"Sign out","description":"Ends the session behind the bearer: every token of its family is revoked at once, and the bearer answers 401 from then on.","responses":{"204":{"description":"Done; no body"},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/auth/code":{"post":{"operationId":"auth_code","tags":["Auth"],"summary":"Auth code for checkout","description":"Mints a one-time auth code for the account behind the bearer, so the customer panel can hand the browser to checkout. Checkout exchanges the code with the account service; it is not a bearer for this API, and it is single-use. Nothing else about the account is returned.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A short-lived auth code for handing the signed-in account from the customer panel to checkout.","properties":{"code":{"type":"string","description":"The one-time code. Checkout exchanges it; it is not a bearer for this API."},"expires_at":{"type":"string","description":"When the code expires, as the account service stated it. Unused after that, and single-use."}},"required":["code","expires_at"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`forbidden`: The bearer was not issued to the first-party CLI client.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["forbidden","insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/me":{"get":{"operationId":"me","tags":["Account"],"summary":"Who am I","description":"The account this bearer is signed in as: display name, username, email address and whether it is verified, phone number, and the stable account, brand and account-holder identifiers. Eleven fields, allowlisted: nothing else about the account leaves here. Takes no arguments, and records the session as used.","x-mcp-tool":"me","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account this connection is signed in as.","properties":{"id":{"type":["string","null"],"description":"The account id."},"actor_id":{"type":["string","null"],"description":"The stable id of the signed-in account holder."},"email":{"type":["string","null"],"description":"The sign-in email address."},"name":{"type":["string","null"],"description":"The display name."},"first_name":{"type":["string","null"],"description":"The account holder's first name."},"last_name":{"type":["string","null"],"description":"The account holder's last name."},"username":{"type":["string","null"],"description":"The username on the account."},"email_verified":{"type":["boolean","null"],"description":"Whether the default email address has been verified."},"phone":{"type":["string","null"],"description":"The default phone number, in international format."},"brand_id":{"type":["string","null"],"description":"The brand the account belongs to."},"account_id":{"type":["string","null"],"description":"The billing account id."}},"required":["id","actor_id","email","name","first_name","last_name","username","email_verified","phone","brand_id","account_id"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/profile":{"get":{"operationId":"get_profile","tags":["Account"],"summary":"Get the full profile","description":"The full account holder record: contact details, and every email address, phone number, postal address and company on the account. Heavier than the eleven fields of GET /v1/me; for when contact or billing-address detail is needed. Takes no arguments.","x-mcp-tool":"get_profile","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account holder record.","properties":{"id":{"type":["string","null"],"description":"The account holder id (actor_id on me)."},"username":{"type":["string","null"],"description":"The username on the account."},"first_name":{"type":["string","null"],"description":"First name."},"last_name":{"type":["string","null"],"description":"Last name."},"name":{"type":["string","null"],"description":"Full name."},"public_name":{"type":["string","null"],"description":"The name shown to others, e.g. on support tickets."},"verified":{"type":["boolean","null"],"description":"Whether the account holder is verified."},"created_at":{"type":["string","null"],"description":"When the account was created."},"brand_id":{"type":["string","null"],"description":"The brand the account belongs to."},"account_id":{"type":["string","null"],"description":"The billing account id."},"emails":{"type":"array","description":"Every email address on the account.","items":{"type":"object","properties":{"email":{"type":["string","null"],"description":"The address."},"verified":{"type":["boolean","null"],"description":"Whether it has been verified."},"default":{"type":["boolean","null"],"description":"Whether it is the account's default address."}},"required":["email","verified","default"],"additionalProperties":false}},"phones":{"type":"array","description":"Every phone number on the account.","items":{"type":"object","properties":{"number":{"type":["string","null"],"description":"The number, in international format."},"country_code":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 country of the number."},"verified":{"type":["boolean","null"],"description":"Whether it has been verified."},"default":{"type":["boolean","null"],"description":"Whether it is the account's default number."}},"required":["number","country_code","verified","default"],"additionalProperties":false}},"addresses":{"type":"array","description":"Every postal address on the account.","items":{"type":"object","description":"A postal address.","properties":{"name":{"type":["string","null"],"description":"The label the account gave the address, e.g. Home."},"line_1":{"type":["string","null"],"description":"First line."},"line_2":{"type":["string","null"],"description":"Second line."},"city":{"type":["string","null"],"description":"City."},"postcode":{"type":["string","null"],"description":"Postal code."},"country_code":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 country code."},"country":{"type":["string","null"],"description":"Country name."},"region":{"type":["string","null"],"description":"Region or state, when the country has them."},"default":{"type":["boolean","null"],"description":"Whether it is the account's default address."}},"required":["name","line_1","line_2","city","postcode","country_code","country","region","default"],"additionalProperties":false}},"companies":{"type":"array","description":"Every company on the account.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The company name."},"registration_number":{"type":["string","null"],"description":"The company registration number."},"vat_number":{"type":["string","null"],"description":"The VAT number."},"default":{"type":["boolean","null"],"description":"Whether it is the account's default company."},"address":{"type":["object","null"],"description":"The company's registered address.","properties":{"line_1":{"type":["string","null"],"description":"First line."},"line_2":{"type":["string","null"],"description":"Second line."},"city":{"type":["string","null"],"description":"City."},"postcode":{"type":["string","null"],"description":"Postal code."},"country_code":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 country code."},"country":{"type":["string","null"],"description":"Country name."},"region":{"type":["string","null"],"description":"Region or state, when the country has them."}},"required":["line_1","line_2","city","postcode","country_code","country","region"],"additionalProperties":false}},"required":["name","registration_number","vat_number","default","address"],"additionalProperties":false}}},"required":["id","username","first_name","last_name","name","public_name","verified","created_at","brand_id","account_id","emails","phones","addresses","companies"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/services":{"get":{"operationId":"list_services","tags":["Account"],"summary":"List services","description":"The account's services: hosting, email, domains and add-ons. Each row carries its status, next_due_date (the paid-up-to date), price, provisioning provider, and the service_id and contract_id every per-service read needs. A service that holds websites also carries platform (hosting or managed_wordpress): that is how to find a hosting service or managed WordPress plan for get_hosting_plan, list_mwp_locations and create_website; the rest carry null. expiring_only finds the services that will lapse because auto-renew is off. Paged with limit and offset; total counts every match.","x-mcp-tool":"list_services","parameters":[{"name":"status","in":"query","required":false,"description":"Only services in this status. Omit for all statuses.","schema":{"type":"string","enum":["contract_active","contract_awaiting_activation","contract_pending","contract_suspended","contract_cancelled","contract_closed"]}},{"name":"search","in":"query","required":false,"description":"Free-text search across product name and service identifier (domain, hostname, account name).","schema":{"type":"string","maxLength":200}},{"name":"expiring_only","in":"query","required":false,"description":"Only live services with auto-renew off and a finite billing cycle, i.e. those that will lapse at next_due_date. Overrides status.","schema":{"type":"boolean","default":false}},{"name":"order","in":"query","required":false,"description":"Sort field; a leading - means descending.","schema":{"type":"string","enum":["next_due_date","-next_due_date","created_at","-created_at","total_amount","-total_amount"],"default":"next_due_date"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"services":{"type":"array","description":"The services of this page.","items":{"type":"object","description":"One of the account's services.","properties":{"service_id":{"type":["string","null"],"description":"The contract product id; with contract_id, the input to the per-service reads."},"contract_id":{"type":["string","null"],"description":"The contract the service belongs to."},"name":{"type":["string","null"],"description":"The custom label the account gave it, else the product name."},"identifier":{"type":["string","null"],"description":"The domain, hostname or account name the service was provisioned as."},"category":{"type":["string","null"],"description":"The product category, as the catalogue names it."},"provision_category":{"type":["string","null"],"description":"The provisioning category code, e.g. domain-names, shared-hosting."},"provider":{"type":["string","null"],"description":"The provisioning provider code, e.g. cpanel."},"platform":{"type":["string","null"],"description":"For a service that holds websites, which panel they live on: hosting or managed_wordpress (what get_hosting_plan and create_website take as service_id). Null for anything else: domains, email, add-ons.","enum":["hosting","managed_wordpress",null]},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active, contract_suspended, contract_cancelled."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date. The service lapses on it only when auto_renew is false."},"auto_renew":{"type":["boolean","null"],"description":"Whether the service renews itself at next_due_date."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months; 0 for a one-off."},"amount":{"type":["number","null"],"description":"The recurring amount, in currency."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."}},"required":["service_id","contract_id","name","identifier","category","provision_category","provider","platform","status","next_due_date","auto_renew","billing_cycle_months","amount","currency"],"additionalProperties":false}}},"required":["total","services"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/contracts/{contract_id}":{"get":{"operationId":"get_service","tags":["Account"],"summary":"Get a contract and one of its services","description":"One contract in full: billing terms, status, the payment method that renews it, whether a cancellation has been requested, and every service on it as a row. Pass service_id to have that one service surfaced as `service` (null when it is omitted or matches nothing on the contract).","x-mcp-tool":"get_service","parameters":[{"name":"contract_id","in":"path","required":true,"description":"The contract id (contract_id on a service row).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}},{"name":"service_id","in":"query","required":false,"description":"A contract product id (service_id on a service row) to surface as `service`.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A contract and the service asked about.","properties":{"contract":{"type":"object","description":"The contract.","properties":{"contract_id":{"type":["string","null"],"description":"The contract id."},"number":{"type":["string","null"],"description":"The contract number as the account sees it."},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active."},"currency":{"type":["string","null"],"description":"ISO 4217 code of total_amount."},"total_amount":{"type":["number","null"],"description":"The recurring amount of the whole contract."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date."},"cancellation_requested":{"type":"boolean","description":"Whether a cancellation has been requested."},"payment_method":{"type":["string","null"],"description":"The saved payment method that renews it (its display name, e.g. \"Visa ending 4242\"), else the gateway."},"services":{"type":"array","description":"Every service on the contract.","items":{"type":"object","description":"One of the account's services.","properties":{"service_id":{"type":["string","null"],"description":"The contract product id; with contract_id, the input to the per-service reads."},"contract_id":{"type":["string","null"],"description":"The contract the service belongs to."},"name":{"type":["string","null"],"description":"The custom label the account gave it, else the product name."},"identifier":{"type":["string","null"],"description":"The domain, hostname or account name the service was provisioned as."},"category":{"type":["string","null"],"description":"The product category, as the catalogue names it."},"provision_category":{"type":["string","null"],"description":"The provisioning category code, e.g. domain-names, shared-hosting."},"provider":{"type":["string","null"],"description":"The provisioning provider code, e.g. cpanel."},"platform":{"type":["string","null"],"description":"For a service that holds websites, which panel they live on: hosting or managed_wordpress (what get_hosting_plan and create_website take as service_id). Null for anything else: domains, email, add-ons.","enum":["hosting","managed_wordpress",null]},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active, contract_suspended, contract_cancelled."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date. The service lapses on it only when auto_renew is false."},"auto_renew":{"type":["boolean","null"],"description":"Whether the service renews itself at next_due_date."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months; 0 for a one-off."},"amount":{"type":["number","null"],"description":"The recurring amount, in currency."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."}},"required":["service_id","contract_id","name","identifier","category","provision_category","provider","platform","status","next_due_date","auto_renew","billing_cycle_months","amount","currency"],"additionalProperties":false}}},"required":["contract_id","number","status","currency","total_amount","billing_cycle_months","next_due_date","cancellation_requested","payment_method","services"],"additionalProperties":false},"service":{"type":["object","null"],"description":"The service named by service_id, or null when none was named or it is not on this contract.","properties":{"service_id":{"type":["string","null"],"description":"The contract product id; with contract_id, the input to the per-service reads."},"contract_id":{"type":["string","null"],"description":"The contract the service belongs to."},"name":{"type":["string","null"],"description":"The custom label the account gave it, else the product name."},"identifier":{"type":["string","null"],"description":"The domain, hostname or account name the service was provisioned as."},"category":{"type":["string","null"],"description":"The product category, as the catalogue names it."},"provision_category":{"type":["string","null"],"description":"The provisioning category code, e.g. domain-names, shared-hosting."},"provider":{"type":["string","null"],"description":"The provisioning provider code, e.g. cpanel."},"platform":{"type":["string","null"],"description":"For a service that holds websites, which panel they live on: hosting or managed_wordpress (what get_hosting_plan and create_website take as service_id). Null for anything else: domains, email, add-ons.","enum":["hosting","managed_wordpress",null]},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active, contract_suspended, contract_cancelled."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date. The service lapses on it only when auto_renew is false."},"auto_renew":{"type":["boolean","null"],"description":"Whether the service renews itself at next_due_date."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months; 0 for a one-off."},"amount":{"type":["number","null"],"description":"The recurring amount, in currency."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."}},"required":["service_id","contract_id","name","identifier","category","provision_category","provider","platform","status","next_due_date","auto_renew","billing_cycle_months","amount","currency"],"additionalProperties":false}},"required":["contract","service"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No contract with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/contracts/{contract_id}/services/{service_id}/provision-fields":{"get":{"operationId":"get_service_provision_fields","tags":["Account"],"summary":"Get a service's provisioning fields","description":"The provider-defined provisioning fields of one service with their current values: where nameservers, registrant contacts, hostnames and usernames live. The field set is the provider's, so read each field's name and label rather than expecting fixed ones. A secret (a field the provider types as a password, an EPP/auth code) is marked secret and its value withheld; the audited actions exist for those.","x-mcp-tool":"get_service_provision_fields","parameters":[{"name":"contract_id","in":"path","required":true,"description":"The contract id (contract_id on a service row).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}},{"name":"service_id","in":"path","required":true,"description":"The contract product id (service_id on a service row).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A service's provisioning fields.","properties":{"contract_id":{"type":"string","description":"The contract asked about."},"service_id":{"type":"string","description":"The service asked about."},"fields":{"type":"array","description":"The provisioning fields with their values, in the provider's order.","items":{"type":"object","description":"One provisioning field with its value.","properties":{"name":{"type":["string","null"],"description":"The field code, as the provider names it."},"label":{"type":["string","null"],"description":"The label shown for it."},"type":{"type":["string","null"],"description":"The field type, e.g. text, toggle, password."},"required":{"type":["boolean","null"],"description":"Whether the provider requires a value."},"secret":{"type":"boolean","description":"true when the value is a secret and is therefore withheld."},"value":{"type":["string","null"],"description":"The current value, as a string; null when none is recorded or the field is a secret."}},"required":["name","label","type","required","secret","value"],"additionalProperties":false}}},"required":["contract_id","service_id","fields"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No contract or service with these ids on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/invoices":{"get":{"operationId":"list_invoices","tags":["Billing"],"summary":"List invoices","description":"The account's invoices. state=outstanding is what is owed (unpaid, overdue and adjusted invoices), state=paid the payment history; omit state for everything. Each row's invoice_id is the input to the invoice detail and to paying it. Paged with limit and offset.","x-mcp-tool":"list_invoices","parameters":[{"name":"state","in":"query","required":false,"description":"outstanding: unpaid, overdue and adjusted invoices (what is owed). paid: settled. refunded_or_cancelled: refunded or cancelled. Omit for all.","schema":{"type":"string","enum":["paid","outstanding","refunded_or_cancelled"]}},{"name":"number","in":"query","required":false,"description":"Partial invoice number to match, e.g. \"INV-00\" or \"42\".","schema":{"type":"string","maxLength":64}},{"name":"order","in":"query","required":false,"description":"Sort field; a leading - means descending.","schema":{"type":"string","enum":["-create_datetime","create_datetime","due_date","-due_date","-total_amount"],"default":"-create_datetime"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"invoices":{"type":"array","description":"The invoices of this page.","items":{"type":"object","description":"One invoice as a list row.","properties":{"invoice_id":{"type":["string","null"],"description":"The invoice id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."}},"required":["invoice_id","number","status","issued","due_date","paid_at","total","paid","currency"],"additionalProperties":false}}},"required":["total","invoices"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/invoices/{invoice_id}":{"get":{"operationId":"get_invoice","tags":["Billing"],"summary":"Get an invoice","description":"One invoice in full: its lines, taxes and payments, the services it bills, the payment method it is set to be paid with, and unpaid_amount, the amount still owed in the invoice currency and the exact number to pass back when paying it. unpaid_amount is null when it could not be determined, which does not mean nothing is owed.","x-mcp-tool":"get_invoice","parameters":[{"name":"invoice_id","in":"path","required":true,"description":"The invoice id from the invoices or orders list.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Invoice in full.","properties":{"invoice_id":{"type":["string","null"],"description":"The invoice id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."},"net_amount":{"type":["number","null"],"description":"The total before tax."},"tax_amount":{"type":["number","null"],"description":"The tax on it."},"unpaid_amount":{"type":["number","null"],"description":"What is still owed, in currency: the exact number to pass back when paying. Null when it could not be determined, which does not mean nothing is owed."},"lines":{"type":"array","description":"The lines of the invoice.","items":{"type":"object","properties":{"description":{"type":["string","null"],"description":"What the line bills."},"quantity":{"type":["number","null"],"description":"How many."},"unit_amount":{"type":["number","null"],"description":"The price of one."},"total":{"type":["number","null"],"description":"The line total, tax included."},"service_id":{"type":["string","null"],"description":"The service the line bills, when it bills one."},"service_identifier":{"type":["string","null"],"description":"That service's domain, hostname or account name."}},"required":["description","quantity","unit_amount","total","service_id","service_identifier"],"additionalProperties":false}},"taxes":{"type":"array","description":"The taxes applied.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The tax, e.g. VAT."},"rate":{"type":["number","null"],"description":"The rate, as a percentage."},"amount":{"type":["number","null"],"description":"The tax amount."}},"required":["name","rate","amount"],"additionalProperties":false}},"payments":{"type":"array","description":"The payments made against it.","items":{"type":"object","properties":{"date":{"type":["string","null"],"description":"When it was paid."},"amount":{"type":["number","null"],"description":"The amount paid."},"method":{"type":["string","null"],"description":"How it was paid."}},"required":["date","amount","method"],"additionalProperties":false}},"payment_method":{"type":["string","null"],"description":"The saved payment method it is set to be paid with, else the gateway; null when none."},"original_invoice_id":{"type":["string","null"],"description":"For an adjusted invoice, the one it adjusts."}},"required":["invoice_id","number","status","issued","due_date","paid_at","total","paid","currency","net_amount","tax_amount","unpaid_amount","lines","taxes","payments","payment_method","original_invoice_id"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No invoice with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/orders":{"get":{"operationId":"list_orders","tags":["Billing"],"summary":"List orders","description":"The account's orders: its invoices viewed by purchase category (what was bought) rather than by payment state (what is owed, which is the invoices list). Newest first. An order is an invoice, so each row's invoice_id works with the invoice detail and with paying, and the order detail takes the same id. Paged with limit and offset.","x-mcp-tool":"list_orders","parameters":[{"name":"category","in":"query","required":false,"description":"Purchase category. Omit for all categories.","schema":{"type":"string","enum":["new_contract","additional_service","one_time_service","migration_pro_rata","recurrent"]}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"orders":{"type":"array","description":"The orders of this page.","items":{"type":"object","description":"One invoice as a list row.","properties":{"invoice_id":{"type":["string","null"],"description":"The invoice id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."}},"required":["invoice_id","number","status","issued","due_date","paid_at","total","paid","currency"],"additionalProperties":false}}},"required":["total","orders"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/orders/{order_id}":{"get":{"operationId":"get_order","tags":["Billing"],"summary":"Get an order","description":"One order in full: the invoice a purchase raised, read with the purchase relations (its lines, the services they bought) and unpaid_amount, what is still owed on it. The same id works with the invoice detail and with paying.","x-mcp-tool":"get_order","parameters":[{"name":"order_id","in":"path","required":true,"description":"The order id from the orders list (an invoice id).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Order in full.","properties":{"order_id":{"type":["string","null"],"description":"The order id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."},"net_amount":{"type":["number","null"],"description":"The total before tax."},"tax_amount":{"type":["number","null"],"description":"The tax on it."},"unpaid_amount":{"type":["number","null"],"description":"What is still owed, in currency: the exact number to pass back when paying. Null when it could not be determined, which does not mean nothing is owed."},"lines":{"type":"array","description":"The lines of the invoice.","items":{"type":"object","properties":{"description":{"type":["string","null"],"description":"What the line bills."},"quantity":{"type":["number","null"],"description":"How many."},"unit_amount":{"type":["number","null"],"description":"The price of one."},"total":{"type":["number","null"],"description":"The line total, tax included."},"service_id":{"type":["string","null"],"description":"The service the line bills, when it bills one."},"service_identifier":{"type":["string","null"],"description":"That service's domain, hostname or account name."}},"required":["description","quantity","unit_amount","total","service_id","service_identifier"],"additionalProperties":false}},"taxes":{"type":"array","description":"The taxes applied.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The tax, e.g. VAT."},"rate":{"type":["number","null"],"description":"The rate, as a percentage."},"amount":{"type":["number","null"],"description":"The tax amount."}},"required":["name","rate","amount"],"additionalProperties":false}},"payments":{"type":"array","description":"The payments made against it.","items":{"type":"object","properties":{"date":{"type":["string","null"],"description":"When it was paid."},"amount":{"type":["number","null"],"description":"The amount paid."},"method":{"type":["string","null"],"description":"How it was paid."}},"required":["date","amount","method"],"additionalProperties":false}},"payment_method":{"type":["string","null"],"description":"The saved payment method it is set to be paid with, else the gateway; null when none."},"original_invoice_id":{"type":["string","null"],"description":"For an adjusted invoice, the one it adjusts."}},"required":["order_id","number","status","issued","due_date","paid_at","total","paid","currency","net_amount","tax_amount","unpaid_amount","lines","taxes","payments","payment_method","original_invoice_id"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No order with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/payment-methods":{"get":{"operationId":"list_payment_methods","tags":["Billing"],"summary":"List payment methods","description":"The account's active stored payment methods, the default first: each one's display name (e.g. \"Visa ending 4242\"), gateway, and whether it is the default and pays automatically. The card or account detail behind a method never leaves the payment gateway. Not paged. Takes no arguments.","x-mcp-tool":"list_payment_methods","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account's stored payment methods.","properties":{"payment_methods":{"type":"array","description":"The active stored methods, the default first. Not paged.","items":{"type":"object","description":"One stored payment method.","properties":{"id":{"type":["string","null"],"description":"The saved method's id; the input to paying with it."},"name":{"type":["string","null"],"description":"Its display name, e.g. \"Visa ending 4242\"."},"gateway":{"type":["string","null"],"description":"The payment gateway that holds it."},"is_default":{"type":["boolean","null"],"description":"Whether it is the account's default method."},"auto_payment":{"type":["boolean","null"],"description":"Whether it pays invoices automatically when due."}},"required":["id","name","gateway","is_default","auto_payment"],"additionalProperties":false}}},"required":["payment_methods"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/credit":{"get":{"operationId":"get_account_credit","tags":["Billing"],"summary":"Get the credit balance","description":"The credit held on the account and, unless include_statements is false, the most recent monthly credit statements (the period each covers and its total; the customer panel offers each as a PDF or CSV). Credit is applied to invoices before a payment method is charged.","x-mcp-tool":"get_account_credit","parameters":[{"name":"include_statements","in":"query","required":false,"description":"Also return the most recent monthly credit statements.","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account's credit.","properties":{"balance":{"type":"object","description":"The balance: online and offline credit together.","properties":{"amount":{"type":["number","null"],"description":"The credit held, in currency, to the cent."},"formatted":{"type":["string","null"],"description":"The same, formatted for display."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."}},"required":["amount","formatted","currency"],"additionalProperties":false},"statements":{"type":["array","null"],"description":"The most recent monthly credit statements, newest first (the panel offers each as a PDF or CSV under Account Credit); null when include_statements was false.","items":{"type":"object","properties":{"statement_id":{"type":["string","null"],"description":"The statement id."},"from":{"type":["string","null"],"description":"The start of the period the statement covers."},"to":{"type":["string","null"],"description":"The end of the period the statement covers."},"total":{"type":["number","null"],"description":"The statement's total for the period, in the wallet's currency (balance.currency)."},"formatted":{"type":["string","null"],"description":"The same, formatted for display."},"created_at":{"type":["string","null"],"description":"When the statement was generated."}},"required":["statement_id","from","to","total","formatted","created_at"],"additionalProperties":false}}},"required":["balance","statements"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains":{"get":{"operationId":"list_domains","tags":["Domains"],"summary":"List domains","description":"The account's domain registrations, each with its status, expires (the paid-up-to date) and auto_renew. A domain is a service in the domain-names category, so each row's service_id and contract_id work with the contract and provisioning reads too. expiring_only finds the domains that will lapse because auto-renew is off. Paged with limit and offset.","x-mcp-tool":"list_domains","parameters":[{"name":"status","in":"query","required":false,"description":"Only domains in this status. Omit for all statuses.","schema":{"type":"string","enum":["contract_active","contract_awaiting_activation","contract_pending","contract_suspended","contract_cancelled","contract_closed"]}},{"name":"expiring_only","in":"query","required":false,"description":"Only domains with auto-renew off, which will therefore lapse at next_due_date. Overrides status.","schema":{"type":"boolean","default":false}},{"name":"order","in":"query","required":false,"description":"Sort field; a leading - means descending.","schema":{"type":"string","enum":["next_due_date","-next_due_date","created_at","-created_at"],"default":"next_due_date"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"domains":{"type":"array","description":"The domains of this page.","items":{"type":"object","description":"One of the account's domain registrations.","properties":{"service_id":{"type":["string","null"],"description":"The contract product id; with contract_id, the input to the per-service reads."},"contract_id":{"type":["string","null"],"description":"The contract the service belongs to."},"name":{"type":["string","null"],"description":"The custom label the account gave it, else the product name."},"identifier":{"type":["string","null"],"description":"The domain, hostname or account name the service was provisioned as."},"category":{"type":["string","null"],"description":"The product category, as the catalogue names it."},"provision_category":{"type":["string","null"],"description":"The provisioning category code, e.g. domain-names, shared-hosting."},"provider":{"type":["string","null"],"description":"The provisioning provider code, e.g. cpanel."},"platform":{"type":["string","null"],"description":"For a service that holds websites, which panel they live on: hosting or managed_wordpress (what get_hosting_plan and create_website take as service_id). Null for anything else: domains, email, add-ons.","enum":["hosting","managed_wordpress",null]},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active, contract_suspended, contract_cancelled."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date. The service lapses on it only when auto_renew is false."},"auto_renew":{"type":["boolean","null"],"description":"Whether the service renews itself at next_due_date."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months; 0 for a one-off."},"amount":{"type":["number","null"],"description":"The recurring amount, in currency."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."},"domain":{"type":["string","null"],"description":"The domain name; the input to the per-domain reads and actions."},"expires":{"type":["string","null"],"description":"The paid-up-to date. There is no registry expiry field: the domain lapses on this date only when auto_renew is false."}},"required":["service_id","contract_id","name","identifier","category","provision_category","provider","platform","status","next_due_date","auto_renew","billing_cycle_months","amount","currency","domain","expires"],"additionalProperties":false}}},"required":["total","domains"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"register_domain","tags":["Domains"],"summary":"Order a new domain","description":"Puts a new domain registration on a draft order for the account: a new order when order_id is left out, or one more line on the draft order given. The name is checked against the catalogue first and the order is refused, with nothing placed, when it cannot be registered, when the period is not one it is sold for, or when the account already holds it. The answer is the draft order and its total, tax included. Nothing is registered or charged yet: give the order_id and that exact amount to complete_purchase, which converts the draft to an invoice and pays it with a saved payment method.","x-mcp-tool":"register_domain","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain to register, e.g. example.com, as check_domain_availability answered it available."},"period_months":{"type":"integer","minimum":1,"maximum":120,"description":"The registration period in months, one of the period_months check_domain_availability lists for the name (usually 12, 24, 36...)."},"order_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"A draft order already open on this account, to add the domain to as one more line. Omitted, a new draft order is opened with the domain as its first line."}},"required":["domain","period_months"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"A domain on a draft order, awaiting completion.","properties":{"order_id":{"type":["string","null"],"description":"The draft order the domain is on. Give it to complete_purchase to convert and pay, or to register_domain again to add another domain to the same order."},"domain":{"type":"string","description":"The domain ordered. It is not registered until the order is completed and paid."},"period_months":{"type":"integer","description":"The registration period ordered."},"net_amount":{"type":["number","null"],"description":"The draft's total before tax, every line included."},"tax_amount":{"type":["number","null"],"description":"The tax on the draft."},"amount":{"type":["number","null"],"description":"The draft's total to confirm, tax included: the amount to give complete_purchase."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."},"items":{"type":"array","description":"Every line on the draft, this domain included.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The line: the domain for a registration."},"product":{"type":["string","null"],"description":"The catalogue product's name."},"period_months":{"type":["integer","null"],"description":"The line's period."},"amount":{"type":["number","null"],"description":"The line's total, tax included."}},"required":["name","product","period_months","amount"],"additionalProperties":false}}},"required":["order_id","domain","period_months","net_amount","tax_amount","amount","currency","items"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before purchases was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: order_id names no draft order on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The account service refused the order; the description carries its reason and nothing was ordered.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["purchase_refused","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/search":{"get":{"operationId":"check_domain_availability","tags":["Domains"],"summary":"Check domain availability","description":"Whether one exact domain can be registered now, with the periods it is sold for and their prices before tax. The answer comes from the brand's catalogue, so a TLD it does not sell reads as unavailable. Prices are in currency_code when given, otherwise the account's default currency, or the brand's if the account has none. A name that is available can be ordered with register_domain for one of the periods listed.","x-mcp-tool":"check_domain_availability","parameters":[{"name":"domain","in":"query","required":true,"description":"The full domain to check, e.g. example.com. One name; the TLD must be one the catalogue sells.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"currency_code","in":"query","required":false,"description":"ISO 4217 currency code for the prices. Omit to use the account's default currency, or the brand's when the account has none.","schema":{"type":"string","pattern":"^[A-Za-z]{3}$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Whether a domain can be registered, and at what price.","properties":{"domain":{"type":["string","null"],"description":"The full name checked."},"tld":{"type":["string","null"],"description":"The TLD, without the leading dot."},"available":{"type":["boolean","null"],"description":"Whether it can be registered now through register_domain; null when the catalogue did not say."},"transferable":{"type":["boolean","null"],"description":"Whether the catalogue would take it as a transfer; transfers are not offered through here."},"premium":{"type":["boolean","null"],"description":"Whether the registry prices it as a premium name; null when the catalogue did not say."},"prices":{"type":"array","description":"The periods the catalogue sells the name for and their prices, before tax; empty when the name cannot be registered. The order's total, tax included, is what register_domain answers.","items":{"type":"object","properties":{"period_months":{"type":["integer","null"],"description":"The registration period the price buys; the period_months to give register_domain."},"amount":{"type":["number","null"],"description":"The price for the period, before tax, with any promotion applied."},"list_amount":{"type":["number","null"],"description":"The price before any promotion; equals amount when none applies."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."}},"required":["period_months","amount","list_amount","currency"],"additionalProperties":false}}},"required":["domain","tld","available","transferable","premium","prices"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/{domain}":{"get":{"operationId":"get_domain","tags":["Domains"],"summary":"Get a domain","description":"One of the account's domains, by name: its service row, what the registrar records for it (nameservers, the registrar lock, registrant details, as provisioning fields whose set is the registrar's) and the registrar actions available on it, as a listing only. The EPP/auth code is never in here, nor anywhere on this API.","x-mcp-tool":"get_domain","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain name, e.g. example.com. Case does not matter.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One of the account's domains in full.","properties":{"service_id":{"type":["string","null"],"description":"The contract product id; with contract_id, the input to the per-service reads."},"contract_id":{"type":["string","null"],"description":"The contract the service belongs to."},"name":{"type":["string","null"],"description":"The custom label the account gave it, else the product name."},"identifier":{"type":["string","null"],"description":"The domain, hostname or account name the service was provisioned as."},"category":{"type":["string","null"],"description":"The product category, as the catalogue names it."},"provision_category":{"type":["string","null"],"description":"The provisioning category code, e.g. domain-names, shared-hosting."},"provider":{"type":["string","null"],"description":"The provisioning provider code, e.g. cpanel."},"platform":{"type":["string","null"],"description":"For a service that holds websites, which panel they live on: hosting or managed_wordpress (what get_hosting_plan and create_website take as service_id). Null for anything else: domains, email, add-ons.","enum":["hosting","managed_wordpress",null]},"status":{"type":["string","null"],"description":"The contract status code, e.g. contract_active, contract_suspended, contract_cancelled."},"next_due_date":{"type":["string","null"],"description":"The paid-up-to date. The service lapses on it only when auto_renew is false."},"auto_renew":{"type":["boolean","null"],"description":"Whether the service renews itself at next_due_date."},"billing_cycle_months":{"type":["integer","null"],"description":"The billing cycle in months; 0 for a one-off."},"amount":{"type":["number","null"],"description":"The recurring amount, in currency."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."},"domain":{"type":["string","null"],"description":"The domain name; the input to the per-domain reads and actions."},"expires":{"type":["string","null"],"description":"The paid-up-to date. There is no registry expiry field: the domain lapses on this date only when auto_renew is false."},"registrar_fields":{"type":"array","description":"What the registrar records for the domain: nameservers, the registrar lock, registrant details. The field set is the registrar's; a secret (the EPP/auth code) is withheld and comes only from the audited EPP action.","items":{"type":"object","description":"One provisioning field with its value.","properties":{"name":{"type":["string","null"],"description":"The field code, as the provider names it."},"label":{"type":["string","null"],"description":"The label shown for it."},"type":{"type":["string","null"],"description":"The field type, e.g. text, toggle, password."},"required":{"type":["boolean","null"],"description":"Whether the provider requires a value."},"secret":{"type":"boolean","description":"true when the value is a secret and is therefore withheld."},"value":{"type":["string","null"],"description":"The current value, as a string; null when none is recorded or the field is a secret."}},"required":["name","label","type","required","secret","value"],"additionalProperties":false}},"actions":{"type":"array","description":"The registrar actions available on the domain. A listing only; nothing is run.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The action's name at the registrar."},"label":{"type":["string","null"],"description":"The label shown for it."}},"required":["name","label"],"additionalProperties":false}}},"required":["service_id","contract_id","name","identifier","category","provision_category","provider","platform","status","next_due_date","auto_renew","billing_cycle_months","amount","currency","domain","expires","registrar_fields","actions"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/{domain}/nameservers":{"get":{"operationId":"get_domain_nameservers","tags":["Domains"],"summary":"Get a domain's nameservers","description":"The nameservers of one of the account's domains, as the account has them on record: hostnames in slot order. A change made directly at the registrar, outside this account, may not show until the record is next updated. Setting them is the POST on the same path.","x-mcp-tool":"get_domain_nameservers","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain name, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain's nameservers.","properties":{"domain":{"type":"string","description":"The domain."},"nameservers":{"type":"array","description":"The nameserver hostnames in slot order, as the account has them on record.","items":{"type":"string"}}},"required":["domain","nameservers"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"set_domain_nameservers","tags":["Domains"],"summary":"Set a domain's nameservers","description":"Replaces the nameservers of one of the account's domains at the registrar with the complete list given (2 to 5 hostnames). This changes where the domain's DNS is served from and can take the site and email offline if wrong. Hostnames only; a nameserver inside this domain needs a glue record first. Answers the nameservers now on record.","x-mcp-tool":"set_domain_nameservers","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to change, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"nameservers":{"type":"array","minItems":2,"maxItems":5,"items":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+\\.?$"},"description":"The complete new list of nameserver hostnames, 2 to 5, e.g. [\"ns1.example.net\", \"ns2.example.net\"]. Replaces every existing nameserver; there is no partial edit. Hostnames only: a nameserver inside this domain needs a glue record first."}},"required":["nameservers"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain's nameservers after the change.","properties":{"domain":{"type":"string","description":"The domain."},"nameservers":{"type":"array","description":"The nameservers now on record.","items":{"type":"string"}},"message":{"type":["string","null"],"description":"The registrar's own confirmation, when it gave one."}},"required":["domain","nameservers","message"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before domain changes was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The registrar refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/invoices/{invoice_id}/payments":{"post":{"operationId":"pay_invoice","tags":["Billing"],"summary":"Pay an invoice","description":"Pays an outstanding invoice (or order) in full with one of the account's saved payment methods. The amount and currency must be the invoice's unpaid_amount and currency exactly; any other value is refused and nothing is paid. Partial payments and new cards are not possible here. The outcome's status is paid, pending or action_required: action_required means the card issuer wants the payer to approve the payment in a browser at approval_url first, and the invoice is not yet paid.","x-mcp-tool":"pay_invoice","parameters":[{"name":"invoice_id","in":"path","required":true,"description":"The invoice (or order) to pay, as the invoices and orders listings identify it.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","description":"The amount to pay. Must equal the invoice's unpaid_amount exactly; any other value is refused and nothing is paid. Partial payments are not possible."},"currency":{"type":"string","description":"The invoice's three-letter currency code, e.g. GBP; a different currency is refused."},"payment_method_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"A saved payment method, as the payment methods listing identifies it. Omitted, the account's default method is charged."}},"required":["amount","currency"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a payment.","properties":{"status":{"type":"string","description":"paid: the invoice is now settled. pending: accepted, settlement not yet confirmed; re-read the invoice later. action_required: the payer must approve at approval_url in a browser; not paid yet.","enum":["paid","pending","action_required"]},"transaction_id":{"type":["string","null"],"description":"The payment system's transaction."},"transaction_status":{"type":["string","null"],"description":"The payment system's own status word for the transaction."},"approval_url":{"type":["object","null"],"description":"Present only when status is action_required.","properties":{"url":{"type":"string","description":"Where the payer approves the payment."},"method":{"type":"string","description":"get or post."},"fields":{"type":"object","description":"Form fields to submit with the request, when method is post.","additionalProperties":true}},"required":["url","method","fields"],"additionalProperties":false},"invoice":{"type":"object","description":"The invoice after the payment.","properties":{"invoice_id":{"type":["string","null"],"description":"The invoice id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."}},"required":["invoice_id","number","status","issued","due_date","paid_at","total","paid","currency"],"additionalProperties":false}},"required":["status","transaction_id","transaction_status","approval_url","invoice"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before payments was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No invoice matching the identifier on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The invoice is not payable: already paid, cancelled, or without a saved payment method.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["rejected","not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/orders/{order_id}/complete":{"post":{"operationId":"complete_purchase","tags":["Billing"],"summary":"Complete and pay a draft order","description":"Converts a draft order into an invoice and pays it in full with one of the account's saved payment methods. The amount and currency must be the draft's total exactly, as register_domain answered it (or get_order shows it); any other value is refused and nothing is converted or paid. Partial payments and new cards are not possible here. The outcome's status is paid, pending or action_required, as pay_invoice answers it: action_required means the card issuer wants the payer to approve the payment in a browser at approval_url first. If the payment is refused after the order was converted, the answer names the invoice, which stands unpaid and can be paid with pay_invoice.","x-mcp-tool":"complete_purchase","parameters":[{"name":"order_id","in":"path","required":true,"description":"The draft order to complete, as register_domain answered it.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","description":"The draft's total to pay, as register_domain (or get_order) answered it as amount. Must match exactly; any other value is refused and nothing is converted or paid."},"currency":{"type":"string","description":"The draft's three-letter currency code, e.g. GBP; a different currency is refused."},"payment_method_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"A saved payment method, as the payment methods listing identifies it. Omitted, the account's default method is charged."}},"required":["amount","currency"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a payment.","properties":{"status":{"type":"string","description":"paid: the invoice is now settled. pending: accepted, settlement not yet confirmed; re-read the invoice later. action_required: the payer must approve at approval_url in a browser; not paid yet.","enum":["paid","pending","action_required"]},"transaction_id":{"type":["string","null"],"description":"The payment system's transaction."},"transaction_status":{"type":["string","null"],"description":"The payment system's own status word for the transaction."},"approval_url":{"type":["object","null"],"description":"Present only when status is action_required.","properties":{"url":{"type":"string","description":"Where the payer approves the payment."},"method":{"type":"string","description":"get or post."},"fields":{"type":"object","description":"Form fields to submit with the request, when method is post.","additionalProperties":true}},"required":["url","method","fields"],"additionalProperties":false},"invoice":{"type":"object","description":"The invoice after the payment.","properties":{"invoice_id":{"type":["string","null"],"description":"The invoice id; the input to the detail read and to paying."},"number":{"type":["string","null"],"description":"The invoice number as the account sees it."},"status":{"type":["string","null"],"description":"e.g. invoice_paid, invoice_unpaid, invoice_overdue, invoice_cancelled."},"issued":{"type":["string","null"],"description":"When it was raised."},"due_date":{"type":["string","null"],"description":"When it is due."},"paid_at":{"type":["string","null"],"description":"When it was paid, when it has been."},"total":{"type":["number","null"],"description":"The total, tax included."},"paid":{"type":["number","null"],"description":"What has been paid so far."},"currency":{"type":["string","null"],"description":"ISO 4217 code of the amounts."}},"required":["invoice_id","number","status","issued","due_date","paid_at","total","paid","currency"],"additionalProperties":false}},"required":["status","transaction_id","transaction_status","approval_url","invoice"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before purchases was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No draft order matching the identifier on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The account service refused the conversion, or the payment method is not the account's or the payment system refused the charge after the order was converted; the description says which, and names the unpaid invoice when there is one.\n`not_supported`: The account has no saved payment method to pay the invoice with.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["purchase_refused","rejected","not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/{domain}/lock":{"post":{"operationId":"set_domain_lock","tags":["Domains"],"summary":"Lock or unlock a domain","description":"Enables or disables the registrar lock on one of the account's domains. Locked, the domain cannot be transferred away or changed at the registrar level; unlocked, it can. Answers the lock state afterwards.","x-mcp-tool":"set_domain_lock","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to lock or unlock, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"locked":{"type":"boolean","description":"true enables the registrar lock (blocks transfers away and registrar-level changes); false disables it, for example before transferring the domain out."}},"required":["locked"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain's registrar lock after the change.","properties":{"domain":{"type":"string","description":"The domain."},"locked":{"type":"boolean","description":"The lock state now in force."},"message":{"type":["string","null"],"description":"The registrar's own confirmation, when it gave one."}},"required":["domain","locked","message"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before domain changes was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The registrar refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/{domain}/glue-records":{"post":{"operationId":"set_domain_glue_record","tags":["Domains"],"summary":"Set a glue record","description":"Creates or replaces a glue record at the registry for a nameserver hostname inside one of the account's domains, e.g. ns1.example.com with its IP addresses. Needed before that hostname can be used as a nameserver for the domain itself; setting an existing hostname replaces its addresses. Answers the domain's glue records afterwards when the registrar reports them.","x-mcp-tool":"set_domain_glue_record","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain the glue record belongs to, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The nameserver hostname inside the domain, e.g. ns1.example.com. Must end in the domain."},"ips":{"type":"array","minItems":1,"maxItems":4,"items":{"type":"string"},"description":"One to four IPv4 or IPv6 addresses the hostname resolves to. Replaces the addresses of an existing glue record for the same hostname."}},"required":["hostname","ips"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain's glue records after the change.","properties":{"domain":{"type":"string","description":"The domain."},"glue_records":{"type":["array","null"],"description":"The glue records now at the registry; null when the registrar did not report them.","items":{"type":"object","properties":{"hostname":{"type":"string","description":"A nameserver hostname inside the domain."},"ips":{"type":"array","description":"Its IPv4 and IPv6 addresses at the registry.","items":{"type":"string"}}},"required":["hostname","ips"],"additionalProperties":false}},"message":{"type":["string","null"],"description":"The registrar's own confirmation, when it gave one."}},"required":["domain","glue_records","message"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before domain changes was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The registrar refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/domains/{domain}/glue-records/remove":{"post":{"operationId":"remove_domain_glue_record","tags":["Domains"],"summary":"Remove a glue record","description":"Removes a glue record (a nameserver hostname inside the domain and its addresses) from the registry for one of the account's domains. A nameserver still in use by this domain or others stops resolving. Answers the domain's glue records afterwards when the registrar reports them.","x-mcp-tool":"remove_domain_glue_record","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain the glue record belongs to, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The glue record hostname to remove, e.g. ns1.example.com. A nameserver still in use by the domain or by others should be replaced first."}},"required":["hostname"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain's glue records after the change.","properties":{"domain":{"type":"string","description":"The domain."},"glue_records":{"type":["array","null"],"description":"The glue records now at the registry; null when the registrar did not report them.","items":{"type":"object","properties":{"hostname":{"type":"string","description":"A nameserver hostname inside the domain."},"ips":{"type":"array","description":"Its IPv4 and IPv6 addresses at the registry.","items":{"type":"string"}}},"required":["hostname","ips"],"additionalProperties":false}},"message":{"type":["string","null"],"description":"The registrar's own confirmation, when it gave one."}},"required":["domain","glue_records","message"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before domain changes was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No domain matching the name on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The registrar refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites":{"get":{"operationId":"list_websites","tags":["Websites"],"summary":"List websites","description":"The websites on the account's hosting, across every hosting service, as the control panel has them right now: each with its domain, aliases, status, PHP version, disk in use and the hosting service it belongs to. The services list says which hosting services were read and which could not be (unavailable) or cannot be managed here (not_supported). Signs in to the control panel as the account holder when needed. Websites are addressed by domain in every other website operation.","x-mcp-tool":"list_websites","parameters":[{"name":"service_id","in":"query","required":false,"description":"Only the websites of this hosting service, as the services list or the answer's own services list identify it. Omit for every hosting service on the account.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}},{"name":"search","in":"query","required":false,"description":"Only websites whose domain or an alias contains this text.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The websites on the account's hosting.","properties":{"websites":{"type":"array","description":"The websites, across every hosting service that could be read.","items":{"type":"object","description":"One website as a list row.","properties":{"domain":{"type":"string","description":"The website's primary domain; the input to the per-website operations."},"aliases":{"type":"array","description":"Other domains that reach the same website. On managed WordPress this includes the site's temporary address.","items":{"type":"string"}},"platform":{"type":"string","description":"hosting or managed_wordpress; decides which tools the website takes.","enum":["hosting","managed_wordpress"]},"status":{"type":["string","null"],"description":"active or disabled on hosting; active, pending, locked or deleting on managed WordPress."},"suspended":{"type":"boolean","description":"Whether the website is suspended. On managed WordPress only a lock the platform itself placed shows here; a suspend_website is not reported back."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"label":{"type":["string","null"],"description":"The name the site was given, apart from its domain; managed WordPress only, null on hosting."},"plan":{"type":["string","null"],"description":"The plan name on the panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83; null in a managed WordPress list row (the detail has it)."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running (hosting)."},"created_at":{"type":["string","null"],"description":"When the website was created."},"size_bytes":{"type":["integer","null"],"description":"Disk in use, as the panel last measured it; null when the panel does not count it (a cPanel account with quotas off)."},"service_id":{"type":"string","description":"The hosting service the website belongs to; works with the service detail."},"service_label":{"type":"string","description":"Its label on the account."}},"required":["domain","aliases","platform","status","suspended","kind","label","plan","php_version","pending_backup","created_at","size_bytes","service_id","service_label"],"additionalProperties":false}},"services":{"type":"array","description":"Every hosting service considered, with whether its websites are in the list.","items":{"type":"object","properties":{"service_id":{"type":"string","description":"The hosting service."},"label":{"type":"string","description":"Its label on the account."},"platform":{"type":"string","description":"hosting or managed_wordpress: which panel the service's websites live on, and so which tools they take.","enum":["hosting","managed_wordpress"]},"status":{"type":"string","description":"ok: its websites are in the list. unavailable: its panel could not be reached just now. not_supported: not manageable through this connection (another panel, an AI hosting plan, or a plan awaiting activation).","enum":["ok","unavailable","not_supported"]},"websites":{"type":"integer","description":"How many of its websites are in the list."},"truncated":{"type":"boolean","description":"true when the service has more websites than were listed."}},"required":["service_id","label","platform","status","websites","truncated"],"additionalProperties":false}}},"required":["websites","services"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_website","tags":["Websites"],"summary":"Create a website","description":"Creates a website on one of the account's services, on either platform, as the account holder; the service decides which, and the websites list shows each service's platform (service_id is required when more than one service could take the site). On a hosting service: give domain (and optionally php_version); the control panel adds an empty website for it, writes the domain's DNS records itself, and the answer's preview_domain is where the site can be seen before its domain resolves; install_website_app then puts WordPress or another application on it. Refused, with nothing created, when the domain is already in use or the plan allows no more websites. On a managed WordPress plan: give label, location (a location_id from list_mwp_locations), admin_username, admin_email and admin_password (the user's; it goes to the platform once and is never echoed), and optionally multisite and php_version; omit domain. The platform builds WordPress before it answers (expect twenty to thirty seconds): the answer is the finished site, active and reachable on its temporary address (domain and preview_domain), with get_wordpress_login_link signing the user in; set_website_main_domain attaches the real domain later, once its DNS can be pointed, because the temporary address then redirects to it. Refused when the plan has no site slot left or the location is not one of its. When the platform does not answer in time the site may still have been built: run list_websites and look for it before trying again. A field that belongs to the other platform is refused (422) naming the fields the chosen service takes.","x-mcp-tool":"create_website","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"Hosting: the domain the new website will answer to, e.g. example.com or shop.example.com; required, and it must not already be a website on the account. Managed WordPress: omit it; the platform gives the site a temporary address, and set_website_main_domain attaches the real domain once its DNS can be pointed."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service or managed WordPress plan to create the site on, as the websites list identifies it. Required when more than one service of the platform the other fields imply could take it; omit when one can."},"php_version":{"type":"string","pattern":"^(php[0-9]{2}|[78]\\.[0-9])$","description":"The PHP version to start on, in either platform's form (php83 or 8.3). Omit for the plan's default."},"label":{"type":"string","pattern":"^[^\\x00-\\x1f\\x7f]{1,100}$","description":"Managed WordPress only, required there: the site's title and its name in listings, e.g. \"Acme Shop\". Not a domain."},"location":{"type":"integer","minimum":1,"description":"Managed WordPress only, required there: the data centre to build the site in, by location_id from list_mwp_locations."},"admin_username":{"type":"string","pattern":"^[A-Za-z0-9_.@-]{3,60}$","description":"Managed WordPress only, required there: the WordPress administrator's username."},"admin_password":{"type":"string","minLength":12,"maxLength":128,"description":"Managed WordPress only, required there: the administrator's password, 12 to 128 characters, given by the user. It goes to the platform once and is never stored, logged or echoed."},"admin_email":{"type":"string","maxLength":254,"format":"email","description":"Managed WordPress only, required there: the administrator's email address."},"multisite":{"type":"boolean","description":"Managed WordPress only: true for a WordPress multisite network. false unless given."}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The website just created.","properties":{"domain":{"type":"string","description":"The website's primary domain; the input to the per-website operations."},"aliases":{"type":"array","description":"Other domains that reach the same website. On managed WordPress this includes the site's temporary address.","items":{"type":"string"}},"platform":{"type":"string","description":"hosting or managed_wordpress; decides which tools the website takes.","enum":["hosting","managed_wordpress"]},"status":{"type":["string","null"],"description":"active or disabled on hosting; active, pending, locked or deleting on managed WordPress."},"suspended":{"type":"boolean","description":"Whether the website is suspended. On managed WordPress only a lock the platform itself placed shows here; a suspend_website is not reported back."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"label":{"type":["string","null"],"description":"The name the site was given, apart from its domain; managed WordPress only, null on hosting."},"plan":{"type":["string","null"],"description":"The plan name on the panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83; null in a managed WordPress list row (the detail has it)."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running (hosting)."},"created_at":{"type":["string","null"],"description":"When the website was created."},"size_bytes":{"type":["integer","null"],"description":"Disk in use, as the panel last measured it; null when the panel does not count it (a cPanel account with quotas off)."},"service_id":{"type":"string","description":"The hosting service the website belongs to; works with the service detail."},"service_label":{"type":"string","description":"Its label on the account."},"subdomains":{"type":"array","description":"Subdomains mapped onto the website (hosting).","items":{"type":"string"}},"document_root":{"type":["string","null"],"description":"Where the primary domain is served from."},"server_ips":{"type":"array","description":"The addresses the website is served from.","items":{"type":"string"}},"tags":{"type":"array","description":"The panel's tags on the website (hosting).","items":{"type":"string"}},"location":{"type":["string","null"],"description":"The data centre the site is served from; managed WordPress only."},"preview_domain":{"type":["string","null"],"description":"A hostname the new site can be opened on before its own domain resolves: the control panel's preview hostname on hosting (null when it could not give one), the site's temporary address on managed WordPress."},"created":{"type":"boolean","description":"true: the website now exists. On hosting it is an empty website on the control panel; on managed WordPress the platform has built WordPress and the site is active on preview_domain."},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","aliases","platform","status","suspended","kind","label","plan","php_version","pending_backup","created_at","size_bytes","service_id","service_label","subdomains","document_root","server_ips","tags","location","preview_domain","created","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No service on the account can take a new website, or service_id names none of them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: More than one service could take the site and service_id was not given; the description names them and what each takes.\n`rejected`: The panel or platform refused the site; the description carries its reason and nothing was created.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}":{"get":{"operationId":"get_website","tags":["Websites"],"summary":"Get a website","description":"One website on the account's hosting, by its domain (or an alias of it): status, PHP version, aliases and subdomains, document root, the server addresses it is served from, its size and tags, and the hosting service it belongs to.","x-mcp-tool":"get_website","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One website in full.","properties":{"domain":{"type":"string","description":"The website's primary domain; the input to the per-website operations."},"aliases":{"type":"array","description":"Other domains that reach the same website. On managed WordPress this includes the site's temporary address.","items":{"type":"string"}},"platform":{"type":"string","description":"hosting or managed_wordpress; decides which tools the website takes.","enum":["hosting","managed_wordpress"]},"status":{"type":["string","null"],"description":"active or disabled on hosting; active, pending, locked or deleting on managed WordPress."},"suspended":{"type":"boolean","description":"Whether the website is suspended. On managed WordPress only a lock the platform itself placed shows here; a suspend_website is not reported back."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"label":{"type":["string","null"],"description":"The name the site was given, apart from its domain; managed WordPress only, null on hosting."},"plan":{"type":["string","null"],"description":"The plan name on the panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83; null in a managed WordPress list row (the detail has it)."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running (hosting)."},"created_at":{"type":["string","null"],"description":"When the website was created."},"size_bytes":{"type":["integer","null"],"description":"Disk in use, as the panel last measured it; null when the panel does not count it (a cPanel account with quotas off)."},"service_id":{"type":"string","description":"The hosting service the website belongs to; works with the service detail."},"service_label":{"type":"string","description":"Its label on the account."},"subdomains":{"type":"array","description":"Subdomains mapped onto the website (hosting).","items":{"type":"string"}},"document_root":{"type":["string","null"],"description":"Where the primary domain is served from."},"server_ips":{"type":"array","description":"The addresses the website is served from.","items":{"type":"string"}},"tags":{"type":"array","description":"The panel's tags on the website (hosting).","items":{"type":"string"}},"location":{"type":["string","null"],"description":"The data centre the site is served from; managed WordPress only."},"preview_domain":{"type":["string","null"],"description":"A hostname the site answers on before its own domain resolves; managed WordPress only, create_website_preview gives the hosting one."}},"required":["domain","aliases","platform","status","suspended","kind","label","plan","php_version","pending_backup","created_at","size_bytes","service_id","service_label","subdomains","document_root","server_ips","tags","location","preview_domain"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/delete":{"post":{"operationId":"delete_website","tags":["Websites"],"summary":"Delete a website","description":"Deletes one of the account's websites on the control panel: the site goes offline at once with its files, databases and email, and cannot be restored from here. The domain is repeated as confirm_domain, and a mismatch is refused before anything is looked up. The website's domain registration, if the account holds one, is not affected.","x-mcp-tool":"delete_website","parameters":[{"name":"domain","in":"path","required":true,"description":"The website to delete, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this website, its files, databases and email are to be removed."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting a website.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service the website was on."},"service_label":{"type":"string","description":"Its label on the account."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"deleted":{"type":"boolean","description":"true: the panel has marked the website deleted (hosting keeps its data for its own retention; managed WordPress removes the site)."}},"required":["domain","service_id","service_label","platform","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`not_confirmed`: confirm_domain did not repeat the domain exactly; nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected","not_confirmed"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/access":{"get":{"operationId":"get_website_access","tags":["Websites"],"summary":"Get website access details","description":"Where to connect to deploy a website's code: the SSH/SFTP host, port and the website's own shell user, the document root the primary domain is served from, the server addresses and the database host. No secrets: access is by an SSH key added with the keys operation, and files are then copied with rsync, scp or git over SSH.","x-mcp-tool":"get_website_access","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"How to get onto a website to deploy it. No secrets: access is by SSH key.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"service_label":{"type":"string","description":"Its label on the account."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"ssh":{"type":"object","description":"Where to connect over SSH and SFTP.","properties":{"host":{"type":["string","null"],"description":"The hostname or address to connect to."},"port":{"type":"integer","description":"The SSH port."},"user":{"type":["string","null"],"description":"The website's own shell (and SFTP) user."},"enabled":{"type":["boolean","null"],"description":"Whether SSH is switched on: always true on hosting; on managed WordPress as the site's setting says (SFTP is always on), null when it could not be read."}},"required":["host","port","user","enabled"],"additionalProperties":false},"server_ips":{"type":"array","description":"The addresses the website is served from.","items":{"type":"string"}},"document_root":{"type":["string","null"],"description":"Where the primary domain is served from, relative to the shell user's home."},"database_host":{"type":["string","null"],"description":"Where the website's databases are reached from its own code; null on managed WordPress, where the database is reached from the site itself (run_wp_cli)."}},"required":["domain","service_id","service_label","platform","ssh","server_ips","document_root","database_host"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/ssh-keys":{"get":{"operationId":"list_website_ssh_keys","tags":["Websites"],"summary":"List website SSH keys","description":"The SSH public keys authorised to log in as a website's shell user, each with its key_id, name, type and SHA256 fingerprint (compare with ssh-keygen -lf on a key). The keys themselves are not repeated.","x-mcp-tool":"list_website_ssh_keys","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's SSH keys.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"keys":{"type":"array","description":"The keys registered for the shell user, with whether each may log in; the keys themselves are not repeated.","items":{"type":"object","properties":{"key_id":{"type":["string","null"],"description":"The handle the remove, authorize and deauthorize operations take."},"name":{"type":["string","null"],"description":"The name the key was added under."},"type":{"type":["string","null"],"description":"ssh-ed25519, ssh-rsa, ecdsa-sha2-nistp256 …"},"fingerprint":{"type":["string","null"],"description":"SHA256:… as ssh-keygen -lf prints it."},"authorized":{"type":"boolean","description":"Whether the key may log in now. A key added with add_website_ssh_key may on either platform; false only for a key switched off outside this API."},"created_at":{"type":["string","null"],"description":"When it was added."}},"required":["key_id","name","type","fingerprint","authorized","created_at"],"additionalProperties":false}}},"required":["domain","service_id","platform","keys"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"add_website_ssh_key","tags":["Websites"],"summary":"Add a website SSH key","description":"Authorises an SSH public key to log in as a website's shell user, so files can be deployed over SSH (rsync, scp, git). The public key only, never a private key. The key may log in as soon as this answers, on either platform; on managed WordPress it is registered under name (or a name made from its fingerprint) and switched on in the same call. The answer carries the key_id and fingerprint; the access details give the host and user to connect with. Refused when the key is not an OpenSSH public key or the platform will not accept it.","x-mcp-tool":"add_website_ssh_key","parameters":[{"name":"domain","in":"path","required":true,"description":"The website to give shell access to, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"public_key":{"type":"string","maxLength":8192,"pattern":"^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp(256|384|521)|sk-ssh-ed25519@openssh\\.com|sk-ecdsa-sha2-nistp256@openssh\\.com) [A-Za-z0-9+\\/]+={0,2}( [^\\r\\n]{0,255})?$","description":"An OpenSSH public key on one line, e.g. \"ssh-ed25519 AAAA… deploy@laptop\": the contents of a .pub file. Never a private key."},"name":{"type":"string","maxLength":100,"pattern":"^[\\p{L}\\p{N} ._@:\\-]+$","description":"A name to know the key by in the keys list, e.g. the machine or agent it belongs to. Defaults to the key's comment."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["public_key"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The key just added.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"key_id":{"type":["string","null"],"description":"The handle the remove, authorize and deauthorize operations take."},"name":{"type":["string","null"],"description":"The name the key was added under."},"type":{"type":"string","description":"The key type."},"fingerprint":{"type":"string","description":"SHA256:… as ssh-keygen -lf prints it."},"added":{"type":"boolean","description":"true: the key is registered."},"authorized":{"type":"boolean","description":"true: the key may log in now, on either platform."},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","service_id","platform","key_id","name","type","fingerprint","added","authorized","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the key, or refused to switch it on (in which case its registration was withdrawn again); the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/ssh-keys/{key_id}/remove":{"post":{"operationId":"remove_website_ssh_key","tags":["Websites"],"summary":"Remove a website SSH key","description":"Withdraws an SSH public key from a website's shell user, by the key_id the keys list shows. Access by that key ends at once; the key can be added again later.","x-mcp-tool":"remove_website_ssh_key","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"key_id","in":"path","required":true,"description":"The key to remove, as the keys list shows it under key_id.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of withdrawing a key.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"key_id":{"type":"string","description":"The key that was withdrawn."},"removed":{"type":"boolean","description":"true: access by that key has ended."}},"required":["domain","service_id","platform","key_id","removed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such key on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/label":{"post":{"operationId":"set_website_label","tags":["Websites"],"summary":"Set a website's label","description":"Managed WordPress sites only. Gives a managed WordPress site the label it shows in listings, apart from its domain. A hosting website is known by its domain alone and answers not_supported.","x-mcp-tool":"set_website_label","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[^\\x00-\\x1f\\x7f]{1,100}$","description":"The label to show, 1 to 100 characters, e.g. \"Acme Shop (production)\"."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["label"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of relabelling a site.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"label":{"type":"string","description":"The label now shown."},"updated":{"type":"boolean","description":"true: the platform has changed it."}},"required":["domain","service_id","platform","label","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the label; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/cache/purge":{"post":{"operationId":"purge_website_cache","tags":["Websites"],"summary":"Purge a website's cache","description":"Managed WordPress sites only. Drops everything the managed WordPress platform has cached for a site at its edge and on its server, so the next request is served fresh. Use after a change the site does not yet show. A hosting website has no platform cache and answers not_supported; restart_website_php clears its opcache.","x-mcp-tool":"purge_website_cache","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of purging a site's cache.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"purged":{"type":"boolean","description":"true: the platform has dropped everything it had cached for the site."}},"required":["domain","service_id","platform","purged"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/suspend":{"post":{"operationId":"suspend_website","tags":["Websites"],"summary":"Suspend a website","description":"Managed WordPress sites only. Takes a managed WordPress site offline until unsuspend_website: its database is cut, so visitors see an error page rather than the site. The site and its data are kept. The platform does not report this state back: get_website and list_websites keep showing status active and suspended false, and get_website answers php_version null while the site is suspended; keep your own note of what you suspended. The domain is repeated as confirm_domain; a mismatch is refused before anything is looked up. A hosting website answers not_supported.","x-mcp-tool":"suspend_website","parameters":[{"name":"domain","in":"path","required":true,"description":"The site to suspend, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this site is to be taken offline."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of suspending or unsuspending a site.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"suspended":{"type":"boolean","description":"Whether the site is suspended now."}},"required":["domain","service_id","platform","suspended"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`forbidden`: The account holder's platform login may not suspend sites; nothing was changed.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","forbidden","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no suspension of its own; nothing was sent. Also answered when the hosting service cannot be managed through this connection.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/unsuspend":{"post":{"operationId":"unsuspend_website","tags":["Websites"],"summary":"Unsuspend a website","description":"Managed WordPress sites only. Brings a suspended managed WordPress site back online for its visitors. Safe to call on a site that is not suspended. A hosting website answers not_supported.","x-mcp-tool":"unsuspend_website","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of suspending or unsuspending a site.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"suspended":{"type":"boolean","description":"Whether the site is suspended now."}},"required":["domain","service_id","platform","suspended"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`forbidden`: The account holder's platform login may not unsuspend sites (a suspension placed by the platform itself is lifted by support); nothing was changed.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","forbidden","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/visitors":{"get":{"operationId":"get_website_visitors","tags":["Websites"],"summary":"Get a website's visitors","description":"Managed WordPress sites only. The unique visitors a managed WordPress site had per day over the platform's current window, and their total: the count the plan's visitor limit is measured against. A hosting website has no platform visitor count and answers not_supported.","x-mcp-tool":"get_website_visitors","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A site's visitors as the platform counts them.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"visitors":{"type":"array","description":"Visitors per day over the platform's current window.","items":{"type":"object","properties":{"date":{"type":"string","description":"The day, as the platform dates it."},"visitors":{"type":"integer","description":"Unique visitors that day."}},"required":["date","visitors"],"additionalProperties":false}},"total":{"type":["integer","null"],"description":"Visitors over the window; null when the platform gave no total."}},"required":["domain","service_id","platform","visitors","total"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/main-domain":{"post":{"operationId":"set_website_main_domain","tags":["Websites"],"summary":"Set a website's main domain","description":"Managed WordPress sites only. Points a managed WordPress site at the user's own domain, in place of the temporary address the platform gave it at creation or of the domain it has now; WordPress's own address is updated with it. The site is addressed by the name it answers to now, and by main_domain in every website tool afterwards. The user then points the domain's DNS at the site as get_website_access shows. Refused, with nothing changed, when main_domain is already a website on the account. A hosting website answers not_supported; add_website_domain adds a name to one.","x-mcp-tool":"set_website_main_domain","parameters":[{"name":"domain","in":"path","required":true,"description":"The site, by the name it answers to now (its temporary address or its current domain), as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"main_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain the site is to answer on as its own, e.g. example.com or www.example.com. The user points the domain's DNS at the site afterwards, as get_website_access shows."},"keep_temporary_domain":{"type":"boolean","description":"true: keep answering on the temporary address too. false unless given; only honoured the first time a site is given its own domain.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["main_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of setting a site's main domain.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"main_domain":{"type":"string","description":"The domain the site now answers on as its own, and is addressed by in every website tool."},"previous_domain":{"type":"string","description":"The name it was addressed by before."},"updated":{"type":"boolean","description":"true: the platform has changed it."},"next_steps":{"type":"array","description":"What follows.","items":{"type":"string"}}},"required":["domain","service_id","platform","main_domain","previous_domain","updated","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: main_domain is already a website on this account, is already the site's main domain, or the platform refused it; the description carries the reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/tasks":{"get":{"operationId":"list_website_tasks","tags":["Websites"],"summary":"List website tasks","description":"Managed WordPress sites only. The background tasks the managed WordPress platform has run or is running for a site (backups, restores, staging copies, publishes, the initial build), newest first, filtered by status or type when asked. A write that starts a task answers its task_id with status queued; this list and get_website_task follow it to DONE, ERROR or CANCELLED. A hosting website's changes complete within the call that made them, so it answers not_supported.","x-mcp-tool":"list_website_tasks","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"status","in":"query","required":false,"description":"Only tasks in this state: NEW, PROGRESS, DONE, ERROR or CANCELLED. Every state unless given.","schema":{"type":"string","enum":["NEW","PROGRESS","DONE","ERROR","CANCELLED"]}},{"name":"type","in":"query","required":false,"description":"Only tasks of this kind: automated_restore, backup, clone_site, cloud_backup_create, cloud_backup_restore, publish, restore, staging. Every kind unless given.","schema":{"type":"string","enum":["automated_restore","backup","clone_site","cloud_backup_create","cloud_backup_restore","publish","restore","staging"]}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A managed WordPress site's background tasks.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"tasks":{"type":"array","description":"The site's tasks, newest first as the platform lists them.","items":{"type":"object","description":"One background task on a managed WordPress site.","properties":{"task_id":{"type":"string","description":"The task; what get_website_task and cancel_website_task take."},"type":{"type":["string","null"],"description":"What the task is: automated_restore, backup, clone_site, cloud_backup_create, cloud_backup_restore, publish, restore, staging."},"status":{"type":["string","null"],"description":"NEW or PROGRESS while running; DONE, ERROR or CANCELLED once finished.","enum":["NEW","PROGRESS","DONE","ERROR","CANCELLED",null]},"percent":{"type":["integer","null"],"description":"How far along, 0 to 100, when the platform says."},"message":{"type":["string","null"],"description":"What the platform says about the task; the error when it failed."},"created_at":{"type":["string","null"],"description":"When the task was started."},"updated_at":{"type":["string","null"],"description":"When the platform last changed it."}},"required":["task_id","type","status","percent","message","created_at","updated_at"],"additionalProperties":false}}},"required":["domain","service_id","platform","tasks"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/tasks/{task_id}":{"get":{"operationId":"get_website_task","tags":["Websites"],"summary":"Get a website task","description":"Managed WordPress sites only. One background task on a managed WordPress site, by the task_id a write answered: its status (NEW or PROGRESS while running; DONE, ERROR or CANCELLED once finished), how far along it is and what the platform says about it. Poll this, a few seconds apart, after a write answered status queued. A hosting website answers not_supported.","x-mcp-tool":"get_website_task","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"task_id","in":"path","required":true,"description":"The task, by the task_id a write answered or the tasks list shows.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One background task in full.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"task_id":{"type":"string","description":"The task; what get_website_task and cancel_website_task take."},"type":{"type":["string","null"],"description":"What the task is: automated_restore, backup, clone_site, cloud_backup_create, cloud_backup_restore, publish, restore, staging."},"status":{"type":["string","null"],"description":"NEW or PROGRESS while running; DONE, ERROR or CANCELLED once finished.","enum":["NEW","PROGRESS","DONE","ERROR","CANCELLED",null]},"percent":{"type":["integer","null"],"description":"How far along, 0 to 100, when the platform says."},"message":{"type":["string","null"],"description":"What the platform says about the task; the error when it failed."},"created_at":{"type":["string","null"],"description":"When the task was started."},"updated_at":{"type":["string","null"],"description":"When the platform last changed it."}},"required":["domain","service_id","platform","task_id","type","status","percent","message","created_at","updated_at"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such task on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/tasks/{task_id}/cancel":{"post":{"operationId":"cancel_website_task","tags":["Websites"],"summary":"Cancel a website task","description":"Managed WordPress sites only. Asks the managed WordPress platform to stop a running background task on a site, by its task_id. A task already finished cannot be cancelled and is refused; what a cancelled restore or publish leaves behind is the platform's, so read the site back afterwards. A hosting website answers not_supported.","x-mcp-tool":"cancel_website_task","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"task_id","in":"path","required":true,"description":"The task, by the task_id a write answered or the tasks list shows.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of cancelling a task.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"task_id":{"type":"string","description":"The task that was cancelled."},"cancelled":{"type":"boolean","description":"true: the platform has accepted the cancellation; get_website_task shows CANCELLED once it has stopped."}},"required":["domain","service_id","platform","task_id","cancelled"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such task on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The task has already finished, or the platform refused to stop it; the description carries its reason.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/preview":{"post":{"operationId":"create_website_preview","tags":["Websites"],"summary":"Create a website preview hostname","description":"Gives a website a preview hostname on the control panel's own domain, so the site can be opened and tested before its real domain resolves. Answers the existing one when the website already has it; a new website's answer already carries its preview_domain.","x-mcp-tool":"create_website_preview","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's preview hostname.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"preview_domain":{"type":["string","null"],"description":"The hostname to open the site on right now."}},"required":["domain","service_id","preview_domain"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/checklist":{"get":{"operationId":"get_website_launch_checklist","tags":["Websites"],"summary":"Get a website's launch checklist","description":"One read of everything that says whether a website is ready: its status and PHP version, each of its domains with the DNS status the control panel sees for it, whether the domain already points at the hosting's nameservers (nameservers.delegated, with the expected ones named) and whether it is registered in this account, the SSL certificate if one is installed, the applications and persistent apps, its preview hostname and how many SSH keys are authorised. Every field is an observation; nothing here waits or blocks. The notes are the closing hand-over of a deploy.","x-mcp-tool":"get_website_launch_checklist","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Everything that says whether a website is ready.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"service_label":{"type":"string","description":"Its label on the account."},"status":{"type":["string","null"],"description":"active or disabled."},"suspended":{"type":"boolean","description":"Whether the website is suspended."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83."},"preview_domain":{"type":["string","null"],"description":"The control panel's preview hostname, for testing before the domain resolves."},"domains":{"type":["array","null"],"description":"Each of the website's domains with the DNS status the panel sees for it; null when they could not be read.","items":{"type":"object","properties":{"domain":{"type":"string","description":"The mapped domain."},"kind":{"type":"string","description":"primary, alias, addon or subdomain."},"dns_status":{"type":"string","description":"resolved, foreign_server, failed, mixed, unknown or error, as the control panel sees it."}},"required":["domain","kind","dns_status"],"additionalProperties":false}},"ssl":{"type":["object","null"],"description":"The installed certificate; null when none is installed.","properties":{"issued":{"type":"boolean","description":"Whether a certificate is issued."},"issuer":{"type":["string","null"],"description":"Who issued it."},"common_name":{"type":["string","null"],"description":"The name it is issued to."},"names":{"type":"array","description":"Every name it covers.","items":{"type":"string"}},"issued_at":{"type":["string","null"],"description":"When it was issued."},"expires_at":{"type":["string","null"],"description":"When it expires."},"force_https":{"type":"boolean","description":"Whether http redirects to https."}},"required":["issued","issuer","common_name","names","issued_at","expires_at","force_https"],"additionalProperties":false},"apps":{"type":["array","null"],"description":"The installed applications; null when they could not be read.","items":{"type":"object","properties":{"app":{"type":"string","description":"The kind, as the control panel names it."},"version":{"type":["string","null"],"description":"Its version; null while the panel is still installing it."},"path":{"type":["string","null"],"description":"The folder under the website root; null for the root itself."}},"required":["app","version","path"],"additionalProperties":false}},"persistent_apps":{"type":["array","null"],"description":"The long-running processes behind the site; null when they could not be read.","items":{"type":"object","properties":{"command":{"type":["string","null"],"description":"What it runs."},"working_directory":{"type":["string","null"],"description":"The folder it runs in, relative to the shell user's home."},"start_mode":{"type":["string","null"],"description":"automatic or manual."},"node_version":{"type":["string","null"],"description":"The Node version it runs under."},"path":{"type":["string","null"],"description":"The URL path proxied to the app; null for a worker."},"port":{"type":["integer","null"],"description":"The local port it listens on."}},"required":["command","working_directory","start_mode","node_version","path","port"],"additionalProperties":false}},"ssh_keys":{"type":["integer","null"],"description":"How many shell keys are authorised."},"nameservers":{"type":"object","description":"Whether the domain already points at the hosting.","properties":{"expected":{"type":"array","description":"The hosting's nameservers, as the hosting service records them.","items":{"type":"string"}},"current":{"type":"array","description":"The nameservers the domain has now, from a DNS lookup.","items":{"type":"string"}},"delegated":{"type":["boolean","null"],"description":"true when the domain already points at the hosting's nameservers; null when that could not be told."},"in_account":{"type":["boolean","null"],"description":"true when the domain is registered in this account, so its nameservers can be set here."},"registered_domain":{"type":["string","null"],"description":"The name the account holds (the domain, or its registrable parent for a site on a subdomain): what the nameservers change takes."}},"required":["expected","current","delegated","in_account","registered_domain"],"additionalProperties":false},"notes":{"type":"array","description":"The closing hand-over of a deploy, to relay word for word; never absolute about DNS.","items":{"type":"string"}}},"required":["domain","service_id","service_label","status","suspended","php_version","preview_domain","domains","ssl","apps","persistent_apps","ssh_keys","nameservers","notes"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/deploy-plan":{"get":{"operationId":"plan_website_deploy","tags":["Websites"],"summary":"Plan a website deploy","description":"For a domain (a website already, or not yet): the questions to settle up front (which hosting service when there are several, what kind of site from what this hosting can set up, what that kind needs), the steps for the kind with those already done marked, and the closing hand-over to say at the end. Read-only: it changes nothing.","x-mcp-tool":"plan_website_deploy","parameters":[{"name":"domain","in":"path","required":true,"description":"The domain the website is (or will be) for, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"kind","in":"query","required":false,"description":"What kind of site, when known: a kind from kinds_available (an application the hosting can install, e.g. wordpress; php; static; node). Omit to be told what to ask.","schema":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,63}$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service, once chosen; only needed when the account has more than one that can hold websites.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The plan for building or deploying a website.","properties":{"domain":{"type":"string","description":"The domain the website is, or will be, for."},"exists":{"type":"boolean","description":"Whether the website already exists."},"service_id":{"type":["string","null"],"description":"The hosting service, once known."},"service_label":{"type":["string","null"],"description":"Its label on the account."},"services":{"type":"array","description":"The hosting services that can hold websites.","items":{"type":"object","properties":{"service_id":{"type":"string","description":"A hosting service."},"label":{"type":"string","description":"Its label on the account."}},"required":["service_id","label"],"additionalProperties":false}},"preview_domain":{"type":["string","null"],"description":"The preview hostname when the site has one; for the closing hand-over."},"kind":{"type":["string","null"],"description":"The kind of site, once settled."},"kinds_available":{"type":"array","description":"What this hosting can set up.","items":{"type":"object","properties":{"kind":{"type":"string","description":"The kind, as the plan takes it."},"label":{"type":"string","description":"Its name for a person."},"how":{"type":"string","description":"How a site of this kind is finished."},"needs_shell":{"type":"boolean","description":"true: finishing this kind means copying code over SSH from a shell."}},"required":["kind","label","how","needs_shell"],"additionalProperties":false}},"questions":{"type":"array","description":"What to settle before the first change.","items":{"type":"string"}},"steps":{"type":"array","description":"The steps for the kind, those already done marked.","items":{"type":"object","properties":{"tool":{"type":["string","null"],"description":"The operation the step is done with; null for a step done elsewhere."},"why":{"type":"string","description":"What the step is for."},"done":{"type":"boolean","description":"Whether it is already done."}},"required":["tool","why","done"],"additionalProperties":false}},"nameservers":{"type":"object","description":"Whether the domain already points at the hosting.","properties":{"expected":{"type":"array","description":"The hosting's nameservers, as the hosting service records them.","items":{"type":"string"}},"current":{"type":"array","description":"The nameservers the domain has now, from a DNS lookup.","items":{"type":"string"}},"delegated":{"type":["boolean","null"],"description":"true when the domain already points at the hosting's nameservers; null when that could not be told."},"in_account":{"type":["boolean","null"],"description":"true when the domain is registered in this account, so its nameservers can be set here."},"registered_domain":{"type":["string","null"],"description":"The name the account holds (the domain, or its registrable parent for a site on a subdomain): what the nameservers change takes."}},"required":["expected","current","delegated","in_account","registered_domain"],"additionalProperties":false},"closing":{"type":"array","description":"What to say at the end, word for word, and not before.","items":{"type":"string"}}},"required":["domain","exists","service_id","service_label","services","preview_domain","kind","kinds_available","questions","steps","nameservers","closing"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/installable-apps":{"get":{"operationId":"list_installable_apps","tags":["Websites"],"summary":"List installable applications","description":"The applications a website's hosting service can install right now, read live from the control panel: each kind with its versions (the latest flagged), a description and its size. The list is the hosting plan's and changes over time; the install operation takes a kind and version exactly as listed here.","x-mcp-tool":"list_installable_apps","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The applications a website's hosting can install.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"apps":{"type":"array","description":"What the hosting service can install right now.","items":{"type":"object","properties":{"app":{"type":"string","description":"The kind, exactly as the install operation takes it."},"description":{"type":["string","null"],"description":"What it is."},"latest_version":{"type":["string","null"],"description":"The newest version offered."},"versions":{"type":"array","description":"The versions offered.","items":{"type":"object","properties":{"version":{"type":"string","description":"A version offered."},"latest":{"type":"boolean","description":"Whether it is the newest."},"size_bytes":{"type":["integer","null"],"description":"Its size."}},"required":["version","latest","size_bytes"],"additionalProperties":false}}},"required":["app","description","latest_version","versions"],"additionalProperties":false}}},"required":["domain","service_id","apps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/apps":{"get":{"operationId":"list_website_apps","tags":["Websites"],"summary":"List website applications","description":"The applications installed on a website, each with its kind, version and the folder it is installed in (null for the website root).","x-mcp-tool":"list_website_apps","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The applications installed on a website.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"apps":{"type":"array","description":"The installed applications.","items":{"type":"object","properties":{"app":{"type":"string","description":"The kind, as the control panel names it."},"version":{"type":["string","null"],"description":"Its version; null while the panel is still installing it."},"path":{"type":["string","null"],"description":"The folder under the website root; null for the root itself."}},"required":["app","version","path"],"additionalProperties":false}}},"required":["domain","service_id","apps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"install_website_app","tags":["Websites"],"summary":"Install a website application","description":"Installs an application (for example WordPress) on a website, at its root or in a folder, with the first administrator given. app and version must be exactly as the installable applications list gives them: anything the hosting service does not list is refused with nothing installed, the refusal naming what it does offer. The password is sent to the control panel and never echoed back. The install continues on the panel's side and may take a minute or more: status says installing until the installed applications list shows a real version.","x-mcp-tool":"install_website_app","parameters":[{"name":"domain","in":"path","required":true,"description":"The website to install on, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,63}$","description":"The application kind, exactly as the installable applications list shows it for this website's hosting service. Only what that listing offers can be installed."},"version":{"type":"string","pattern":"^[0-9A-Za-z][0-9A-Za-z.+-]{0,63}$","description":"A version the installable applications list gives for that kind. Omit for the latest it offers."},"path":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"A folder under the website root to install in, e.g. blog. Omit to install at the root."},"on_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"One of the website's mapped domains to install on, as the launch checklist lists them. Omit for the primary domain."},"admin_username":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[A-Za-z0-9._@-]+$","description":"The application's first administrator login."},"admin_password":{"type":"string","minLength":8,"maxLength":128,"description":"That administrator's password, chosen by the user; sent to the control panel and never echoed back."},"admin_email":{"type":"string","maxLength":254,"format":"email","description":"That administrator's email address."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["app","admin_username","admin_password","admin_email"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The outcome of installing an application.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app":{"type":"string","description":"The kind installed."},"version":{"type":["string","null"],"description":"The version asked for; null for the latest."},"path":{"type":["string","null"],"description":"The folder installed in; null for the root."},"on_domain":{"type":["string","null"],"description":"The mapped domain installed on; null for the primary."},"admin_username":{"type":"string","description":"The first administrator's login. On cPanel this is the one WordPress Toolkit named, not the one sent; next_steps says so."},"installed":{"type":"boolean","description":"The control panel has taken the install."},"status":{"type":"string","description":"installing: the panel is still setting it up (the installed list shows it with no real version yet). installed: it is ready.","enum":["installing","installed"]},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","service_id","app","version","path","on_domain","admin_username","installed","status","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/apps/remove":{"post":{"operationId":"remove_website_app","tags":["Websites"],"summary":"Remove a website application","description":"Removes an installed application and its data from a website, by its kind (and its folder when that kind is installed more than once). This cannot be undone from here; the domain is repeated as confirm_domain. Refused with not_found when no such application is installed.","x-mcp-tool":"remove_website_app","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that the application and its data are to be removed from this website."},"app":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,63}$","description":"The application kind, as the installed applications list shows it."},"path":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder it is installed in, as the installed applications list shows it; needed only when that kind is installed more than once."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain","app"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of removing an application.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app":{"type":"string","description":"The kind removed."},"path":{"type":["string","null"],"description":"The folder it was installed in."},"removed":{"type":"boolean","description":"true: the application and its data are gone."}},"required":["domain","service_id","app","path","removed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such application installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_domain did not repeat the domain exactly; nothing was changed.\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/wordpress":{"get":{"operationId":"get_wordpress","tags":["Websites"],"summary":"Get a WordPress installation","description":"A website's WordPress installation as its platform sees it: version, site URL, whether maintenance mode is on, how many plugins and users it has and whether WooCommerce is installed. path names the installation when WordPress is installed more than once. On managed WordPress the site is one WordPress at its root (path is refused as not_found): the answer carries health (operational, or critical_error with the fatal error the platform saw) and the plugin count, while version, users and maintenance mode are null, read with run_wp_cli when needed.","x-mcp-tool":"get_wordpress","parameters":[{"name":"domain","in":"path","required":true,"description":"The website the WordPress installation is on, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"path","in":"query","required":false,"description":"The folder WordPress is installed in, as the installed applications list shows it; needed only when it is installed more than once on the website.","schema":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A WordPress installation as its platform sees it.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"hosting or managed_wordpress: a managed WordPress site is one WordPress at its root, and its version, users and maintenance mode are not reported here (run_wp_cli reads them).","enum":["hosting","managed_wordpress"]},"app":{"type":"string","description":"wordpress."},"path":{"type":["string","null"],"description":"The folder it is installed in; null for the root."},"version":{"type":["string","null"],"description":"The WordPress core version."},"site_url":{"type":["string","null"],"description":"The URL the site answers on."},"maintenance_mode":{"type":["boolean","null"],"description":"Whether maintenance mode is on; null on managed WordPress, which does not report it."},"plugins":{"type":["integer","null"],"description":"How many plugins it has."},"users":{"type":["integer","null"],"description":"How many users it has; null on managed WordPress."},"woocommerce":{"type":["boolean","null"],"description":"Whether WooCommerce is installed."},"health":{"type":["string","null"],"description":"Whether the site runs normally (operational) or is broken (critical_error), as managed WordPress and cPanel's WordPress Toolkit report it; null on other hosting, which does not.","enum":["operational","critical_error","not_applicable","unknown",null]},"health_error":{"type":["string","null"],"description":"What the platform saw, when health is critical_error."}},"required":["domain","service_id","platform","app","path","version","site_url","maintenance_mode","plugins","users","woocommerce","health","health_error"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management, or managed WordPress, was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no WordPress installed on it (at that path).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/wordpress/login-link":{"post":{"operationId":"get_wordpress_login_link","tags":["Websites"],"summary":"Get a WordPress login link","description":"A one-time link that signs in to a website's WordPress admin as its default administrator, or as the named user. The link is a credential for the account holder alone and expires quickly. A POST because each call mints a new link. On managed WordPress the platform signs in as the site's administrator only: username is refused (rejected) and path as not_found.","x-mcp-tool":"get_wordpress_login_link","parameters":[{"name":"domain","in":"path","required":true,"description":"The website the WordPress installation is on, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder WordPress is installed in, as the installed applications list shows it; needed only when it is installed more than once on the website."},"username":{"type":"string","maxLength":60,"pattern":"^[A-Za-z0-9._@-]+$","description":"The WordPress user to sign in as. Omit for the installation's default administrator."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A one-time WordPress login link.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":["string","null"],"description":"The folder WordPress is installed in."},"username":{"type":["string","null"],"description":"The user the link signs in as; null for the default administrator."},"login_url":{"type":"string","description":"One-time; a credential for the account holder alone."}},"required":["domain","service_id","path","username","login_url"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, no WordPress installed on it, or no such user.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change, or username was given for a managed WordPress site, which signs in as its administrator only; the description carries the reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/wordpress/update":{"post":{"operationId":"update_wordpress_version","tags":["Websites"],"summary":"Update WordPress core","description":"Hosting websites only. Updates a website's WordPress core to the latest version the control panel offers. Answers the version afterwards when the panel reports it. On managed WordPress the platform has no such route: run_wp_cli with core update does it, and this answers not_supported.","x-mcp-tool":"update_wordpress_version","parameters":[{"name":"domain","in":"path","required":true,"description":"The website the WordPress installation is on, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder WordPress is installed in, as the installed applications list shows it; needed only when it is installed more than once on the website."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of updating WordPress core.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":["string","null"],"description":"The folder WordPress is installed in."},"version":{"type":["string","null"],"description":"The core version afterwards, when the panel reports it."},"updated":{"type":"boolean","description":"true: the panel has taken the update."}},"required":["domain","service_id","path","version","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no WordPress installed on it (at that path).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/wordpress/url":{"post":{"operationId":"set_wordpress_url","tags":["Websites"],"summary":"Set the WordPress site URL","description":"Hosting websites only. Changes the site URL a website's WordPress answers on, e.g. from the preview hostname it was built on to https://example.com once the domain resolves (the launch checklist shows when it does). A wrong URL makes the site redirect to an address that does not serve it. On managed WordPress, set_website_main_domain points the site at its domain and the platform adjusts WordPress itself; this answers not_supported.","x-mcp-tool":"set_wordpress_url","parameters":[{"name":"domain","in":"path","required":true,"description":"The website the WordPress installation is on, by its domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder WordPress is installed in, as the installed applications list shows it; needed only when it is installed more than once on the website."},"url":{"type":"string","maxLength":255,"pattern":"^https?:\\/\\/[A-Za-z0-9.-]+(:[0-9]{2,5})?(\\/[^\\s]*)?$","description":"The site URL WordPress should use from now on, e.g. https://example.com, once the domain resolves; a site built on the preview hostname needs this to go live on its own domain."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["url"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of changing the WordPress site URL.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":["string","null"],"description":"The folder WordPress is installed in."},"site_url":{"type":"string","description":"The URL the site answers on from now on."},"updated":{"type":"boolean","description":"true: the panel has changed it."}},"required":["domain","service_id","path","site_url","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no WordPress installed on it (at that path).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/wordpress/cli":{"post":{"operationId":"run_wp_cli","tags":["Websites"],"summary":"Run a WP-CLI command","description":"Managed WordPress sites only. Runs one WP-CLI command on a managed WordPress site and answers what it printed, within about a minute; long output is cut and says so. Use it for what no other tool does: reading or setting options (option get siteurl, option update blogname Shop), users, the core version (core version, core update), search-replace, cache flush, cron. Prefer the dedicated tools for plugins and themes, which report the platform's outcome per item. A command that changes the site is a change like any other: tell the user what it will do first. The command text is never logged; a password it carries stays between the user and the site. A hosting website answers not_supported.","x-mcp-tool":"run_wp_cli","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site to run the command on, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"command":{"type":"string","minLength":1,"maxLength":2000,"pattern":"^[^\\x00-\\x1f\\x7f]+$","description":"The WP-CLI command without the leading wp, on one line, e.g. \"option get siteurl\", \"plugin list --format=json\", \"cache flush\". Up to 2000 characters. Treat any password it carries as a secret: never repeat it."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["command"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The output of one WP-CLI command.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"command_summary":{"type":"string","description":"The command's first two words, as the audit trail records them."},"command_length":{"type":"integer","description":"The command's length in characters."},"output":{"type":"string","description":"What WP-CLI printed, standard output and errors together, as the platform relays it."},"truncated":{"type":"boolean","description":"true when the output was longer than this answer carries and was cut."},"bytes":{"type":"integer","description":"The full output's length in bytes."}},"required":["domain","service_id","platform","command_summary","command_length","output","truncated","bytes"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused to run the command; the description carries its reason.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins":{"get":{"operationId":"list_website_plugins","tags":["Websites"],"summary":"List a website's plugins","description":"Managed WordPress sites only. The plugins installed on a managed WordPress site: slug, title, whether active, version and whether the WordPress directory has a newer one. search narrows by slug or title. A hosting website answers not_supported: its plugins are managed from its WordPress admin.","x-mcp-tool":"list_website_plugins","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"search","in":"query","required":false,"description":"Only installed plugins whose slug or title contains this.","schema":{"type":"string","maxLength":100}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A managed WordPress site's installed plugins.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"plugins":{"type":"array","description":"The plugins installed on the site, as the platform orders them.","items":{"type":"object","description":"One installed plugin.","properties":{"name":{"type":"string","description":"The plugin's slug; what the other plugin tools take."},"title":{"type":["string","null"],"description":"Its display name."},"status":{"type":["string","null"],"description":"active, inactive, must-use or dropin (the last two cannot be removed here)."},"version":{"type":["string","null"],"description":"The installed version."},"update_available":{"type":"boolean","description":"Whether the directory has a newer version."},"update_version":{"type":["string","null"],"description":"The newer version, when there is one."}},"required":["name","title","status","version","update_available","update_version"],"additionalProperties":false}}},"required":["domain","service_id","platform","plugins"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"install_website_plugins","tags":["Websites"],"summary":"Install plugins","description":"Managed WordPress sites only. Installs plugins on a managed WordPress site from the WordPress directory, by slug (up to ten at once, as list_website_plugins or search_website_plugins name them), or one from an https download URL (custom_url), and activates them when activate is true. The platform answers one row per plugin with a note: already installed, not found, or what prevented it; the call succeeds even when a plugin did not install, so read the notes. Tell the user which plugins and whether they will be activated before calling this. A hosting website answers not_supported.","x-mcp-tool":"install_website_plugins","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site to install the plugins on, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"plugins":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"},"description":"The plugins to install, by slug, 1 to 10 at once, e.g. [\"akismet\", \"wordpress-seo\"]. Not with custom_url."},"custom_url":{"type":"string","maxLength":2000,"pattern":"^https:\\/\\/[A-Za-z0-9.-]+(\\/[^\\s]*)?$","description":"An https URL of a plugin zip to install instead of a directory plugin, e.g. a purchased plugin. Not with plugins."},"activate":{"type":"boolean","description":"Whether to activate the plugins once installed. false unless given.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of installing plugins.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"requested":{"type":"array","description":"The slugs asked for, or the one download URL.","items":{"type":"string"}},"activate":{"type":"boolean","description":"Whether activation was asked for."},"installed":{"type":"array","description":"One row per item, in the platform's words; read each note.","items":{"type":"object","description":"The outcome of installing one plugin.","properties":{"name":{"type":["string","null"],"description":"The plugin's slug."},"version":{"type":["string","null"],"description":"The version installed."},"activated":{"type":["boolean","null"],"description":"Whether it is active now."},"note":{"type":["string","null"],"description":"The platform's word on it: already installed, not found in the directory, a PHP error that prevented it, and so on. Empty when nothing is to be said."}},"required":["name","version","activated","note"],"additionalProperties":false}},"next_steps":{"type":"array","description":"What follows.","items":{"type":"string"}}},"required":["domain","service_id","platform","requested","activate","installed","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the install; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins/search":{"get":{"operationId":"search_website_plugins","tags":["Websites"],"summary":"Search the plugin directory","description":"Managed WordPress sites only. Searches the WordPress plugin directory, through the managed WordPress platform, for plugins to install on a site: by words (query), or browsing the new, popular or top-rated ones (browse). Each result's name is the slug install_website_plugins takes, and status says whether the site already has it. Pages of limit results, from page 1. A hosting website answers not_supported.","x-mcp-tool":"search_website_plugins","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"query","in":"query","required":false,"description":"Words to search the WordPress plugin directory for, e.g. \"contact form\". Without it the directory is browsed (browse, popular by default).","schema":{"type":"string","minLength":2,"maxLength":100}},{"name":"browse","in":"query","required":false,"description":"Browse the directory instead of searching: new, popular or top-rated plugins. One of query or browse.","schema":{"type":"string","enum":["new","popular","top-rated"]}},{"name":"page","in":"query","required":false,"description":"The page of results, from 1.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1}},{"name":"limit","in":"query","required":false,"description":"Results per page, 1 to 50.","schema":{"type":"integer","minimum":1,"maximum":50,"default":10}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The WordPress plugin directory, searched through the platform.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"query":{"type":["string","null"],"description":"The words searched for; null when browsing."},"browse":{"type":["string","null"],"description":"new, popular or top-rated when browsing; null when searching by words."},"page":{"type":"integer","description":"The page answered."},"limit":{"type":"integer","description":"Results per page."},"total":{"type":["integer","null"],"description":"Results across every page, when the directory says."},"results":{"type":"array","description":"This page of the directory's results.","items":{"type":"object","description":"One plugin the WordPress directory offers.","properties":{"name":{"type":"string","description":"The plugin's slug; what install_website_plugins takes."},"title":{"type":["string","null"],"description":"Its display name."},"status":{"type":["string","null"],"description":"active, inactive or not_installed on this site."},"version":{"type":["string","null"],"description":"The version the directory offers."},"description":{"type":["string","null"],"description":"The author's description, in short."},"rating":{"type":["integer","null"],"description":"The directory's rating out of 100."},"ratings":{"type":["integer","null"],"description":"How many rated it."},"active_installs":{"type":["integer","null"],"description":"How many sites run it, as the directory counts."},"homepage":{"type":["string","null"],"description":"The plugin's home page."}},"required":["name","title","status","version","description","rating","ratings","active_installs","homepage"],"additionalProperties":false}}},"required":["domain","service_id","platform","query","browse","page","limit","total","results"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins/featured":{"get":{"operationId":"list_featured_plugins","tags":["Websites"],"summary":"List recommended plugins","description":"Managed WordPress sites only. The plugins the managed WordPress platform recommends for its sites (caching, security, SEO and the like), each with whether the site already has it installed or active. Each name is the slug install_website_plugins takes. A hosting website answers not_supported.","x-mcp-tool":"list_featured_plugins","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The plugins the platform recommends.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"plugins":{"type":"array","description":"The platform's recommended plugins, with whether each is on the site.","items":{"type":"object","description":"One plugin the platform recommends for its sites.","properties":{"name":{"type":"string","description":"The plugin's slug; what install_website_plugins takes."},"title":{"type":["string","null"],"description":"Its display name."},"status":{"type":["string","null"],"description":"active, inactive or not_installed on this site."},"version":{"type":["string","null"],"description":"The installed version, when installed."},"update_available":{"type":"boolean","description":"Whether a newer version exists, when installed."},"description":{"type":["string","null"],"description":"Why the platform recommends it."}},"required":["name","title","status","version","update_available","description"],"additionalProperties":false}}},"required":["domain","service_id","platform","plugins"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins/{plugin}/status":{"post":{"operationId":"set_website_plugin_status","tags":["Websites"],"summary":"Activate or deactivate a plugin","description":"Managed WordPress sites only. Activates (active: true) or deactivates an installed plugin on a managed WordPress site, by slug. Deactivating keeps the plugin and its data; uninstall_website_plugins removes them. A plugin that is not installed is not_found before anything is sent. A hosting website answers not_supported.","x-mcp-tool":"set_website_plugin_status","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site the plugin is installed on, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"plugin","in":"path","required":true,"description":"The plugin, by its slug exactly as list_website_plugins shows it (name), e.g. akismet.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean","description":"true activates the plugin, false deactivates it."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["active"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of activating or deactivating a plugin.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"plugin":{"type":"string","description":"The plugin's slug."},"active":{"type":"boolean","description":"Whether it is active now."},"updated":{"type":"boolean","description":"true: the platform has applied the change."}},"required":["domain","service_id","platform","plugin","active","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such plugin installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins/{plugin}/update":{"post":{"operationId":"update_website_plugin","tags":["Websites"],"summary":"Update a plugin","description":"Managed WordPress sites only. Updates one installed plugin on a managed WordPress site to the version the WordPress directory offers (list_website_plugins shows update_available and update_version). Answers the version before and after and the platform's note; a plugin already current says so. Tell the user which plugin and the versions before calling this. A hosting website answers not_supported.","x-mcp-tool":"update_website_plugin","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"plugin","in":"path","required":true,"description":"The plugin, by its slug exactly as list_website_plugins shows it (name), e.g. akismet.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of updating a plugin.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"plugin":{"type":"string","description":"The plugin's slug."},"previous_version":{"type":["string","null"],"description":"The version before."},"version":{"type":["string","null"],"description":"The version now."},"note":{"type":["string","null"],"description":"The platform's word on it: updated, or already up to date."},"updated":{"type":"boolean","description":"true: the platform has run the update."}},"required":["domain","service_id","platform","plugin","previous_version","version","note","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such plugin installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the update; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/plugins/uninstall":{"post":{"operationId":"uninstall_website_plugins","tags":["Websites"],"summary":"Uninstall plugins","description":"Managed WordPress sites only. Removes installed plugins from a managed WordPress site, by slug, up to ten at once, with their code and their data; this cannot be undone from here. Must-use and drop-in plugins are refused. Confirm the exact plugins and the domain with the user and pass the domain again as confirm_domain; a mismatch is refused before anything is looked up. A hosting website answers not_supported.","x-mcp-tool":"uninstall_website_plugins","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site to remove the plugins from, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plugins":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"},"description":"The plugins to remove, by slug, 1 to 10 at once, e.g. [\"akismet\", \"wordpress-seo\"]."},"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that each plugin named, with its data, is to be removed from this site."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["plugins","confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of removing plugins.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"removed":{"type":"array","description":"One row per item, in the platform's words.","items":{"type":"object","description":"The outcome of removing one plugin.","properties":{"name":{"type":["string","null"],"description":"The plugin's slug."},"note":{"type":["string","null"],"description":"deleted, or the platform's reason it was not."}},"required":["name","note"],"additionalProperties":false}}},"required":["domain","service_id","platform","removed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or a named plugin is not installed on it; nothing was removed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no plugin to remove; nothing was sent. A hosting website's plugins are managed from its WordPress admin (get_wordpress_login_link). Also answered when the hosting service cannot be managed through this connection.\n`rejected`: A named plugin is must-use or a drop-in, which cannot be removed here, or the platform refused; nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/themes":{"get":{"operationId":"list_website_themes","tags":["Websites"],"summary":"List a website's themes","description":"Managed WordPress sites only. The themes installed on a managed WordPress site: slug, title, whether active, version and whether the WordPress directory has a newer one. search narrows by slug or title. A hosting website answers not_supported: its themes are managed from its WordPress admin.","x-mcp-tool":"list_website_themes","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"search","in":"query","required":false,"description":"Only installed themes whose slug or title contains this.","schema":{"type":"string","maxLength":100}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A managed WordPress site's installed themes.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"themes":{"type":"array","description":"The themes installed on the site, as the platform orders them.","items":{"type":"object","description":"One installed theme.","properties":{"name":{"type":"string","description":"The theme's slug; what the other theme tools take."},"title":{"type":["string","null"],"description":"Its display name."},"status":{"type":["string","null"],"description":"active or inactive."},"version":{"type":["string","null"],"description":"The installed version."},"update_available":{"type":"boolean","description":"Whether the directory has a newer version."},"update_version":{"type":["string","null"],"description":"The newer version, when there is one."},"description":{"type":["string","null"],"description":"The theme's description from its author."}},"required":["name","title","status","version","update_available","update_version","description"],"additionalProperties":false}}},"required":["domain","service_id","platform","themes"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"install_website_themes","tags":["Websites"],"summary":"Install themes","description":"Managed WordPress sites only. Installs themes on a managed WordPress site from the WordPress directory, by slug (up to ten at once, as list_website_themes or search_website_themes name them), or one from an https download URL (custom_url), and activates the first when activate is true. The platform answers one row per theme with a note: already installed, not found, or what prevented it; the call succeeds even when a theme did not install, so read the notes. Tell the user which themes and whether they will be activated before calling this. A hosting website answers not_supported.","x-mcp-tool":"install_website_themes","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site to install the themes on, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"themes":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"},"description":"The themes to install, by slug, 1 to 10 at once, e.g. [\"twentytwentyfour\", \"astra\"]. Not with custom_url."},"custom_url":{"type":"string","maxLength":2000,"pattern":"^https:\\/\\/[A-Za-z0-9.-]+(\\/[^\\s]*)?$","description":"An https URL of a theme zip to install instead of a directory theme, e.g. a purchased theme. Not with themes."},"activate":{"type":"boolean","description":"Whether to make the installed theme the active one. false unless given; only the first of several can be active.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of installing themes.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"requested":{"type":"array","description":"The slugs asked for, or the one download URL.","items":{"type":"string"}},"activate":{"type":"boolean","description":"Whether activation was asked for."},"installed":{"type":"array","description":"One row per item, in the platform's words; read each note.","items":{"type":"object","description":"The outcome of installing one theme.","properties":{"name":{"type":["string","null"],"description":"The theme's slug."},"version":{"type":["string","null"],"description":"The version installed."},"activated":{"type":["boolean","null"],"description":"Whether it is active now."},"note":{"type":["string","null"],"description":"The platform's word on it: already installed, not found in the directory, a PHP error that prevented it, and so on. Empty when nothing is to be said."}},"required":["name","version","activated","note"],"additionalProperties":false}},"next_steps":{"type":"array","description":"What follows.","items":{"type":"string"}}},"required":["domain","service_id","platform","requested","activate","installed","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the install; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/themes/search":{"get":{"operationId":"search_website_themes","tags":["Websites"],"summary":"Search the theme directory","description":"Managed WordPress sites only. Searches the WordPress theme directory, through the managed WordPress platform, for themes to install on a site: by words (query), or browsing the new, popular or top-rated ones (browse). Each result's name is the slug install_website_themes takes, and status says whether the site already has it. Pages of limit results, from page 1. A hosting website answers not_supported.","x-mcp-tool":"search_website_themes","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"query","in":"query","required":false,"description":"Words to search the WordPress theme directory for, e.g. \"contact form\". Without it the directory is browsed (browse, popular by default).","schema":{"type":"string","minLength":2,"maxLength":100}},{"name":"browse","in":"query","required":false,"description":"Browse the directory instead of searching: new, popular or top-rated themes. One of query or browse.","schema":{"type":"string","enum":["new","popular","top-rated"]}},{"name":"page","in":"query","required":false,"description":"The page of results, from 1.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1}},{"name":"limit","in":"query","required":false,"description":"Results per page, 1 to 50.","schema":{"type":"integer","minimum":1,"maximum":50,"default":10}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The WordPress theme directory, searched through the platform.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"query":{"type":["string","null"],"description":"The words searched for; null when browsing."},"browse":{"type":["string","null"],"description":"new, popular or top-rated when browsing; null when searching by words."},"page":{"type":"integer","description":"The page answered."},"limit":{"type":"integer","description":"Results per page."},"total":{"type":["integer","null"],"description":"Results across every page, when the directory says."},"results":{"type":"array","description":"This page of the directory's results.","items":{"type":"object","description":"One theme the WordPress directory offers.","properties":{"name":{"type":"string","description":"The theme's slug; what install_website_themes takes."},"title":{"type":["string","null"],"description":"Its display name."},"status":{"type":["string","null"],"description":"active, inactive or not_installed on this site."},"version":{"type":["string","null"],"description":"The version the directory offers."},"description":{"type":["string","null"],"description":"The author's description, in short."},"preview_url":{"type":["string","null"],"description":"A live preview of the theme."},"screenshot_url":{"type":["string","null"],"description":"A screenshot of the theme."}},"required":["name","title","status","version","description","preview_url","screenshot_url"],"additionalProperties":false}}},"required":["domain","service_id","platform","query","browse","page","limit","total","results"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/themes/{theme}/status":{"post":{"operationId":"set_website_theme_status","tags":["Websites"],"summary":"Activate or deactivate a theme","description":"Managed WordPress sites only. Activates (active: true) or deactivates an installed theme on a managed WordPress site, by slug. Activating a theme makes it the site's look; the previous theme stays installed. A site always has an active theme, so deactivating the active one is refused: activate another instead. A theme that is not installed is not_found before anything is sent. A hosting website answers not_supported.","x-mcp-tool":"set_website_theme_status","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site the theme is installed on, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"theme","in":"path","required":true,"description":"The theme, by its slug exactly as list_website_themes shows it (name), e.g. twentytwentyfour.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean","description":"true makes the theme the active one (the previous one stays installed); false is refused by WordPress for the active theme, since a site always has one."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["active"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of activating or deactivating a theme.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"theme":{"type":"string","description":"The theme's slug."},"active":{"type":"boolean","description":"Whether it is active now."},"updated":{"type":"boolean","description":"true: the platform has applied the change."}},"required":["domain","service_id","platform","theme","active","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such theme installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/themes/{theme}/update":{"post":{"operationId":"update_website_theme","tags":["Websites"],"summary":"Update a theme","description":"Managed WordPress sites only. Updates one installed theme on a managed WordPress site to the version the WordPress directory offers (list_website_themes shows update_available and update_version). Answers the version before and after and the platform's note; a theme already current says so. Tell the user which theme and the versions before calling this. A hosting website answers not_supported.","x-mcp-tool":"update_website_theme","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"theme","in":"path","required":true,"description":"The theme, by its slug exactly as list_website_themes shows it (name), e.g. twentytwentyfour.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of updating a theme.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"theme":{"type":"string","description":"The theme's slug."},"previous_version":{"type":["string","null"],"description":"The version before."},"version":{"type":["string","null"],"description":"The version now."},"note":{"type":["string","null"],"description":"The platform's word on it: updated, or already up to date."},"updated":{"type":"boolean","description":"true: the platform has run the update."}},"required":["domain","service_id","platform","theme","previous_version","version","note","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such theme installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The platform refused the update; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/themes/{theme}/uninstall":{"post":{"operationId":"uninstall_website_theme","tags":["Websites"],"summary":"Uninstall a theme","description":"Managed WordPress sites only. Removes one installed theme from a managed WordPress site, by slug; this cannot be undone from here. The active theme is refused, since a site always has one: activate another first (set_website_theme_status). Confirm the theme and the domain with the user and pass the domain again as confirm_domain; a mismatch is refused before anything is looked up. A hosting website answers not_supported.","x-mcp-tool":"uninstall_website_theme","parameters":[{"name":"domain","in":"path","required":true,"description":"The managed WordPress site to remove the theme from, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"theme","in":"path","required":true,"description":"The theme, by its slug exactly as list_website_themes shows it (name), e.g. twentytwentyfour.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that the theme is to be removed from this site."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of removing themes.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"removed":{"type":"array","description":"One row per item, in the platform's words.","items":{"type":"object","description":"The outcome of removing one theme.","properties":{"name":{"type":["string","null"],"description":"The theme's slug."},"note":{"type":["string","null"],"description":"deleted, or the platform's reason it was not."}},"required":["name","note"],"additionalProperties":false}}},"required":["domain","service_id","platform","removed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such theme installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no theme to remove; nothing was sent. A hosting website's themes are managed from its WordPress admin (get_wordpress_login_link). Also answered when the hosting service cannot be managed through this connection.\n`rejected`: The theme is the active one, or the platform refused; nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/backups":{"get":{"operationId":"list_website_backups","tags":["Websites"],"summary":"List a website's backups","description":"Every backup of a website in one list, newest first: the ones the customer took (type manual) and the ones the platform takes on its own schedule (type automated), each with its backup_id, label, status (NEW, PROGRESS, DONE, ERROR, RESTORING), what it holds, size and when it was taken. type narrows to one kind, status to one state and search to labels containing the text. Any backup can be restored once DONE with restore_website_backup, whatever its type. On hosting the list is the control panel's (type archive is one it keeps past its schedule). On managed WordPress the manual ones are the site's cloud backups, which can also be downloaded and removed; the automated ones are the platform's recovery points, which can only be restored, and whose contents and size the platform does not report.","x-mcp-tool":"list_website_backups","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"type","in":"query","required":false,"description":"Only backups of this type: manual (the customer took it), automated (the platform took it on its own schedule) or archive (hosting: the control panel keeps it past its schedule). Omit for all of them.","schema":{"type":"string","enum":["manual","automated","archive"]}},{"name":"status","in":"query","required":false,"description":"Only backups in this state: NEW, PROGRESS, DONE, ERROR, RESTORING.","schema":{"type":"string","enum":["NEW","PROGRESS","DONE","ERROR","RESTORING"]}},{"name":"search","in":"query","required":false,"description":"Only backups whose label or file name contains this.","schema":{"type":"string","maxLength":100}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's backups.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backups":{"type":"array","description":"The backups of the site, those the customer took and those the platform took on its own schedule together, newest first; type tells them apart.","items":{"type":"object","description":"One backup of a website.","properties":{"backup_id":{"type":"string","description":"The backup, of whatever type; what get_website_backup, restore_website_backup, delete_website_backup and (managed WordPress) get_website_backup_download take."},"type":{"type":"string","description":"manual: one the customer took. automated: one the platform took on its own schedule; it can be restored but not removed or downloaded, and on managed WordPress it says nothing of what it holds or its size. archive: hosting only, one the control panel keeps past its schedule; restored like a manual one.","enum":["manual","automated","archive"]},"label":{"type":["string","null"],"description":"The name it was given; null for an automated backup."},"status":{"type":["string","null"],"description":"NEW or PROGRESS while being taken; DONE once it can be restored (or, on managed WordPress, downloaded); ERROR when it failed; RESTORING while a restore from it runs. On hosting a backup is DONE when at least one part of it was taken; includes_files and includes_database say which. An automated backup on managed WordPress is DONE or RESTORING.","enum":["NEW","PROGRESS","DONE","ERROR","RESTORING",null]},"includes_files":{"type":["boolean","null"],"description":"Whether it holds the site's files; null while it is still being taken, or when the platform does not say (an automated backup on managed WordPress holds both)."},"includes_database":{"type":["boolean","null"],"description":"Whether it holds the site's database (on hosting, its databases); null while it is still being taken, or when the platform does not say."},"size_bytes":{"type":["integer","null"],"description":"Its size in bytes, once taken; null when the platform does not say."},"created_at":{"type":["string","null"],"description":"When it was taken (UTC)."},"task_id":{"type":["string","null"],"description":"Managed WordPress: the task that took a manual backup; get_website_task follows it while status is NEW or PROGRESS. Null on hosting, where get_website_backup shows the progress, and for an automated backup."},"file_name":{"type":["string","null"],"description":"Managed WordPress: the archive's file name. Null on hosting."},"wordpress_version":{"type":["string","null"],"description":"Managed WordPress: the WordPress version the site ran when the backup was taken."},"php_version":{"type":["string","null"],"description":"Managed WordPress: the PHP version the site ran then."}},"required":["backup_id","type","label","status","includes_files","includes_database","size_bytes","created_at","task_id","file_name","wordpress_version","php_version"],"additionalProperties":false}}},"required":["domain","service_id","platform","backups"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management (or managed WordPress) was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_website_backup","tags":["Websites"],"summary":"Back up a website","description":"Takes a labelled backup of a website. On managed WordPress: its files, its database or both (both by default), leaving out any exclude_paths; the platform runs it as a task, the answer carries task_id and status queued, and get_website_backup shows the backup DONE once it can be restored or downloaded. On hosting: the whole website, files and databases, with nothing left out (includes_files or includes_database false, or exclude_paths, are refused); the control panel takes it before answering, so the call runs for as long as the backup does and the answer is its outcome, DONE (backup_id set) or ERROR; a panel that has not answered within the budget is 503 saying the backup may still be running (get_website reports pending_backup), so look before taking another. Both includes flags false is refused on either.","x-mcp-tool":"create_website_backup","parameters":[{"name":"domain","in":"path","required":true,"description":"The site to back up, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[^\\x00-\\x1f\\x7f]+$","description":"A name for the backup, e.g. \"Before the theme change\"; what list_website_backups shows."},"includes_files":{"type":"boolean","description":"Whether to back up the site's files. Default true. A hosting backup always holds both: false is refused there.","default":true},"includes_database":{"type":"boolean","description":"Whether to back up the site's database (on hosting, its databases). Default true. A hosting backup always holds both: false is refused there.","default":true},"exclude_paths":{"type":"array","maxItems":50,"items":{"type":"string","pattern":"^(?!.*(?:^|\\/)\\.\\.(?:\\/|$))[^\\x00-\\x1f\\x7f]{1,255}$"},"description":"Managed WordPress: paths inside the site to leave out of the backup, relative to its root, e.g. \"wp-content/uploads/2019\". At most fifty. A hosting backup leaves nothing out: refused there."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["label"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A backup started (managed WordPress) or taken (hosting).","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backup_id":{"type":["string","null"],"description":"The backup; get_website_backup shows it in full."},"label":{"type":"string","description":"The name it was given."},"task_id":{"type":["string","null"],"description":"Managed WordPress: the task the platform started; follow it with get_website_task. Null on hosting, and when the platform answered none."},"status":{"type":"string","description":"queued: the work has been accepted and runs in the background (managed WordPress always; hosting when the control panel is still at it after answering); the call does not wait for it. DONE or ERROR: the hosting control panel took the backup within the call, and that is how it ended.","enum":["queued","DONE","ERROR"]}},"required":["domain","service_id","platform","backup_id","label","task_id","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management (or managed WordPress) was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: includes_files and includes_database are both false; on hosting either is false or exclude_paths given; or the platform refused (a backup already running, for one). Nothing was started.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/backups/{backup_id}":{"get":{"operationId":"get_website_backup","tags":["Websites"],"summary":"Get a website backup","description":"One backup of a website in full, of whatever type: status, what it holds, size and when it was taken. On managed WordPress also the task that took it and the WordPress and PHP versions of the time; poll it after create_website_backup until status is DONE (an automated backup there has none of these). On hosting also the databases it holds by name, RESTORING while the control panel restores from it, and last_restore saying how the last restore from it went.","x-mcp-tool":"get_website_backup","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"backup_id","in":"path","required":true,"description":"The backup, by the backup_id list_website_backups shows, whatever its type.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F-]{8,64}|[0-9]{1,20})$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One backup in full.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backup_id":{"type":"string","description":"The backup, of whatever type; what get_website_backup, restore_website_backup, delete_website_backup and (managed WordPress) get_website_backup_download take."},"type":{"type":"string","description":"manual: one the customer took. automated: one the platform took on its own schedule; it can be restored but not removed or downloaded, and on managed WordPress it says nothing of what it holds or its size. archive: hosting only, one the control panel keeps past its schedule; restored like a manual one.","enum":["manual","automated","archive"]},"label":{"type":["string","null"],"description":"The name it was given; null for an automated backup."},"status":{"type":["string","null"],"description":"NEW or PROGRESS while being taken; DONE once it can be restored (or, on managed WordPress, downloaded); ERROR when it failed; RESTORING while a restore from it runs. On hosting a backup is DONE when at least one part of it was taken; includes_files and includes_database say which. An automated backup on managed WordPress is DONE or RESTORING.","enum":["NEW","PROGRESS","DONE","ERROR","RESTORING",null]},"includes_files":{"type":["boolean","null"],"description":"Whether it holds the site's files; null while it is still being taken, or when the platform does not say (an automated backup on managed WordPress holds both)."},"includes_database":{"type":["boolean","null"],"description":"Whether it holds the site's database (on hosting, its databases); null while it is still being taken, or when the platform does not say."},"size_bytes":{"type":["integer","null"],"description":"Its size in bytes, once taken; null when the platform does not say."},"created_at":{"type":["string","null"],"description":"When it was taken (UTC)."},"task_id":{"type":["string","null"],"description":"Managed WordPress: the task that took a manual backup; get_website_task follows it while status is NEW or PROGRESS. Null on hosting, where get_website_backup shows the progress, and for an automated backup."},"file_name":{"type":["string","null"],"description":"Managed WordPress: the archive's file name. Null on hosting."},"wordpress_version":{"type":["string","null"],"description":"Managed WordPress: the WordPress version the site ran when the backup was taken."},"php_version":{"type":["string","null"],"description":"Managed WordPress: the PHP version the site ran then."},"databases":{"type":["array","null"],"description":"Hosting: the databases the backup holds, by name. Null on managed WordPress, where the site has one database.","items":{"type":"string"}},"last_restore":{"type":["object","null"],"description":"Hosting: how the last restore from this backup went, when the control panel kept one. Null on managed WordPress, where get_website_task follows a restore.","properties":{"status":{"type":"string","description":"PROGRESS while it runs; DONE once every part restored; ERROR when a part failed.","enum":["PROGRESS","DONE","ERROR"]},"started_at":{"type":["string","null"],"description":"When the restore started (UTC)."},"finished_at":{"type":["string","null"],"description":"When it finished (UTC); null while it runs."}},"required":["status","started_at","finished_at"],"additionalProperties":false}},"required":["domain","service_id","platform","backup_id","type","label","status","includes_files","includes_database","size_bytes","created_at","task_id","file_name","wordpress_version","php_version","databases","last_restore"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management (or managed WordPress) was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such backup of it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/backups/{backup_id}/delete":{"post":{"operationId":"delete_website_backup","tags":["Websites"],"summary":"Delete a website backup","description":"Managed WordPress sites only. Removes one cloud backup of a managed WordPress site for good; it can no longer be restored or downloaded. Confirm the backup (its label and date from get_website_backup) and the domain with the user and pass the domain again as confirm_domain; a mismatch is refused before anything is looked up. A backup still being taken or restored is refused. A hosting website answers not_supported: the control panel keeps and expires its backups on the hosting provider's schedule, and a customer cannot remove one.","x-mcp-tool":"delete_website_backup","parameters":[{"name":"domain","in":"path","required":true,"description":"The site the backup belongs to, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"backup_id","in":"path","required":true,"description":"The backup, by the backup_id list_website_backups shows, whatever its type.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F-]{8,64}|[0-9]{1,20})$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this backup is to be removed for good."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A backup removed.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backup_id":{"type":"string","description":"The backup that was removed."},"deleted":{"type":"boolean","description":"true: the backup has been removed; it can no longer be restored or downloaded."}},"required":["domain","service_id","platform","backup_id","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such backup of it; nothing was changed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no backup the customer can remove; nothing was sent. A hosting website's backups are kept and expired by the control panel on the hosting provider's schedule; there is nothing for the customer to remove. Also answered when the hosting service cannot be managed through this connection.\n`rejected`: The backup is being taken or restored, or the platform refused; nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/backups/{backup_id}/download":{"post":{"operationId":"get_website_backup_download","tags":["Websites"],"summary":"Get a backup download link","description":"Managed WordPress sites only. Mints a time-limited link to download one DONE cloud backup of a managed WordPress site as an archive. The link is a credential for the account holder: hand it over once, do not store, log or repeat it; it expires after a short period and each call mints a new one. Counts as a write because it mints a secret. A hosting website answers not_supported: the control panel's backups are restored in place and have no archive to fetch; compress_website_files and download_website_file fetch the live files.","x-mcp-tool":"get_website_backup_download","parameters":[{"name":"domain","in":"path","required":true,"description":"The site the backup belongs to, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"backup_id","in":"path","required":true,"description":"The backup, by the backup_id list_website_backups shows, whatever its type.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F-]{8,64}|[0-9]{1,20})$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A backup's download link, answered once.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backup_id":{"type":"string","description":"The backup."},"download_url":{"type":"string","description":"A time-limited link to the backup's archive. A credential for the account holder alone: use it promptly, do not store or repeat it; it expires after a short period and this call mints a new one."}},"required":["domain","service_id","platform","backup_id","download_url"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such backup of it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The backup is not DONE yet (or failed), so there is nothing to download.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/backups/{backup_id}/restore":{"post":{"operationId":"restore_website_backup","tags":["Websites"],"summary":"Restore a website backup","description":"Writes one DONE backup back over the website, whichever type it is (one the customer took or one the platform took on its own schedule; list_website_backups shows both): its files, its database or both (both by default), the files limited to restore_paths when given. Whatever is restored replaces what is live now and cannot be undone from here, so confirm the backup (type, label and date) and the domain with the user and pass the domain again as confirm_domain; a mismatch is refused before anything is looked up. Asking for files or database the backup does not hold is refused. On managed WordPress the platform runs it as a task: the answer carries task_id and status queued; get_website_task follows it, and the task can end in ERROR within seconds (the platform could not start the restore) or run for minutes: read it to DONE or ERROR and report its message before telling the user the site is restored, then check the site with get_wordpress. An automated backup there restores some of its files only on their own: restore_paths with includes_database true is refused. On hosting the control panel restores before answering: the answer is the outcome (DONE, ERROR, or queued when the panel is still at it, which get_website_backup then shows as RESTORING and last_restore reports once done); mailboxes are never restored from here. A panel that has not answered within the budget is 503 saying the restore may still be running.","x-mcp-tool":"restore_website_backup","parameters":[{"name":"domain","in":"path","required":true,"description":"The site to restore onto, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"backup_id","in":"path","required":true,"description":"The backup, by the backup_id list_website_backups shows, whatever its type.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F-]{8,64}|[0-9]{1,20})$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"includes_files":{"type":"boolean","description":"Whether to restore the site's files. Default true.","default":true},"includes_database":{"type":"boolean","description":"Whether to restore the site's database (on hosting, its databases). Default true.","default":true},"restore_paths":{"type":"array","maxItems":50,"items":{"type":"string","pattern":"^(?!.*(?:^|\\/)\\.\\.(?:\\/|$))[^\\x00-\\x1f\\x7f]{1,255}$"},"description":"Only these paths are restored from the backup's files, relative to the site's root, e.g. \"public_html/wp-content/themes\"; everything else stays as it is. Needs includes_files. At most fifty. From an automated backup on managed WordPress, only with includes_database false."},"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this site's current files or database are to be overwritten by the backup."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A restore from a backup started (managed WordPress) or run (hosting).","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"backup_id":{"type":"string","description":"The backup restored from."},"type":{"type":"string","description":"Whether the backup restored from was the customer's (manual, archive) or the platform's own (automated).","enum":["manual","automated","archive"]},"includes_files":{"type":"boolean","description":"Whether the files are restored."},"includes_database":{"type":"boolean","description":"Whether the database is restored."},"restore_paths":{"type":"array","description":"The paths the file restore keeps to; empty for every file.","items":{"type":"string"}},"task_id":{"type":["string","null"],"description":"Managed WordPress: the task the platform started; follow it with get_website_task. Null on hosting, and when the platform answered none."},"status":{"type":"string","description":"queued: the work has been accepted and runs in the background (managed WordPress always; hosting when the control panel is still at it after answering); the call does not wait for it. DONE or ERROR: the hosting control panel ran the restore within the call, and that is how it ended.","enum":["queued","DONE","ERROR"]}},"required":["domain","service_id","platform","backup_id","type","includes_files","includes_database","restore_paths","task_id","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management (or managed WordPress) was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such backup of it; nothing was started.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The hosting service cannot be managed through this connection.\n`rejected`: Both includes flags false, the backup not DONE, the backup lacking what was asked for, restore_paths with the database from an automated backup on managed WordPress, or the platform refused; nothing was started.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/staging":{"post":{"operationId":"create_website_staging","tags":["Websites"],"summary":"Create a staging copy","description":"Managed WordPress sites only. Copies a managed WordPress production site to a staging copy, on the platform's preview address by default or a custom staging address with vanity_domain. One copy per site: a site that already has one, or that is itself a staging copy, is refused. The platform runs it as a task: the answer carries task_id and status queued; once done, list_websites shows the copy as its own website with kind staging, taking the site tools by its own domain. A hosting website answers not_supported.","x-mcp-tool":"create_website_staging","parameters":[{"name":"domain","in":"path","required":true,"description":"The production site to copy, by its domain, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"vanity_domain":{"type":"boolean","description":"true: the platform gives the staging copy a custom staging address rather than its default preview address. Default false.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A staging copy started.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"vanity_domain":{"type":"boolean","description":"Whether a custom staging address was asked for."},"task_id":{"type":["string","null"],"description":"The task the platform started; follow it with get_website_task. Null when the platform answered none."},"status":{"type":"string","description":"queued: the task has been accepted and runs in the background; the call does not wait for it.","enum":["queued"]},"next_steps":{"type":"array","description":"What to do next.","items":{"type":"string"}}},"required":["domain","service_id","platform","vanity_domain","task_id","status","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The site already has a staging copy, is itself one, or the platform refused; nothing was started.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/staging/delete":{"post":{"operationId":"delete_website_staging","tags":["Websites"],"summary":"Delete a staging copy","description":"Managed WordPress sites only. Removes a managed WordPress production site's staging copy for good, with whatever was changed on it; the production site is untouched. Name the production site, not the copy. Confirm the domain with the user and pass it again as confirm_domain; a mismatch is refused before anything is looked up. A site with no copy answers not_found. A hosting website answers not_supported.","x-mcp-tool":"delete_website_staging","parameters":[{"name":"domain","in":"path","required":true,"description":"The production site, by its domain, as the websites list shows it (not the staging copy's address).","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this site's staging copy is to be removed for good."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A staging copy removed.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"staging_domain":{"type":["string","null"],"description":"The address the staging copy answered to, when the listing knew it."},"deleted":{"type":"boolean","description":"true: the platform has removed the staging copy; the production site is untouched."}},"required":["domain","service_id","platform","staging_domain","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or it has no staging copy; nothing was changed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no staging copy of its own; nothing was sent. A hosting website has no staging copy of its own; create_website with another domain and copy the files over SSH. Also answered when the hosting service cannot be managed through this connection.\n`rejected`: The site named is itself the staging copy, or the platform refused; nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/staging/publish":{"post":{"operationId":"publish_website_staging","tags":["Websites"],"summary":"Publish a staging copy","description":"Managed WordPress sites only. Copies a managed WordPress site's staging copy over its production site: the live files and database are replaced by the copy's and this cannot be undone from here (create_website_backup first when in doubt). Name the production site, not the copy. Confirm the domain with the user and pass it again as confirm_domain; a mismatch is refused before anything is looked up. The platform runs it as a task: the answer carries task_id and status queued; get_website_task follows it. A site with no copy answers not_found. A hosting website answers not_supported.","x-mcp-tool":"publish_website_staging","parameters":[{"name":"domain","in":"path","required":true,"description":"The production site, by its domain, as the websites list shows it (not the staging copy's address).","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_domain":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain repeated exactly, as the caller's confirmation that this site's live files and database are to be replaced by its staging copy."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["confirm_domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A publish of the staging copy over the production site started.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"Which platform answered: hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"staging_domain":{"type":["string","null"],"description":"The address of the staging copy being published, when the listing knew it."},"task_id":{"type":["string","null"],"description":"The task the platform started; follow it with get_website_task. Null when the platform answered none."},"status":{"type":"string","description":"queued: the task has been accepted and runs in the background; the call does not wait for it.","enum":["queued"]}},"required":["domain","service_id","platform","staging_domain","task_id","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or it has no staging copy; nothing was started.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_supported`: The website is on hosting, which has no staging copy of its own; nothing was sent. A hosting website has no staging copy of its own; create_website with another domain and copy the files over SSH. Also answered when the hosting service cannot be managed through this connection.\n`rejected`: The site named is itself the staging copy, or the platform refused; nothing was started.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_confirmed","not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/php-version":{"post":{"operationId":"set_website_php_version","tags":["Websites"],"summary":"Set a website's PHP version","description":"Changes the PHP version a website runs on, e.g. php83 or php84, as the control panel names them (the website detail shows the current one). The panel refuses a version it does not offer.","x-mcp-tool":"set_website_php_version","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"php_version":{"type":"string","pattern":"^php[0-9]{2,3}$","description":"The version as the control panel names it, e.g. php83."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["php_version"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of changing the PHP version.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"platform":{"type":"string","description":"hosting or managed_wordpress.","enum":["hosting","managed_wordpress"]},"php_version":{"type":"string","description":"The version now in force, as the control panel names it."},"updated":{"type":"boolean","description":"true: the panel has changed it."}},"required":["domain","service_id","platform","php_version","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/php/restart":{"post":{"operationId":"restart_website_php","tags":["Websites"],"summary":"Restart a website's PHP","description":"Restarts the PHP processes serving a website, so a changed configuration or opcache is picked up. A brief interruption to PHP requests.","x-mcp-tool":"restart_website_php","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of restarting PHP.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"restarted":{"type":"boolean","description":"true: the PHP processes were restarted."}},"required":["domain","service_id","restarted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/php/error-log":{"get":{"operationId":"get_website_php_error_log","tags":["Websites"],"summary":"Get a website's PHP error log","description":"The last lines of a website's PHP error log (200 unless lines says otherwise, at most 1000), to see why a PHP site fails.","x-mcp-tool":"get_website_php_error_log","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"lines","in":"query","required":false,"description":"How many lines from the end to answer; 200 unless given, at most 1000.","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The tail of a website's PHP error log.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"lines":{"type":"integer","description":"How many lines were answered."},"truncated":{"type":"boolean","description":"true when older lines were left out."},"log":{"type":"string","description":"The lines, newest last."}},"required":["domain","service_id","lines","truncated","log"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/node":{"post":{"operationId":"install_node","tags":["Websites"],"summary":"Install Node on a website","description":"Installs the control panel's Node version manager for a website, and a Node version with it when version is given (e.g. 20.11.1). Needed before a persistent app runs a Node server; the Node versions list shows what is installed afterwards. Safe to call again: a manager or version already installed is left alone. When version_installed is false, the manager is in place but the panel refused that version for the reason given.","x-mcp-tool":"install_node","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string","pattern":"^(default|stable|[0-9]+(\\.[0-9]+){0,2}([-+][0-9A-Za-z.]+)?)$","description":"A Node version to install as well, e.g. 20.11.1, or stable. Omit to install the version manager only."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The outcome of installing Node.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"version":{"type":["string","null"],"description":"The Node version asked for; null when only the manager was."},"installed":{"type":"boolean","description":"The version manager is installed."},"version_installed":{"type":["boolean","null"],"description":"null when no version was asked for; true when it is installed (now or already); false when the control panel refused it, with the reason in version_error."},"version_error":{"type":["string","null"],"description":"The control panel's reason when version_installed is false."}},"required":["domain","service_id","version","installed","version_installed","version_error"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/node/versions":{"get":{"operationId":"list_node_versions","tags":["Websites"],"summary":"List a website's Node versions","description":"The Node versions installed for a website through the control panel's version manager. Refused with not_found when Node is not installed yet.","x-mcp-tool":"list_node_versions","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's installed Node versions.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"versions":{"type":"array","description":"The Node versions installed through the version manager.","items":{"type":"string"}}},"required":["domain","service_id","versions"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or Node is not installed on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/node/default-version":{"post":{"operationId":"set_default_node_version","tags":["Websites"],"summary":"Set a website's default Node version","description":"Makes an installed Node version the default for a website's shell and for persistent apps that run under default. The version must be one the Node versions list shows; the panel refuses others.","x-mcp-tool":"set_default_node_version","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string","pattern":"^(default|stable|[0-9]+(\\.[0-9]+){0,2}([-+][0-9A-Za-z.]+)?)$","description":"An installed version, as the Node versions list shows it."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["version"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of changing the default Node version.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"version":{"type":"string","description":"The version now the default."},"updated":{"type":"boolean","description":"true: the panel has changed it."}},"required":["domain","service_id","version","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/persistent-apps":{"get":{"operationId":"list_persistent_apps","tags":["Websites"],"summary":"List a website's persistent apps","description":"The long-running processes the control panel keeps alive behind a website (Node servers, workers): each with its app_id, kind, command, working directory, start mode, Node version and the path and port the web server proxies to it.","x-mcp-tool":"list_persistent_apps","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's persistent apps.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"apps":{"type":"array","description":"The long-running processes the panel keeps alive behind the site.","items":{"type":"object","properties":{"app_id":{"type":["string","null"],"description":"The handle the update, delete and log operations take."},"kind":{"type":["string","null"],"description":"The kind of process, as the panel names it."},"command":{"type":["string","null"],"description":"What it runs."},"working_directory":{"type":["string","null"],"description":"The folder it runs in, relative to the shell user's home."},"start_mode":{"type":["string","null"],"description":"automatic or manual."},"node_version":{"type":["string","null"],"description":"The Node version it runs under."},"path":{"type":["string","null"],"description":"The URL path proxied to the app; null for a worker."},"port":{"type":["integer","null"],"description":"The local port it listens on."},"websockets":{"type":["boolean","null"],"description":"Whether WebSocket upgrades pass through the proxy."},"status":{"type":["string","null"],"description":"Where the app stands when the panel reports it: created (not yet deployed), deploying, running, stopped or errored; null on a panel that only keeps it alive."},"url":{"type":["string","null"],"description":"The address the app answers at when the panel gives it one of its own; null when it is reached through the website at path."}},"required":["app_id","kind","command","working_directory","start_mode","node_version","path","port","websockets","status","url"],"additionalProperties":false}}},"required":["domain","service_id","apps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_persistent_app","tags":["Websites"],"summary":"Create a persistent app","description":"Runs a command as a long-running process behind a website and keeps it alive: for a Node server, the command (e.g. npm start), the folder, the Node version, and the path and port the web server should proxy to it; omit path and port for a worker. The code is deployed over SSH first and Node installed. Refused when the hosting plan allows no persistent apps.","x-mcp-tool":"create_persistent_app","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"command":{"type":"string","minLength":1,"maxLength":1024,"description":"What to run, e.g. \"npm start\" or \"node server.js\". Runs as the website's shell user."},"working_directory":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder to run in, relative to the shell user's home, e.g. app. Omit for the home itself."},"start_mode":{"type":"string","enum":["automatic","manual"],"description":"automatic: started by the panel and kept running (the default on create); manual: started by hand."},"node_version":{"type":"string","pattern":"^(default|stable|[0-9]+(\\.[0-9]+){0,2}([-+][0-9A-Za-z.]+)?)$","description":"The Node version to run under: one the Node versions list shows, \"default\" or \"stable\". Omit to use the default."},"path":{"type":"string","maxLength":255,"pattern":"^\\/[^\\s]*$","description":"The URL path the web server proxies to the app, e.g. / or /api. Give path and port together for a web-facing app; omit both for a worker."},"port":{"type":"integer","minimum":1024,"maximum":65535,"description":"The local port the app listens on (1024 to 65535), proxied from path."},"websockets":{"type":"boolean","description":"Allow WebSocket upgrades through the proxy."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["command"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The persistent app just created.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app_id":{"type":["string","null"],"description":"The handle the update, delete and log operations take."},"command":{"type":["string","null"],"description":"What it runs."},"working_directory":{"type":["string","null"],"description":"The folder it runs in, relative to the shell user's home."},"start_mode":{"type":["string","null"],"description":"automatic or manual."},"node_version":{"type":["string","null"],"description":"The Node version it runs under."},"path":{"type":["string","null"],"description":"The URL path proxied to the app; null for a worker."},"port":{"type":["integer","null"],"description":"The local port it listens on."},"websockets":{"type":["boolean","null"],"description":"Whether WebSocket upgrades pass through the proxy."},"created":{"type":"boolean","description":"true: the panel is keeping it alive."},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","service_id","app_id","command","working_directory","start_mode","node_version","path","port","websockets","created","next_steps"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/persistent-apps/{app_id}/update":{"post":{"operationId":"update_persistent_app","tags":["Websites"],"summary":"Update a persistent app","description":"Changes a persistent app's settings: only the fields given change (command, working directory, start mode, Node version, proxied path and port, WebSockets).","x-mcp-tool":"update_persistent_app","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"app_id","in":"path","required":true,"description":"The persistent app, as the persistent apps list shows it under app_id.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"command":{"type":"string","minLength":1,"maxLength":1024,"description":"What to run, e.g. \"npm start\" or \"node server.js\". Runs as the website's shell user."},"working_directory":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"The folder to run in, relative to the shell user's home, e.g. app. Omit for the home itself."},"start_mode":{"type":"string","enum":["automatic","manual"],"description":"automatic: started by the panel and kept running (the default on create); manual: started by hand."},"node_version":{"type":"string","pattern":"^(default|stable|[0-9]+(\\.[0-9]+){0,2}([-+][0-9A-Za-z.]+)?)$","description":"The Node version to run under: one the Node versions list shows, \"default\" or \"stable\". Omit to use the default."},"path":{"type":"string","maxLength":255,"pattern":"^\\/[^\\s]*$","description":"The URL path the web server proxies to the app, e.g. / or /api. Give path and port together for a web-facing app; omit both for a worker."},"port":{"type":"integer","minimum":1024,"maximum":65535,"description":"The local port the app listens on (1024 to 65535), proxied from path."},"websockets":{"type":"boolean","description":"Allow WebSocket upgrades through the proxy."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The persistent app after the change.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app_id":{"type":"string","description":"The persistent app."},"command":{"type":["string","null"],"description":"What it runs."},"working_directory":{"type":["string","null"],"description":"The folder it runs in, relative to the shell user's home."},"start_mode":{"type":["string","null"],"description":"automatic or manual."},"node_version":{"type":["string","null"],"description":"The Node version it runs under."},"path":{"type":["string","null"],"description":"The URL path proxied to the app; null for a worker."},"port":{"type":["integer","null"],"description":"The local port it listens on."},"websockets":{"type":["boolean","null"],"description":"Whether WebSocket upgrades pass through the proxy."},"updated":{"type":"boolean","description":"true: the panel has changed it."}},"required":["domain","service_id","app_id","command","working_directory","start_mode","node_version","path","port","websockets","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such persistent app on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/persistent-apps/{app_id}/delete":{"post":{"operationId":"delete_persistent_app","tags":["Websites"],"summary":"Delete a persistent app","description":"Stops a persistent app and removes it from the control panel, by the app_id the persistent apps list shows. The code it ran stays on the website; the app can be created again.","x-mcp-tool":"delete_persistent_app","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"app_id","in":"path","required":true,"description":"The persistent app, as the persistent apps list shows it under app_id.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting a persistent app.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app_id":{"type":"string","description":"The persistent app that was removed."},"deleted":{"type":"boolean","description":"true: it is stopped and gone from the panel."}},"required":["domain","service_id","app_id","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such persistent app on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/persistent-apps/{app_id}/log":{"get":{"operationId":"get_persistent_app_log","tags":["Websites"],"summary":"Get a persistent app's log","description":"The last lines a persistent app printed (200 unless lines says otherwise, at most 1000): its start-up output and errors, to see whether it is running and why not.","x-mcp-tool":"get_persistent_app_log","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"app_id","in":"path","required":true,"description":"The persistent app, as the persistent apps list shows it under app_id.","schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,127}$"}},{"name":"lines","in":"query","required":false,"description":"How many lines from the end to answer; 200 unless given, at most 1000.","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The tail of what a persistent app printed.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"app_id":{"type":"string","description":"The persistent app."},"lines":{"type":"integer","description":"How many lines were answered."},"truncated":{"type":"boolean","description":"true when older lines were left out."},"log":{"type":"string","description":"The lines, newest last."}},"required":["domain","service_id","app_id","lines","truncated","log"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such persistent app on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/databases":{"get":{"operationId":"list_databases","tags":["Websites"],"summary":"List a website's databases","description":"The MySQL databases of a website, each with its name (as the control panel lists it, usually prefixed with the website's user), size, how many users have access and when it was created. The database host to connect from the site's code is in the access details.","x-mcp-tool":"list_databases","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's MySQL databases.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"databases":{"type":"array","description":"The website's databases.","items":{"type":"object","properties":{"name":{"type":"string","description":"The database, as the control panel lists it; usually prefixed with the website's user."},"size_bytes":{"type":["integer","null"],"description":"Its size."},"users":{"type":["integer","null"],"description":"How many users have access."},"created_at":{"type":["string","null"],"description":"When it was created."}},"required":["name","size_bytes","users","created_at"],"additionalProperties":false}}},"required":["domain","service_id","databases"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_database","tags":["Websites"],"summary":"Create a database","description":"Creates a MySQL database on a website. The control panel may prefix the name with the website's user; the answer carries the name as it now appears in the databases list. Refused with nothing created when a database of that name already exists.","x-mcp-tool":"create_database","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"database":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"The name to create. Database names are as the databases list shows them; the control panel may prefix a new name with the website's user."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["database"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The database just created.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"name":{"type":"string","description":"The database as the control panel now lists it."},"created":{"type":"boolean","description":"true: it exists."}},"required":["domain","service_id","name","created"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/databases/delete":{"post":{"operationId":"delete_database","tags":["Websites"],"summary":"Delete a database","description":"Drops a MySQL database and everything in it. This cannot be undone from here; the name is repeated as confirm_database, and a mismatch is refused before anything is looked up.","x-mcp-tool":"delete_database","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"database":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"The database to delete. Database names are as the databases list shows them; the control panel may prefix a new name with the website's user."},"confirm_database":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"The database name repeated exactly, as the caller's confirmation that it and all its data are to be dropped."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["database","confirm_database"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of dropping a database.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"name":{"type":"string","description":"The database that was dropped."},"deleted":{"type":"boolean","description":"true: it and its data are gone."}},"required":["domain","service_id","name","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such database on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_database did not repeat the name exactly; nothing was changed.\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/database-users":{"get":{"operationId":"list_database_users","tags":["Websites"],"summary":"List a website's database users","description":"The MySQL users of a website: each with its username, the hosts it may connect from, its authentication plugin, the databases it has access to and when it was created. Never a password.","x-mcp-tool":"list_database_users","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A website's MySQL users.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"users":{"type":"array","description":"The website's MySQL users; never a password.","items":{"type":"object","properties":{"username":{"type":"string","description":"The MySQL user."},"access_hosts":{"type":"array","description":"The hosts it may connect from.","items":{"type":"string"}},"auth_plugin":{"type":["string","null"],"description":"Its authentication plugin."},"databases":{"type":"array","description":"The databases it has access to.","items":{"type":"string"}},"ephemeral":{"type":"boolean","description":"Whether the panel treats it as temporary."},"created_at":{"type":["string","null"],"description":"When it was created."}},"required":["username","access_hosts","auth_plugin","databases","ephemeral","created_at"],"additionalProperties":false}}},"required":["domain","service_id","users"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_database_user","tags":["Websites"],"summary":"Create a database user","description":"Creates a MySQL user on a website with the password given, and, when database is given, then grants it access to that database (ALL PRIVILEGES unless privileges says otherwise). The password is sent to the control panel and never echoed back. When granted is false, the user was created but the grant was refused for the reason given; the grant operation finishes the job.","x-mcp-tool":"create_database_user","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,32}$","description":"The user to create."},"password":{"type":"string","minLength":8,"maxLength":128,"description":"The user's password, chosen by the user; sent to the control panel and never echoed back."},"database":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"A database to grant the new user access to at once. Database names are as the databases list shows them; the control panel may prefix a new name with the website's user."},"privileges":{"type":"array","maxItems":30,"items":{"type":"string"},"description":"MySQL privileges to grant, e.g. [\"SELECT\", \"INSERT\"]; omit for ALL PRIVILEGES."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["username","password"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The database user just created.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"username":{"type":"string","description":"The user created."},"database":{"type":["string","null"],"description":"The database it was granted access to; null when none was named."},"privileges":{"type":"array","description":"The privileges granted.","items":{"type":"string"}},"granted":{"type":"boolean","description":"false when a database was named but the control panel refused the grant: the user exists, and the grant operation finishes the job."},"grant_error":{"type":["string","null"],"description":"The control panel's reason when granted is false."},"created":{"type":"boolean","description":"true: the user exists."}},"required":["domain","service_id","username","database","privileges","granted","grant_error","created"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/database-users/delete":{"post":{"operationId":"delete_database_user","tags":["Websites"],"summary":"Delete a database user","description":"Deletes a MySQL user from a website. Code connecting as that user stops working at once; the user can be created again.","x-mcp-tool":"delete_database_user","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,32}$","description":"The database user to delete, as the users list shows it."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["username"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting a database user.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"username":{"type":"string","description":"The user deleted."},"deleted":{"type":"boolean","description":"true: code connecting as it stops working."}},"required":["domain","service_id","username","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such database user on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/database-users/grant":{"post":{"operationId":"grant_database_access","tags":["Websites"],"summary":"Grant database access","description":"Sets a MySQL user's privileges on one of the website's databases (ALL PRIVILEGES unless privileges says otherwise), replacing what it had on that database. Refused with not_found when the database or the user does not exist on the website.","x-mcp-tool":"grant_database_access","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,32}$","description":"The database user, as the users list shows it."},"database":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"The database to grant access to. Database names are as the databases list shows them; the control panel may prefix a new name with the website's user."},"privileges":{"type":"array","maxItems":30,"items":{"type":"string"},"description":"MySQL privileges to grant, e.g. [\"SELECT\", \"INSERT\"]; omit for ALL PRIVILEGES."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["username","database"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a grant.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"username":{"type":"string","description":"The user."},"database":{"type":"string","description":"The database."},"privileges":{"type":"array","description":"The privileges now in force on it.","items":{"type":"string"}},"granted":{"type":"boolean","description":"true: the grant is in place."}},"required":["domain","service_id","username","database","privileges","granted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such database or user on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/domains":{"get":{"operationId":"list_website_domains","tags":["Websites"],"summary":"List a website's domains","description":"The domains mapped onto a website as the control panel lists them: the primary domain, aliases, addon domains, subdomains and the preview hostname, each with its kind and the folder it is served from. The DNS records for each were written by the panel when it was added.","x-mcp-tool":"list_website_domains","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The domains mapped onto a website.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"domains":{"type":"array","description":"Every name the website answers on, as the control panel lists them.","items":{"type":"object","properties":{"domain":{"type":"string","description":"The mapped name."},"kind":{"type":"string","description":"primary, alias, addon, subdomain or preview."},"document_root":{"type":["string","null"],"description":"The folder it is served from."}},"required":["domain","kind","document_root"],"additionalProperties":false}}},"required":["domain","service_id","domains"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"add_website_domain","tags":["Websites"],"summary":"Add a domain to a website","description":"Maps another domain onto a website: an alias (same files), an addon domain (its own folder) or a subdomain (a folder reached on a subdomain). The control panel writes the new domain's DNS records itself; they go live on their own, usually within a minute, and the launch checklist shows the panel's view of it. Refused with nothing changed when the name is already mapped here or in use elsewhere on the platform.","x-mcp-tool":"add_website_domain","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The domain to map onto the website, e.g. www.example.com or shop.example.com."},"kind":{"type":"string","enum":["alias","addon","subdomain"],"description":"alias: serves the same files as the website; addon: a separate site in its own folder; subdomain: a folder under the website reached on a subdomain."},"document_root":{"type":"string","maxLength":255,"pattern":"^\\/?[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\/?$","description":"For an addon or subdomain, the folder it is served from, e.g. public_html/shop. The control panel chooses one when omitted."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["name","kind"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The domain just mapped.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"name":{"type":"string","description":"The name mapped."},"kind":{"type":"string","description":"alias, addon or subdomain."},"document_root":{"type":["string","null"],"description":"The folder it is served from."},"added":{"type":"boolean","description":"true: the panel has mapped it and written its DNS."}},"required":["domain","service_id","name","kind","document_root","added"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/domains/remove":{"post":{"operationId":"remove_website_domain","tags":["Websites"],"summary":"Remove a domain from a website","description":"Removes an alias, addon domain or subdomain from a website; the site stops answering on it and its DNS records on the panel go with it. The primary domain and the preview hostname cannot be removed (deleting the website removes the site).","x-mcp-tool":"remove_website_domain","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The mapped domain to remove, as the website domains list shows it. The primary domain cannot be removed."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of removing a mapped domain.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"name":{"type":"string","description":"The name removed."},"kind":{"type":"string","description":"What it was: alias, addon or subdomain."},"removed":{"type":"boolean","description":"true: the site no longer answers on it."}},"required":["domain","service_id","name","kind","removed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no such mapped domain on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/ssl":{"get":{"operationId":"get_website_ssl","tags":["Websites"],"summary":"Get a website's SSL certificate","description":"The certificate installed on a website's domain (the primary one unless name says otherwise): issuer, names covered, dates and whether https is forced. Metadata only: the certificate and its key never leave the control panel; certificate is null when none is installed. The hosting issues certificates itself once a domain resolves to it.","x-mcp-tool":"get_website_ssl","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"name","in":"query","required":false,"description":"One of the website's mapped domains to read the certificate of. Omit for the primary domain.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The certificate on a website's domain.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"certificate_domain":{"type":"string","description":"The name whose certificate this is."},"certificate":{"type":["object","null"],"description":"Metadata only; null when no certificate is installed.","properties":{"issued":{"type":"boolean","description":"Whether a certificate is issued."},"issuer":{"type":["string","null"],"description":"Who issued it."},"common_name":{"type":["string","null"],"description":"The name it is issued to."},"names":{"type":"array","description":"Every name it covers.","items":{"type":"string"}},"issued_at":{"type":["string","null"],"description":"When it was issued."},"expires_at":{"type":["string","null"],"description":"When it expires."},"force_https":{"type":"boolean","description":"Whether http redirects to https."}},"required":["issued","issuer","common_name","names","issued_at","expires_at","force_https"],"additionalProperties":false}},"required":["domain","service_id","certificate_domain","certificate"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"issue_website_ssl","tags":["Websites"],"summary":"Issue a website's SSL certificate","description":"Asks the hosting to issue a certificate for a website's domain (the primary one unless name says otherwise), redirecting http to https as well when force_https is true. The hosting issues certificates itself once a domain resolves to it, so this is for when the automatic certificate has not appeared. It can only issue once the domain resolves: the preflight is asked first and, when it says it cannot issue yet, the request is refused with the reason and nothing changes. When issued is true but force_https is false with a reason, the certificate is in place and only the redirect was refused.","x-mcp-tool":"issue_website_ssl","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"One of the website's mapped domains to certify. Omit for the primary domain."},"force_https":{"type":"boolean","description":"Also redirect http to https once the certificate is issued."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of issuing a certificate.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"certificate_domain":{"type":"string","description":"The name certified."},"issued":{"type":"boolean","description":"true: the hosting has issued the certificate."},"force_https":{"type":"boolean","description":"false when the redirect was asked for and the control panel refused it: the certificate is issued regardless."},"force_https_error":{"type":["string","null"],"description":"The control panel's reason when force_https was asked for and is false."},"certificate":{"type":["object","null"],"description":"Metadata only; null when no certificate is installed.","properties":{"issued":{"type":"boolean","description":"Whether a certificate is issued."},"issuer":{"type":["string","null"],"description":"Who issued it."},"common_name":{"type":["string","null"],"description":"The name it is issued to."},"names":{"type":"array","description":"Every name it covers.","items":{"type":"string"}},"issued_at":{"type":["string","null"],"description":"When it was issued."},"expires_at":{"type":["string","null"],"description":"When it expires."},"force_https":{"type":"boolean","description":"Whether http redirects to https."}},"required":["issued","issuer","common_name","names","issued_at","expires_at","force_https"],"additionalProperties":false}},"required":["domain","service_id","certificate_domain","issued","force_https","force_https_error","certificate"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain on the account's hosting.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files":{"get":{"operationId":"list_website_files","tags":["Websites"],"summary":"List a website's files","description":"The entries of a directory on a website, relative to its home (the directory that holds public_html). An empty path is the home itself. recursive descends at most max_depth levels (3) and the answer keeps at most 1000 entries, with truncated set when there is more; list the deeper directory to see the rest. On managed WordPress the home is the WordPress root itself (there is no public_html), the platform marks no entry as a symbolic link, each directory is read a page at a time (1000 entries) and a recursive listing is one platform read per directory. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"list_website_files","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"path","in":"query","required":false,"description":"The directory to list. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments; omit it for the home directory itself.","schema":{"type":"string","maxLength":1024}},{"name":"recursive","in":"query","required":false,"description":"true to descend into subdirectories, as far as max_depth.","schema":{"type":"boolean","default":false}},{"name":"max_depth","in":"query","required":false,"description":"How many levels a recursive listing descends; 1 unless given, at most 3. Directories past it are listed without their entries and the answer says truncated.","schema":{"type":"integer","minimum":1,"maximum":3,"default":1}},{"name":"metadata","in":"query","required":false,"description":"false to list names and kinds only, without size, modified time or permissions.","schema":{"type":"boolean","default":true}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The entries of a directory on a website.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The directory listed; empty for the website home."},"recursive":{"type":"boolean","description":"Whether subdirectories were descended into."},"max_depth":{"type":"integer","description":"How many levels were descended."},"entries":{"type":"array","description":"The entries, a directory before the entries inside it.","items":{"type":"object","properties":{"path":{"type":"string","description":"The entry's path from the website home."},"name":{"type":"string","description":"Its own name, the last segment of the path."},"kind":{"type":"string","description":"What it is. A symlink is listed and described, and every other file operation refuses to act through it.","enum":["file","directory","symlink"]},"size_bytes":{"type":["integer","null"],"description":"Its size in bytes; null for a directory, or when metadata was not asked for."},"modified_at":{"type":["string","null"],"description":"When it was last modified, UTC; null when the file service did not say.","format":"date-time"},"permissions":{"type":["string","null"],"description":"Its mode in octal (644, 755); null when metadata was not asked for."}},"required":["path","name","kind","size_bytes","modified_at","permissions"],"additionalProperties":false}},"truncated":{"type":"boolean","description":"true when the listing stopped short of the tree: a directory past max_depth was left unexplored, or the entry cap was reached. List that directory on its own to see the rest."}},"required":["domain","service_id","path","recursive","max_depth","entries","truncated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no directory at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The path is not a directory.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"write_website_file","tags":["Websites"],"summary":"Write a website file","description":"Writes a file of at most 20 MiB. contents is text unless encoding is base64. The bytes are uploaded to a temporary name in the same directory and renamed into place, so the destination is unchanged until that rename succeeds; overwrite applies only to the rename and defaults to false. expected_sha256 replaces the file only when its current bytes hash to that value, and is 409 conflict otherwise. A larger file is 413. POST /v1/websites/{domain}/files/raw carries the same size as one file part, without base64. The parent directory must already exist. On managed WordPress a file is written as a plain overwrite in one platform call, a new file created or an existing one replaced, chosen from a listing read under the website lock: overwrite false still refuses an existing file, but expected_sha256 cannot be checked and is rejected; an existing file is replaced with text only (binary contents over an existing file are rejected: delete it first, then write it); and binary travels base64-encoded in a body the platform caps at 20 MB, so a binary file over about 14 MiB is 413. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"write_website_file","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The file to write; its directory must already exist. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"contents":{"type":"string","description":"The file's contents, as text (encoding utf-8) or base64 (encoding base64). May be empty."},"encoding":{"type":"string","enum":["utf-8","base64"],"description":"How contents is encoded: utf-8 unless given.","default":"utf-8"},"overwrite":{"type":"boolean","description":"true to replace a file already at the path. false unless given: an existing entry at the destination is refused.","default":false},"expected_sha256":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"The SHA-256 (hex) of the file as last read, to replace only that version: a different or missing file is 409 conflict and nothing is written. Omit to write regardless."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["path","contents"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The file just written.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The file written."},"size_bytes":{"type":"integer","description":"The size written, in bytes."},"sha256":{"type":"string","description":"The SHA-256 of the bytes written, hex."},"written":{"type":"boolean","description":"true: the file is in place. It was staged under a temporary name and renamed over the destination only after the upload succeeded."}},"required":["domain","service_id","path","size_bytes","sha256","written"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or the parent directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"413":{"description":"`too_large`: The decoded contents are over 20 MiB, or on managed WordPress over what the platform takes in one write (about 14 MiB of binary).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The destination exists and overwrite is false, the destination is a directory or a symbolic link, or the contents are not the encoding asked for; on managed WordPress also expected_sha256 given, or binary contents over an existing file. Nothing was written.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/content":{"get":{"operationId":"get_website_file","tags":["Websites"],"summary":"Read a website file","description":"A file's contents, up to 20 MiB. Valid UTF-8 comes back as text (encoding utf-8); anything else, or encoding base64, comes back as base64. A larger file is 413 too_large and names GET /v1/websites/{domain}/files/raw, which carries up to 100 MiB. The answer includes the SHA-256 of the raw bytes. On managed WordPress the platform answers the file inside JSON (base64 when binary) and the same 20 MiB cap applies; it marks no entry as a symbolic link, so none is refused as one. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"get_website_file","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"path","in":"query","required":true,"description":"The file to read. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments.","schema":{"type":"string","maxLength":1024}},{"name":"encoding","in":"query","required":false,"description":"How to answer the contents: utf-8 (text as it is) or base64 (any bytes). Omit to get utf-8 when the file is valid UTF-8 and base64 otherwise; asking for utf-8 outright refuses a file that is not.","schema":{"type":"string","enum":["utf-8","base64"]}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A file's contents.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The file, from the website home."},"encoding":{"type":"string","description":"How contents is encoded. utf-8 is the file as text; base64 is any bytes.","enum":["utf-8","base64"]},"contents":{"type":"string","description":"The file. A file over the JSON route's limit is refused and the description names the raw download route."},"size_bytes":{"type":"integer","description":"The file's size in bytes, before encoding."},"sha256":{"type":"string","description":"The SHA-256 of the raw bytes, hex. Pass it back as expected_sha256 to replace only this version."}},"required":["domain","service_id","path","encoding","contents","size_bytes","sha256"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no entry at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"413":{"description":"`too_large`: The file is over the size this route carries. The JSON route names the raw route, which carries a larger file.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The entry is a symbolic link, or is a directory where a file was asked for. Nothing was read.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many file transfers are already in progress for this account; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/raw":{"get":{"operationId":"download_website_file","tags":["Websites"],"summary":"Download a website file","description":"The file's bytes as application/octet-stream, up to 100 MiB, with its SHA-256 in X-Content-Sha256. A file over that is 413 and no body: the length is checked before anything is sent, and a response without a length is spooled and refused if it crosses the cap. Not an MCP tool; get_website_file reads a file up to 20 MiB. On managed WordPress the platform streams the file and the same 100 MiB cap applies. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"path","in":"query","required":true,"description":"The file to download. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments.","schema":{"type":"string","maxLength":1024}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary","description":"The file's bytes. X-Content-Sha256 is the SHA-256 of those bytes, hex."}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no entry at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"413":{"description":"`too_large`: The file is over the size this route carries. The JSON route names the raw route, which carries a larger file.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The entry is a symbolic link, or is a directory where a file was asked for. Nothing was read.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many file transfers are already in progress for this account; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"upload_website_file","tags":["Websites"],"summary":"Upload a website file","description":"Writes a file of at most 20 MiB as multipart/form-data: a path field and one file part, with optional overwrite and expected_sha256. The same commit as write_website_file: staged under a temporary name, then renamed. Not an MCP tool. The parent directory must already exist. On managed WordPress the same plain overwrite as write_website_file, with its limits: expected_sha256 is rejected, an existing file is replaced with text only, and a binary file over about 14 MiB is 413. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The file to write; its directory must already exist. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"overwrite":{"type":"boolean","description":"true to replace a file already at the path. false unless given: an existing entry at the destination is refused.","default":false},"expected_sha256":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"The SHA-256 (hex) of the file as last read, to replace only that version: a different or missing file is 409 conflict and nothing is written. Omit to write regardless."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."},"file":{"type":"string","description":"The file's bytes, as one multipart part.","format":"binary"}},"required":["path","file"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The file just written.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The file written."},"size_bytes":{"type":"integer","description":"The size written, in bytes."},"sha256":{"type":"string","description":"The SHA-256 of the bytes written, hex."},"written":{"type":"boolean","description":"true: the file is in place. It was staged under a temporary name and renamed over the destination only after the upload succeeded."}},"required":["domain","service_id","path","size_bytes","sha256","written"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or the parent directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"413":{"description":"`too_large`: The file is over 20 MiB, or the request leaves no room for the multipart framing.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The destination exists and overwrite is false, or the destination is a directory or a symbolic link; on managed WordPress also expected_sha256 given, or binary contents over an existing file. Nothing was written.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/info":{"get":{"operationId":"get_website_file_info","tags":["Websites"],"summary":"Describe a website file","description":"Hosting websites only. The kind, size, modified time and octal permissions of one entry. An empty path is the website home. On managed WordPress this answers not_supported with reason platform: list_website_files on the entry's directory describes it. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"get_website_file_info","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"path","in":"query","required":false,"description":"The entry to describe. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments; omit it for the home directory itself.","schema":{"type":"string","maxLength":1024}},{"name":"service_id","in":"query","required":false,"description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One entry on a website: its kind, size, modified time and permissions.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"entry":{"type":"object","description":"The entry.","properties":{"path":{"type":"string","description":"The entry's path from the website home."},"name":{"type":"string","description":"Its own name, the last segment of the path."},"kind":{"type":"string","description":"What it is. A symlink is listed and described, and every other file operation refuses to act through it.","enum":["file","directory","symlink"]},"size_bytes":{"type":["integer","null"],"description":"Its size in bytes; null for a directory, or when metadata was not asked for."},"modified_at":{"type":["string","null"],"description":"When it was last modified, UTC; null when the file service did not say.","format":"date-time"},"permissions":{"type":["string","null"],"description":"Its mode in octal (644, 755); null when metadata was not asked for."}},"required":["path","name","kind","size_bytes","modified_at","permissions"],"additionalProperties":false}},"required":["domain","service_id","entry"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no entry at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/directories":{"post":{"operationId":"create_website_directory","tags":["Websites"],"summary":"Create a website directory","description":"Creates one directory. The parent must already exist: a missing parent is 404 and nothing is created along the way. overwrite defaults to false. An existing file at the path is refused. On managed WordPress the parent is checked here before the platform is asked, and overwrite true on a directory that exists makes no platform call. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"create_website_directory","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The directory to create; its parent must already exist. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"overwrite":{"type":"boolean","description":"true to accept a directory already at the path. false unless given: an existing entry at the destination is refused.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["path"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The directory just created.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The directory."},"created":{"type":"boolean","description":"true: the directory exists."}},"required":["domain","service_id","path","created"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or the parent directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The path exists and overwrite is false, or a file or symbolic link is already there. Nothing was created.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/delete":{"post":{"operationId":"delete_website_files","tags":["Websites"],"summary":"Delete website files","description":"Deletes each path in order and stops at the first failure. deleted lists what was removed; failed names the path that stopped it and why. Earlier deletions are not undone. The website home is not an accepted path. Deleting a directory removes that directory; whether the file service also removes what is inside it is confirmed on the staging probe. On managed WordPress one path per call: more than one is rejected and nothing is deleted. Whether the platform removes a directory's contents with it is confirmed on the staging probe too. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"delete_website_files","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"paths":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","maxLength":1024},"description":"The entries to delete, in order; a directory goes with everything in it. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments. At most 100."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["paths"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting files. Deletion stops at the first failure.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"deleted":{"type":"array","description":"The paths removed, in the order they were given, up to the first failure.","items":{"type":"string"}},"failed":{"type":["object","null"],"description":"The first path that could not be removed; null when every path was. Paths in deleted are already gone and are not put back.","properties":{"path":{"type":"string","description":"The path the deletion stopped on."},"reason":{"type":"string","description":"Why it could not be removed."}},"required":["path","reason"],"additionalProperties":false}},"required":["domain","service_id","deleted","failed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: On managed WordPress more than one path was given. Nothing was deleted.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/move":{"post":{"operationId":"move_website_file","tags":["Websites"],"summary":"Move a website file","description":"Hosting websites only. Moves an entry to another path on the same website. destination is the new full path, and its directory must already exist. overwrite defaults to false. An entry cannot be moved into itself, and the website home cannot be moved. On managed WordPress this answers not_supported with reason platform: move the entry over run_wp_cli or SSH instead. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"move_website_file","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The entry to move. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"destination":{"type":"string","maxLength":1024,"description":"Where it goes: the new full path of the entry, whose directory must already exist. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"overwrite":{"type":"boolean","description":"true to replace an entry already at the destination. false unless given: an existing entry at the destination is refused.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["path","destination"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a move.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"source":{"type":"string","description":"The path the entry was at."},"destination":{"type":"string","description":"The path it is at now."},"moved":{"type":"boolean","description":"true: The entry now lives at the destination and no longer at the source."}},"required":["domain","service_id","source","destination","moved"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or the source or the destination directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The destination exists and overwrite is false, the entry is a symbolic link, or the destination is inside the source. Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/copy":{"post":{"operationId":"copy_website_file","tags":["Websites"],"summary":"Copy a website file","description":"Hosting websites only. Copies an entry to another path on the same website. The copy runs on the file service; before it is asked, the source's size (a directory's size is the service's own total) must be within 20 MiB or the answer is 413 and nothing is copied. destination is the new full path. overwrite defaults to false. On managed WordPress this answers not_supported with reason platform: copy the entry over run_wp_cli or SSH instead. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"copy_website_file","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The entry to copy. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"destination":{"type":"string","maxLength":1024,"description":"Where it goes: the new full path of the entry, whose directory must already exist. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"overwrite":{"type":"boolean","description":"true to replace an entry already at the destination. false unless given: an existing entry at the destination is refused.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["path","destination"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a copy.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"source":{"type":"string","description":"The path the entry was at."},"destination":{"type":"string","description":"The path it is at now."},"copied":{"type":"boolean","description":"true: The destination is a copy; the source is unchanged."}},"required":["domain","service_id","source","destination","copied"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or the source or the destination directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"413":{"description":"`too_large`: The source is over 20 MiB. Nothing was copied.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The destination exists and overwrite is false, the entry is a symbolic link, or the destination is inside the source. Nothing was copied.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/compress":{"post":{"operationId":"compress_website_files","tags":["Websites"],"summary":"Compress website files","description":"Packs the paths into a zip, tar or tar.gz in the destination directory (the website home when destination is omitted). The file service names the archive. The sources' sizes must total at most 20 MiB or the answer is 413 and nothing is packed. overwrite defaults to false. On managed WordPress the archive is named here (the source's own name plus the format for one source, archive-<timestamp>.<format> for several), each source's directory is listed once to check the sources and their total size (a directory counts as 0), and overwrite false refuses an archive already at that name. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"compress_website_files","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"paths":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","maxLength":1024},"description":"The entries to put in the archive, in order. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments. At most 100."},"destination":{"type":"string","maxLength":1024,"description":"The directory the archive is written into; the file service names the archive. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments; omit it for the home directory itself."},"format":{"type":"string","enum":["zip","tar","tar.gz"],"description":"The archive format: zip unless given.","default":"zip"},"overwrite":{"type":"boolean","description":"true to replace an archive already there. false unless given: an existing entry at the destination is refused.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["paths"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The archive just written.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The archive written."},"format":{"type":"string","description":"The archive format.","enum":["zip","tar","tar.gz"]},"compressed":{"type":"boolean","description":"true: the archive is in place."}},"required":["domain","service_id","path","format","compressed"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or a source or the destination directory does not exist.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"413":{"description":"`too_large`: The sources total more than 20 MiB. Nothing was packed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: An archive is already there and overwrite is false, or a source is a symbolic link. Nothing was packed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/extract":{"post":{"operationId":"extract_website_file","tags":["Websites"],"summary":"Extract a website archive","description":"Extracts a .zip, .tar or .tar.gz of at most 32 MiB into its own directory. overwrite defaults to false. The file service does not expose a limit on how far an archive expands, how many entries it holds or how deep it goes, so a small archive can expand further than 32 MiB once extracted; the size check and a 60 second timeout are the bounds enforced here. An absolute path, a .. segment or a symbolic link found in the extracted tree is reported afterwards and is not followed. The unpacked tree is inspected only as far as a listing goes (3 levels, 1000 entries); past that the extract is reported as not fully inspected, because a link or an unaddressable path further in would not have been seen. The directory the archive sits in is listed only to notice entries added beside the path the file service names; that directory already being too large to list in full does not reject the extract when that path is named and can be walked. On managed WordPress the platform extracts over whatever is already there, so overwrite must be true (false is rejected before anything is sent); the unpacked tree is not inspected afterwards, since the platform marks no entry as a symbolic link; the 32 MiB size check and the 60 second timeout still apply. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"extract_website_file","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The .zip, .tar or .tar.gz archive to extract, into its own directory. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments."},"overwrite":{"type":"boolean","description":"true to replace entries the archive would write over. false unless given: an existing entry at the destination is refused.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["path"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of extracting an archive.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The archive that was extracted."},"output":{"type":["string","null"],"description":"Where the file service reports the extracted entry; null when it does not say (always on managed WordPress)."},"extracted":{"type":"boolean","description":"true: the archive was extracted into its own directory."}},"required":["domain","service_id","path","output","extracted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no archive at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"413":{"description":"`too_large`: The archive is over 32 MiB. Nothing was extracted.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_large"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The path is not a zip, tar or tar.gz archive, the destination exists and overwrite is false (on managed WordPress overwrite false at all), or the extracted tree contains a symbolic link or a path this connection cannot address.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/websites/{domain}/files/permissions":{"post":{"operationId":"set_website_file_permissions","tags":["Websites"],"summary":"Set website file permissions","description":"Sets an entry's mode. permissions is octal, as chmod takes it (644, 755). recursive defaults to false and is refused for the website home; an empty path with recursive false sets the home directory's own mode. On managed WordPress one entry at a time: recursive true is rejected, and the home itself cannot be changed. An entry that is itself a symbolic link can be listed and described, and is refused for reading, writing, moving, copying, compressing, extracting and deleting: a link created outside this connection can name something outside the website home. Whether the file service follows such a link, removes a directory's children, and rejects a bad token before applying a write is confirmed on a staging probe; it cannot be shown from automated tests.","x-mcp-tool":"set_website_file_permissions","parameters":[{"name":"domain","in":"path","required":true,"description":"The website, by its primary domain, e.g. example.com, as the websites list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","maxLength":1024,"description":"The entry to change. Relative to the website home (the directory holding public_html), /-separated, without . or .. segments; omit it for the home directory itself."},"permissions":{"type":"string","pattern":"^0?[0-7]{3}$","description":"The mode in octal, as chmod takes it: 644, 755, 0600."},"recursive":{"type":"boolean","description":"true to apply the mode to everything under a directory as well; refused for the website home.","default":false},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service the website is on, as the websites list identifies it; only needed when the domain answers to websites on more than one service."}},"required":["permissions"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a permissions change.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"path":{"type":"string","description":"The entry changed; empty for the website home."},"permissions":{"type":"string","description":"The mode now set, in octal."},"recursive":{"type":"boolean","description":"Whether the mode was applied to everything under a directory."},"updated":{"type":"boolean","description":"true: the mode is set."}},"required":["domain","service_id","path","permissions","recursive","updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before website management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No website answering to this domain, or no entry at that path.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The entry is a symbolic link, or recursive was asked of the website home; on managed WordPress also recursive at all, or the home itself. Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/services/{service_id}/plan":{"get":{"operationId":"get_hosting_plan","tags":["Websites"],"summary":"Get a service's plan with its usage and limits","description":"The plan a hosting service or managed WordPress plan is on, with what it is using against what it allows right now, as its panel counts them: websites, monthly visitors, disk and bandwidth in bytes (null where the plan sets no limit, or the panel does not count that measure; hosting does not meter visitors). Read on the service named by service_id (list_services shows every service with its platform; a websites listing shows the ones that hold websites). Signs the connection in to the service's panel as the account holder when needed. Use it before create_website when a user asks whether another site fits: sites against limits.sites says so.","x-mcp-tool":"get_hosting_plan","parameters":[{"name":"service_id","in":"path","required":true,"description":"The service, as list_services identifies it: a hosting service or a managed WordPress plan.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The plan a service is on, with its usage and limits.","properties":{"service_id":{"type":"string","description":"The service; what create_website and the other service-bound tools take as service_id."},"label":{"type":"string","description":"Its label on the account."},"platform":{"type":"string","description":"hosting or managed_wordpress: which panel counts the usage.","enum":["hosting","managed_wordpress"]},"status":{"type":"string","description":"ok: its websites can be managed. not_supported: an AI hosting plan, or a plan awaiting activation (reason says which).","enum":["ok","unavailable","not_supported"]},"reason":{"type":["string","null"],"description":"Why a plan is not_supported, when it is.","enum":["ai_hosting","awaiting_activation",null]},"plan":{"type":["string","null"],"description":"The plan's name on its panel."},"usage":{"type":"object","description":"What the plan is using right now, as its panel counts it.","properties":{"sites":{"type":["integer","null"],"description":"Websites in use; null when the panel has no count (list_websites still has the sites)."},"visitors":{"type":["integer","null"],"description":"Monthly visitors in use; null on hosting, which does not meter them."},"disk_bytes":{"type":["integer","null"],"description":"Disk in use, in bytes."},"bandwidth_bytes":{"type":["integer","null"],"description":"Monthly bandwidth in use, in bytes."}},"required":["sites","visitors","disk_bytes","bandwidth_bytes"],"additionalProperties":false},"limits":{"type":"object","description":"What the plan allows; null where it sets no limit, or where the panel does not count that measure.","properties":{"sites":{"type":["integer","null"],"description":"Websites allowed; null when the panel has no count (list_websites still has the sites)."},"visitors":{"type":["integer","null"],"description":"Monthly visitors allowed; null on hosting, which does not meter them."},"disk_bytes":{"type":["integer","null"],"description":"Disk allowed, in bytes."},"bandwidth_bytes":{"type":["integer","null"],"description":"Monthly bandwidth allowed, in bytes."}},"required":["sites","visitors","disk_bytes","bandwidth_bytes"],"additionalProperties":false}},"required":["service_id","label","platform","status","reason","plan","usage","limits"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: The connection lacks the grant for the service's platform (websites, or managed WordPress for a plan approved before it was available through here); disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No hosting service or managed WordPress plan on the account has this service_id.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/mwp/locations":{"get":{"operationId":"list_mwp_locations","tags":["Mwp"],"summary":"List managed WordPress locations","description":"Managed WordPress plans only. The data centres a new WordPress site can be built in, each with the location_id create_website takes as location on a managed WordPress plan. Read as the plan named by service_id, or the account's only plan when it has one.","x-mcp-tool":"list_mwp_locations","parameters":[{"name":"service_id","in":"query","required":false,"description":"The managed WordPress plan, as list_services identifies it (platform managed_wordpress); only needed when the account has more than one.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The data centres available to a plan.","properties":{"service_id":{"type":"string","description":"The plan the list was read as."},"locations":{"type":"array","description":"The data centres a WordPress site can be built in.","items":{"type":"object","properties":{"location_id":{"type":"integer","description":"What create_website takes as location on a managed WordPress plan."},"name":{"type":"string","description":"The data centre, e.g. London."},"region":{"type":["string","null"],"description":"The region it is in, e.g. Europe."}},"required":["location_id","name","region"],"additionalProperties":false}}},"required":["service_id","locations"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before managed WordPress was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: The account has no managed WordPress plan, or none with this service_id.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: The account has more than one managed WordPress plan and service_id was not given; the description names them.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email":{"get":{"operationId":"list_email_services","tags":["Email"],"summary":"List email services","description":"The account's email services, one per domain, as the email control panel has them right now: the domain, plan, how many mailboxes the plan allows and how many exist, expiry and state. Every other email operation takes a domain from this list. A service marked unavailable could not be reached just now; one marked not_supported cannot be managed here, and missing says what the account lacks for it. Signs in to the email control panel as the account holder when needed.","x-mcp-tool":"list_email_services","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account's email services.","properties":{"services":{"type":"array","description":"One entry per email product on the account, whether or not its panel could be reached.","items":{"type":"object","description":"One of the account's email services.","properties":{"service_id":{"type":"string","description":"The email service; the same id as on the services list."},"label":{"type":"string","description":"The service's label on the account."},"domain":{"type":["string","null"],"description":"The domain the mailboxes are on; the input to every other email operation."},"status":{"type":"string","description":"ok: manageable here. unavailable: its email control panel could not be reached just now. not_supported: not manageable through this connection; missing says why.","enum":["ok","unavailable","not_supported"]},"missing":{"type":"array","description":"For not_supported: the details the account does not record for it, which the hosting provider must add.","items":{"type":"string"}},"plan":{"type":["string","null"],"description":"The email plan, as the email control panel names it."},"seats":{"type":["object","null"],"description":"The plan's mailbox allowance; null when the panel did not say.","properties":{"total":{"type":["integer","null"],"description":"How many mailboxes the plan allows."},"used":{"type":["integer","null"],"description":"How many exist."}},"required":["total","used"],"additionalProperties":false},"expires_at":{"type":["string","null"],"description":"When the service expires."},"service_status":{"type":["string","null"],"description":"The service's state on the email control panel, e.g. active or suspended."}},"required":["service_id","label","domain","status","missing","plan","seats","expires_at","service_status"],"additionalProperties":false}}},"required":["services"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}":{"get":{"operationId":"get_email_service","tags":["Email"],"summary":"Get an email service","description":"One of the account's email services, by its domain: plan, seats, state and expiry as the email control panel has them, the catch-all mailbox if one is set, and how many mailboxes and forwarders it holds.","x-mcp-tool":"get_email_service","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One email service in full.","properties":{"service_id":{"type":"string","description":"The email service; the same id as on the services list."},"label":{"type":"string","description":"The service's label on the account."},"domain":{"type":["string","null"],"description":"The domain the mailboxes are on; the input to every other email operation."},"status":{"type":"string","description":"ok: manageable here. unavailable: its email control panel could not be reached just now. not_supported: not manageable through this connection; missing says why.","enum":["ok","unavailable","not_supported"]},"missing":{"type":"array","description":"For not_supported: the details the account does not record for it, which the hosting provider must add.","items":{"type":"string"}},"plan":{"type":["string","null"],"description":"The email plan, as the email control panel names it."},"seats":{"type":["object","null"],"description":"The plan's mailbox allowance; null when the panel did not say.","properties":{"total":{"type":["integer","null"],"description":"How many mailboxes the plan allows."},"used":{"type":["integer","null"],"description":"How many exist."}},"required":["total","used"],"additionalProperties":false},"expires_at":{"type":["string","null"],"description":"When the service expires."},"service_status":{"type":["string","null"],"description":"The service's state on the email control panel, e.g. active or suspended."},"catch_all":{"type":["string","null"],"description":"The mailbox that receives mail for unknown addresses on the domain, or null when none does."},"mailboxes":{"type":"integer","description":"How many mailboxes the service holds."},"forwarders":{"type":["integer","null"],"description":"How many forwarders the service holds; null when they could not be read."}},"required":["service_id","label","domain","status","missing","plan","seats","expires_at","service_status","catch_all","mailboxes","forwarders"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/dns":{"get":{"operationId":"get_email_dns","tags":["Email"],"summary":"Get an email service's DNS records","description":"The DNS records an email service's domain must publish for mail to be received (MX) and trusted (SPF, and DKIM once a signing key exists), and whether the email control panel finds each published right now. For when mail is not arriving or the domain is being set up; the records are published at the domain's DNS provider, which may or may not be this account. Nothing is changed. The values are the provider's own mail hosts, relayed as the panel gives them.","x-mcp-tool":"get_email_dns","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The DNS an email service's domain must publish.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"verified":{"type":"object","description":"What the email control panel finds published right now.","properties":{"mx":{"type":["boolean","null"],"description":"Whether the panel finds the MX records published."},"spf":{"type":["boolean","null"],"description":"Whether the panel finds the SPF record published."},"dkim":{"type":["boolean","null"],"description":"Whether DKIM signing is enabled; null when no signing key exists yet."}},"required":["mx","spf","dkim"],"additionalProperties":false},"records":{"type":"array","description":"The records the domain must publish at its DNS provider.","items":{"type":"object","properties":{"type":{"type":"string","description":"MX or TXT."},"name":{"type":"string","description":"The record name; @ for the domain itself."},"value":{"type":"string","description":"The value to publish, as the provider gives it."},"priority":{"type":["integer","null"],"description":"For MX records."},"verified":{"type":["boolean","null"],"description":"Whether the panel finds this record published; null when it did not say."}},"required":["type","name","value","priority","verified"],"additionalProperties":false}}},"required":["domain","service_id","verified","records"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/dkim":{"post":{"operationId":"enable_email_dkim","tags":["Email"],"summary":"Enable DKIM signing","description":"Sets up DKIM signing for an email service, so receiving servers can verify its mail: a signing key is generated on the email control panel if there is none, and signing is switched on once the domain publishes the key's TXT record. Answers the record to publish and whether signing is enabled yet (pending_dns until the record is found). Safe to call again to check. The record is published at the domain's DNS provider.","x-mcp-tool":"enable_email_dkim","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of enabling DKIM signing.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"status":{"type":"string","description":"enabled: signing is on. pending_dns: publish the record, then call again.","enum":["enabled","pending_dns"]},"selector":{"type":"string","description":"The DKIM selector of the signing key."},"record":{"type":"object","description":"The TXT record the domain must publish.","properties":{"type":{"type":"string","description":"TXT."},"name":{"type":"string","description":"The record name, selector._domainkey.domain."},"value":{"type":"string","description":"The public key record to publish."}},"required":["type","name","value"],"additionalProperties":false}},"required":["domain","service_id","status","selector","record"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/catch-all":{"post":{"operationId":"set_email_catch_all","tags":["Email"],"summary":"Set the catch-all mailbox","description":"Makes one of an email service's mailboxes the catch-all: mail sent to any address on the domain that does not exist is delivered to it instead of bouncing. Replaces the current catch-all if there is one (the service detail shows it).","x-mcp-tool":"set_email_catch_all","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The mailbox on that domain that will receive mail for unknown addresses, by its full address; it must exist."}},"required":["address"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The catch-all setting of an email service.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"catch_all":{"type":["string","null"],"description":"The mailbox now receiving mail for unknown addresses; null when the domain has no catch-all."}},"required":["domain","service_id","catch_all"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/catch-all/delete":{"post":{"operationId":"remove_email_catch_all","tags":["Email"],"summary":"Remove the catch-all","description":"Turns an email service's catch-all off: mail to addresses on the domain that do not exist bounces from then on. The service detail shows which mailbox is the catch-all now.","x-mcp-tool":"remove_email_catch_all","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The catch-all setting of an email service.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"catch_all":{"type":["string","null"],"description":"The mailbox now receiving mail for unknown addresses; null when the domain has no catch-all."}},"required":["domain","service_id","catch_all"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes":{"get":{"operationId":"list_mailboxes","tags":["Email"],"summary":"List mailboxes","description":"The mailboxes of one of the account's email services, as the email control panel has them right now: each with its address and local part, name, state, whether it administers the service, and its storage; and how many mailboxes the plan allows. A mailbox is addressed by its domain and local part in the per-mailbox operations, both of which each row carries.","x-mcp-tool":"list_mailboxes","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"search","in":"query","required":false,"description":"Only mailboxes whose address or name contains this text.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The mailboxes of an email service.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"service_label":{"type":"string","description":"The service's label on the account."},"mailboxes":{"type":"array","description":"The mailboxes, as the email control panel lists them right now.","items":{"type":"object","description":"One mailbox as a list row.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain"],"additionalProperties":false}},"seats":{"type":["object","null"],"description":"The plan's mailbox allowance; null when the panel did not say.","properties":{"total":{"type":["integer","null"],"description":"How many mailboxes the plan allows."},"used":{"type":["integer","null"],"description":"How many exist."}},"required":["total","used"],"additionalProperties":false},"truncated":{"type":"boolean","description":"true when the service has more mailboxes than were listed."}},"required":["domain","service_id","service_label","mailboxes","seats","truncated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_mailbox","tags":["Email"],"summary":"Create a mailbox","description":"Adds a mailbox to one of the account's email services, on the email control panel, as the account holder. The mailboxes list shows the existing addresses and how many mailboxes the plan still allows. Refused, with nothing created, when the address exists or the plan has no seat left; the email control panel enforces its own password policy. The password is never echoed back.","x-mcp-tool":"create_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$","description":"The new mailbox. Its domain must be one of the account's email services and the address must not already exist on it. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts."},"password":{"type":"string","minLength":8,"maxLength":128,"description":"The mailbox's first password, chosen by the user. The email service enforces its own password policy and refuses weak ones; it is never echoed back."},"is_admin":{"type":"boolean","description":"true makes this mailbox an administrator of the email service, able to manage the other mailboxes in the provider's own control panel.","default":false},"alternate_email":{"type":"string","maxLength":254,"format":"email","description":"An address elsewhere that password-reset links for this mailbox can be sent to."},"send_login_details_to":{"type":"string","maxLength":254,"format":"email","description":"An address to send the new mailbox's login details to once it exists, e.g. the person who will use it."}},"required":["mailbox","password"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The mailbox just created.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false},"created":{"type":"boolean","description":"true: the mailbox now exists on the email control panel."},"login_details_sent":{"type":["boolean","null"],"description":"Whether the login details were sent to send_login_details_to; null when none was asked for."}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension","created","login_details_sent"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}":{"get":{"operationId":"get_mailbox","tags":["Email"],"summary":"Get a mailbox","description":"One mailbox on the account's email hosting, by its domain and local part: its name, state, whether it administers the email service, storage, alternate address, its aliases, and the suspension if it is suspended.","x-mcp-tool":"get_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/update":{"post":{"operationId":"update_mailbox","tags":["Email"],"summary":"Update a mailbox","description":"Changes a mailbox's settings on the email control panel: today, whether it administers the email service (an administrator can manage every mailbox in the provider's own control panel). Answers the mailbox as it stands after the change.","x-mcp-tool":"update_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox to change. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"is_admin":{"type":"boolean","description":"true grants, false withdraws, administration of the email service."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/delete":{"post":{"operationId":"delete_mailbox","tags":["Email"],"summary":"Delete a mailbox","description":"Deletes a mailbox on the email control panel: it stops receiving mail at once and its stored mail is removed after the provider's retention period; it cannot be restored from here. The full address is repeated as confirm_address, and a mismatch is refused before anything is looked up.","x-mcp-tool":"delete_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox to delete. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_address":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The full address repeated exactly, as the caller's confirmation that this mailbox and its mail are to be removed."}},"required":["confirm_address"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting a mailbox.","properties":{"address":{"type":"string","description":"The address that was deleted."},"service_id":{"type":"string","description":"The email service."},"domain":{"type":"string","description":"The email service's domain."},"deleted":{"type":"boolean","description":"true: the email control panel has deleted the mailbox."}},"required":["address","service_id","domain","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_address did not repeat the address exactly; nothing was changed.\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/password-reset":{"post":{"operationId":"send_mailbox_password_reset","tags":["Email"],"summary":"Send a mailbox password-reset link","description":"Sends a password-reset link for a mailbox to an address named in the request (the mailbox owner's other address, or the administrator's). The password itself cannot be set from here; the link lets its recipient choose a new one.","x-mcp-tool":"send_mailbox_password_reset","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox whose password is to be reset. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"recipient":{"type":"string","maxLength":254,"format":"email","description":"The address the password-reset link is sent to: the mailbox owner's other address, or the administrator's."}},"required":["recipient"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of sending a password-reset link.","properties":{"address":{"type":"string","description":"The mailbox whose password is to be reset."},"service_id":{"type":"string","description":"The email service."},"reset_link_sent_to":{"type":"string","description":"Where the reset link was sent."}},"required":["address","service_id","reset_link_sent_to"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/suspend":{"post":{"operationId":"suspend_mailbox","tags":["Email"],"summary":"Suspend a mailbox","description":"Suspends a mailbox on the email control panel: its user can no longer sign in or send, and mail to it is held, until it is unsuspended. Nothing is deleted. Answers the mailbox with its suspension.","x-mcp-tool":"suspend_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":200,"description":"Why it is being suspended; recorded with the suspension."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/unsuspend":{"post":{"operationId":"unsuspend_mailbox","tags":["Email"],"summary":"Unsuspend a mailbox","description":"Lifts a mailbox's suspension on the email control panel so its user can sign in and mail flows again. Answers the mailbox as it stands after.","x-mcp-tool":"unsuspend_mailbox","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The suspended mailbox. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/aliases":{"post":{"operationId":"add_mailbox_alias","tags":["Email"],"summary":"Add an alias to a mailbox","description":"Adds an alias to a mailbox: another address on the same domain whose mail is delivered to it and that it can send as. The alias must not already be a mailbox, alias or forwarder on the domain, and the email control panel limits how many a mailbox may have. Answers the mailbox with its aliases.","x-mcp-tool":"add_mailbox_alias","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox the alias delivers to. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"alias":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The alias, a full address on the same domain, e.g. info@example.com. It must not already be a mailbox, alias or forwarder."},"display_name":{"type":"string","maxLength":100,"description":"The name shown when mail is sent as the alias."}},"required":["alias"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/mailboxes/{mailbox}/aliases/delete":{"post":{"operationId":"remove_mailbox_alias","tags":["Email"],"summary":"Remove an alias from a mailbox","description":"Removes an alias from a mailbox: mail to that address is no longer delivered and the address becomes free. Answers the mailbox with its remaining aliases.","x-mcp-tool":"remove_mailbox_alias","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"mailbox","in":"path","required":true,"description":"The mailbox the alias belongs to. Given by the local part of its address: sales for sales@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"alias":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The alias to remove, a full address, as the mailbox detail lists it."}},"required":["alias"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One mailbox in full.","properties":{"address":{"type":"string","description":"The mailbox's full address."},"mailbox":{"type":"string","description":"The local part of the address; with domain, the input to the per-mailbox operations."},"name":{"type":["string","null"],"description":"The display name of the person using it."},"status":{"type":["string","null"],"description":"active or suspended."},"is_admin":{"type":"boolean","description":"Whether it administers the email service."},"storage":{"type":"object","description":"Storage in use and allowed.","properties":{"used":{"type":["integer","null"],"description":"Storage in use, in the email control panel's own unit."},"limit":{"type":["integer","null"],"description":"The mailbox's storage allowance, same unit."}},"required":["used","limit"],"additionalProperties":false},"alternate_email":{"type":["string","null"],"description":"An address elsewhere that password-reset links go to."},"created_at":{"type":["string","null"],"description":"When the mailbox was created."},"purge_at":{"type":["string","null"],"description":"For a deleted mailbox: when its data is removed for good."},"service_id":{"type":"string","description":"The email service the mailbox belongs to."},"domain":{"type":"string","description":"The email service's domain."},"aliases":{"type":"array","description":"Other addresses on the domain that deliver to this mailbox.","items":{"type":"object","properties":{"address":{"type":"string","description":"The alias, a full address on the domain."},"display_name":{"type":["string","null"],"description":"The name shown when mail is sent as the alias."}},"required":["address","display_name"],"additionalProperties":false}},"suspension":{"type":["object","null"],"description":"Why the mailbox is suspended, when it is; null otherwise.","properties":{"type":{"type":["string","null"],"description":"The kind of suspension, as the panel records it."},"note":{"type":["string","null"],"description":"The reason recorded with it."}},"required":["type","note"],"additionalProperties":false}},"required":["address","mailbox","name","status","is_admin","storage","alternate_email","created_at","purge_at","service_id","domain","aliases","suspension"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such mailbox on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/forwarders":{"get":{"operationId":"list_email_forwarders","tags":["Email"],"summary":"List email forwarders","description":"The forwarders of one of the account's email services: forward-only addresses (no mailbox of their own) that deliver to mailboxes on the same domain, e.g. team@example.com delivering to two people. A forwarder is addressed by its domain and local part in the per-forwarder operations, both of which each row carries.","x-mcp-tool":"list_email_forwarders","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The forwarders of an email service.","properties":{"domain":{"type":"string","description":"The email service's domain."},"service_id":{"type":"string","description":"The email service."},"forwarders":{"type":"array","description":"The forwarders, as the email control panel lists them.","items":{"type":"object","description":"One forwarder.","properties":{"address":{"type":"string","description":"The forwarder's full address."},"forwarder":{"type":"string","description":"The local part of the address; with domain, the input to the per-forwarder operations."},"recipients":{"type":"array","description":"The mailboxes on the same domain its mail is delivered to.","items":{"type":"string"}}},"required":["address","forwarder","recipients"],"additionalProperties":false}}},"required":["domain","service_id","forwarders"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_email_forwarder","tags":["Email"],"summary":"Create a forwarder","description":"Adds a forwarder to one of the account's email services: a forward-only address on the domain (no mailbox of its own) whose mail is delivered to one or more mailboxes on the same domain. Mail cannot be forwarded to addresses elsewhere. Refused, with nothing created, when the address exists or a recipient is not a mailbox on the domain.","x-mcp-tool":"create_email_forwarder","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"forwarder":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$","description":"The new forwarder. It must not already be a mailbox, alias or forwarder on the domain. Given by the local part of its address: info for info@example.com; a full address is split at its last @, and the rows of the listings carry both parts."},"recipients":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"},"description":"The mailboxes on the same domain that receive its mail; each must exist."}},"required":["forwarder","recipients"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The forwarder just created.","properties":{"address":{"type":"string","description":"The forwarder's full address."},"forwarder":{"type":"string","description":"The local part of the address; with domain, the input to the per-forwarder operations."},"recipients":{"type":"array","description":"The mailboxes on the same domain its mail is delivered to.","items":{"type":"string"}},"service_id":{"type":"string","description":"The email service."},"domain":{"type":"string","description":"The email service's domain."},"created":{"type":"boolean","description":"true: the forwarder now exists on the email control panel."}},"required":["address","forwarder","recipients","service_id","domain","created"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/forwarders/{forwarder}/update":{"post":{"operationId":"update_email_forwarder","tags":["Email"],"summary":"Update a forwarder","description":"Adds mailboxes to, or removes them from, a forwarder's recipients. Recipients must be mailboxes on the same domain. A removal the panel refuses after an addition went through is undone, so a refusal leaves the forwarder as it was. Answers the forwarder as it stands after.","x-mcp-tool":"update_email_forwarder","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"forwarder","in":"path","required":true,"description":"The forwarder to change. Given by the local part of its address: info for info@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"add":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"},"description":"Mailboxes on the same domain to add as recipients."},"remove":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"},"description":"Recipients to remove."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The forwarder after the change.","properties":{"address":{"type":"string","description":"The forwarder's full address."},"forwarder":{"type":"string","description":"The local part of the address; with domain, the input to the per-forwarder operations."},"recipients":{"type":"array","description":"The mailboxes on the same domain its mail is delivered to.","items":{"type":"string"}},"service_id":{"type":"string","description":"The email service."},"domain":{"type":"string","description":"The email service's domain."}},"required":["address","forwarder","recipients","service_id","domain"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such forwarder on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/email/{domain}/forwarders/{forwarder}/delete":{"post":{"operationId":"delete_email_forwarder","tags":["Email"],"summary":"Delete a forwarder","description":"Deletes a forwarder: mail to its address bounces from then on (or goes to the catch-all, if one is set). No mailbox or stored mail is affected. The full address is repeated as confirm_address, and a mismatch is refused before anything is looked up.","x-mcp-tool":"delete_email_forwarder","parameters":[{"name":"domain","in":"path","required":true,"description":"The email service's domain, e.g. example.com, as the email services list shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"forwarder","in":"path","required":true,"description":"The forwarder to delete. Given by the local part of its address: info for info@example.com; a full address is split at its last @, and the rows of the listings carry both parts.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_address":{"type":"string","maxLength":254,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._+-]{0,62}[A-Za-z0-9])?@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The full address repeated exactly, as the caller's confirmation."}},"required":["confirm_address"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of deleting a forwarder.","properties":{"address":{"type":"string","description":"The address that was deleted."},"forwarder":{"type":"string","description":"Its local part."},"service_id":{"type":"string","description":"The email service."},"domain":{"type":"string","description":"The email service's domain."},"deleted":{"type":"boolean","description":"true: the email control panel has deleted the forwarder."}},"required":["address","forwarder","service_id","domain","deleted"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before email management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No email service for this domain, or no such forwarder on it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_address did not repeat the address exactly; nothing was changed.\n`rejected`: The email control panel refused the change; the description carries its reason and nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers":{"get":{"operationId":"list_servers","tags":["Servers"],"summary":"List the servers","description":"Every server the account holds on the server management service, as it lists them now: hostname, status, primary address, data centre, size and operating system, with the account product each belongs to. Servers are named by hostname in every other server operation. The status word is relayed as the service gives it (today active or suspended; it is moving to the power state); get_server reads the authoritative power state. Products with no listed server appear under unavailable with a reason.","x-mcp-tool":"list_servers","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account's servers.","properties":{"servers":{"type":"array","description":"One entry per server the account holds, as the management service lists them now.","items":{"type":"object","description":"One of the account's servers.","properties":{"hostname":{"type":"string","description":"The server's hostname: how every other server operation names it."},"status":{"type":["string","null"],"description":"The service's status word for the server, relayed as-is: today active or suspended; the service is moving to the power state (running, stopped, rebooting, suspending). get_server's state is the authoritative power state."},"ip_address":{"type":["string","null"],"description":"The primary IPv4 address."},"site":{"type":["string","null"],"description":"The data centre, e.g. lon1."},"cpu":{"type":["integer","null"],"description":"Virtual CPUs."},"ram_mb":{"type":["integer","null"],"description":"Memory, in megabytes."},"disk_gb":{"type":["integer","null"],"description":"Root disk, in gigabytes."},"template":{"type":["string","null"],"description":"The operating system installed, by slug."},"service_id":{"type":["string","null"],"description":"The server product on the account this server belongs to; null when the account records no product for it."},"service_label":{"type":["string","null"],"description":"That product's name as the account shows it."}},"required":["hostname","status","ip_address","site","cpu","ram_mb","disk_gb","template","service_id","service_label"],"additionalProperties":false}},"unavailable":{"type":"array","description":"Server products on the account with no listed server, and why.","items":{"type":"object","properties":{"service_id":{"type":"string","description":"The server product on the account."},"label":{"type":"string","description":"The product's name as the account shows it."},"status":{"type":"string","description":"unavailable: the product is ready but the service lists no server for it right now. not_supported: the product cannot be managed through here; reason says why.","enum":["unavailable","not_supported"]},"reason":{"type":["string","null"],"description":"not_listed, not_listed_within_page_cap, not_provisioned or api_base_mismatch."}},"required":["service_id","label","status","reason"],"additionalProperties":false}},"truncated":{"type":"boolean","description":"true when the account holds more servers than the listing walked; the rest are addressable by hostname all the same."}},"required":["servers","unavailable","truncated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"422":{"description":"`not_supported`: The account has no unmanaged server that can be managed through this connection, or the product does not record what the service needs.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/operating-systems":{"get":{"operationId":"list_server_operating_systems","tags":["Servers"],"summary":"List the operating systems for reimaging","description":"The operating systems an unmanaged server may be reinstalled with, one per slug: what reimage_server takes as template. Read this fresh before a reimage rather than guessing a slug.","x-mcp-tool":"list_server_operating_systems","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The operating systems available for reimaging.","properties":{"operating_systems":{"type":"array","description":"Every operating system an unmanaged server may be reinstalled with, one per slug.","items":{"type":"object","properties":{"slug":{"type":"string","description":"What reimage_server takes as template."},"name":{"type":["string","null"],"description":"The distribution."},"version":{"type":["string","null"],"description":"Its version."},"family":{"type":["string","null"],"description":"The family (e.g. linux, windows)."}},"required":["slug","name","version","family"],"additionalProperties":false}}},"required":["operating_systems"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"422":{"description":"`not_supported`: The account has no unmanaged server that can be managed through this connection, or the product does not record what the service needs.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}":{"get":{"operationId":"get_server","tags":["Servers"],"summary":"Get a server","description":"One server by hostname, with its power state right now (running, stopped, or a transition), its primary address, data centre, size, operating system and whether the provider has suspended it. This is the read to follow a power action, restore or reimage with until the server is where it should be.","x-mcp-tool":"get_server","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server, by its hostname, e.g. vm1.example.com, as list_servers shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One server in full, with its power state.","properties":{"hostname":{"type":"string","description":"The server's hostname: how every other server operation names it."},"state":{"type":["string","null"],"description":"The power state right now: running, stopped, or a transition the service reports. null when the service did not say."},"status":{"type":["string","null"],"description":"The service's status word for the server, relayed as-is: today active or suspended; the service is moving to the power state (running, stopped, rebooting, suspending). get_server's state is the authoritative power state."},"ip_address":{"type":["string","null"],"description":"The primary IPv4 address."},"site":{"type":["string","null"],"description":"The data centre, e.g. lon1."},"cpu":{"type":["integer","null"],"description":"Virtual CPUs."},"ram_mb":{"type":["integer","null"],"description":"Memory, in megabytes."},"disk_gb":{"type":["integer","null"],"description":"Root disk, in gigabytes."},"template":{"type":["string","null"],"description":"The operating system installed, by slug."},"service_id":{"type":["string","null"],"description":"The server product on the account this server belongs to; null when the account records no product for it."},"service_label":{"type":["string","null"],"description":"That product's name as the account shows it."},"suspended":{"type":["boolean","null"],"description":"Whether the provider has suspended the server (billing or abuse); null when not reported."}},"required":["hostname","state","status","ip_address","site","cpu","ram_mb","disk_gb","template","service_id","service_label","suspended"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/stats":{"get":{"operationId":"get_server_stats","tags":["Servers"],"summary":"Get a server's resource usage","description":"The server's processor, memory, disk and network usage right now, from its guest agent: CPU as a fraction of one core (multiply by cores for the whole machine), memory and disk in bytes, network bytes since boot. Needs the server running with the guest agent; otherwise agent_unavailable, which is the server's condition, not an outage.","x-mcp-tool":"get_server_stats","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server, by its hostname, e.g. vm1.example.com, as list_servers shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A server's resource usage right now.","properties":{"hostname":{"type":"string","description":"The server."},"cpu":{"type":"object","description":"Processor.","properties":{"usage":{"type":["number","null"],"description":"Utilisation as a fraction of one core (0.5 is half a core); multiply by cores for the whole machine."},"cores":{"type":["integer","null"],"description":"Virtual CPUs assigned."}},"required":["usage","cores"],"additionalProperties":false},"memory":{"type":"object","description":"Memory, in bytes.","properties":{"used_bytes":{"type":["integer","null"],"description":"In use, including buffers and cache the guest reports."},"total_bytes":{"type":["integer","null"],"description":"Allocated to the server."},"free_bytes":{"type":["integer","null"],"description":"total_bytes less used_bytes."}},"required":["used_bytes","total_bytes","free_bytes"],"additionalProperties":false},"disk":{"type":"object","description":"Disk, in bytes.","properties":{"used_bytes":{"type":["integer","null"],"description":"Across all guest filesystems; 0 when the guest agent is not running."},"total_bytes":{"type":["integer","null"],"description":"The root disk as provisioned."}},"required":["used_bytes","total_bytes"],"additionalProperties":false},"network":{"type":"object","description":"Network, in bytes since boot.","properties":{"in_bytes":{"type":["integer","null"],"description":"Bytes received since the server started."},"out_bytes":{"type":["integer","null"],"description":"Bytes sent since the server started."}},"required":["in_bytes","out_bytes"],"additionalProperties":false}},"required":["hostname","cpu","memory","disk","network"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`agent_unavailable`: The server's guest agent did not answer: it is off, booting or running without the agent. get_server shows whether it is running.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["agent_unavailable"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/stats/{timeframe}":{"get":{"operationId":"get_server_stats_history","tags":["Servers"],"summary":"Get a server's usage history","description":"The server's processor, memory, disk throughput and network throughput over the last hour, day, week, month or year, one sample per row, oldest first; the service averages more coarsely the further back the window reaches. Use it to answer \"has this server been busy\" rather than polling get_server_stats.","x-mcp-tool":"get_server_stats_history","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server, by its hostname, e.g. vm1.example.com, as list_servers shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}},{"name":"timeframe","in":"path","required":true,"description":"How far back the history reaches: hour, day, week, month or year. The service averages more coarsely the further back it goes.","schema":{"type":"string","enum":["hour","day","week","month","year"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A server's resource usage over time.","properties":{"hostname":{"type":"string","description":"The server."},"timeframe":{"type":"string","description":"The window the samples cover."},"samples":{"type":"array","description":"Oldest first.","items":{"type":"object","properties":{"time":{"type":"string","description":"When the sample was taken.","format":"date-time"},"cpu_usage":{"type":["number","null"],"description":"Utilisation as a fraction of one core."},"cpu_cores":{"type":["integer","null"],"description":"Virtual CPUs at the time."},"memory_used_bytes":{"type":["integer","null"],"description":"Memory in use at the time."},"memory_total_bytes":{"type":["integer","null"],"description":"Memory allocated at the time."},"disk_read_bytes":{"type":["integer","null"],"description":"Bytes read per second over the sample."},"disk_write_bytes":{"type":["integer","null"],"description":"Bytes written per second over the sample."},"network_in_bytes":{"type":["integer","null"],"description":"Bytes received per second over the sample."},"network_out_bytes":{"type":["integer","null"],"description":"Bytes sent per second over the sample."}},"required":["time","cpu_usage","cpu_cores","memory_used_bytes","memory_total_bytes","disk_read_bytes","disk_write_bytes","network_in_bytes","network_out_bytes"],"additionalProperties":false}}},"required":["hostname","timeframe","samples"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`agent_unavailable`: The server's guest agent did not answer: it is off, booting or running without the agent. get_server shows whether it is running.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["agent_unavailable"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/filesystems":{"get":{"operationId":"get_server_filesystems","tags":["Servers"],"summary":"List a server's filesystems","description":"Every filesystem mounted on the server with its device, mount point, type, size and use, from its guest agent: the read for \"is the disk full\". Needs the server running with the guest agent; otherwise agent_unavailable.","x-mcp-tool":"get_server_filesystems","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server, by its hostname, e.g. vm1.example.com, as list_servers shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A server's mounted filesystems.","properties":{"hostname":{"type":"string","description":"The server."},"filesystems":{"type":"array","description":"Every mounted filesystem the guest agent reports.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The device, e.g. sda1."},"mountpoint":{"type":["string","null"],"description":"Where it is mounted, e.g. /."},"type":{"type":["string","null"],"description":"The filesystem type, e.g. ext4."},"total_bytes":{"type":["integer","null"],"description":"The filesystem's size."},"used_bytes":{"type":["integer","null"],"description":"In use."}},"required":["name","mountpoint","type","total_bytes","used_bytes"],"additionalProperties":false}}},"required":["hostname","filesystems"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`agent_unavailable`: The server's guest agent did not answer: it is off, booting or running without the agent. get_server shows whether it is running.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["agent_unavailable"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/backups":{"get":{"operationId":"list_server_backups","tags":["Servers"],"summary":"List a server's backups","description":"The backups held for the server, as the service lists them: the id restore_server_backup takes, the name given when it was taken, when, and its size. A backup create_server_backup queued appears here once it is done.","x-mcp-tool":"list_server_backups","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server, by its hostname, e.g. vm1.example.com, as list_servers shows it.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A server's backups.","properties":{"hostname":{"type":"string","description":"The server."},"backups":{"type":"array","description":"The backups held for the server, as the service lists them.","items":{"type":"object","properties":{"id":{"type":"string","description":"What restore_server_backup takes as archive."},"name":{"type":["string","null"],"description":"The name given when the backup was taken, when one was."},"created_at":{"type":["string","null"],"description":"When it was taken.","format":"date-time"},"size_bytes":{"type":["integer","null"],"description":"The backup's size."},"format":{"type":["string","null"],"description":"The backup format, as the service names it."}},"required":["id","name","created_at","size_bytes","format"],"additionalProperties":false}}},"required":["hostname","backups"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many server management sign-ins this hour; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]},"post":{"operationId":"create_server_backup","tags":["Servers"],"summary":"Back up a server","description":"Queues a one-off backup of the server's disk, optionally named. The service answers at once; the backup appears in list_server_backups when it is done, which can take a while for a large disk. On a server without a backup plan only one such backup is kept: the next overwrites it. On a server with a plan it counts towards the plan's retention.","x-mcp-tool":"create_server_backup","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server to back up, by its hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9 ._-]*$","description":"A name for the backup, up to 64 characters (letters, digits, space, dot, underscore, hyphen). Optional."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of requesting a backup.","properties":{"hostname":{"type":"string","description":"The server."},"name":{"type":["string","null"],"description":"The name the backup was given."},"status":{"type":"string","description":"The service has queued the backup; list_server_backups shows it when it is done.","enum":["queued"]}},"required":["hostname","name","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The service is not taking actions on the server right now (an earlier change is still running): try_later. Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/console":{"post":{"operationId":"get_server_console_url","tags":["Servers"],"summary":"Get a console link for the user","description":"A one-time link to the server's console in a browser, for the user to open themselves: how they get in when SSH is down or the server will not boot. The link is a secret minted on request, so this counts as a change (capped and audited). Hand the link to the user; do not open, log or repeat it. The server must be running (rejected, not_running, otherwise).","x-mcp-tool":"get_server_console_url","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server whose console the user wants, by its hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A console link for the user.","properties":{"hostname":{"type":"string","description":"The server."},"url":{"type":"string","description":"A one-time link to the server's console in a browser. Hand it to the user; do not open, log or repeat it."}},"required":["hostname","url"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The server is not running, so there is no console to open: not_running. Start it first.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/state":{"post":{"operationId":"set_server_state","tags":["Servers"],"summary":"Start, stop, reboot or reset a server","description":"A power action on the server: start, shutdown (clean power-off through the operating system), reboot (clean restart), stop (cut the power) or reset (cut and restore the power). Prefer shutdown and reboot; use stop and reset only when the server is not responding, since open files may be lost. Read get_server first to know the state, and follow with get_server until it is where it should be: the service queues the action and answers at once. A reboot may become a full power cycle when hardware changes are pending; note says so.","x-mcp-tool":"set_server_state","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server to act on, by its hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"state":{"type":"string","enum":["start","stop","shutdown","reboot","reset"],"description":"The power action: start (boot a stopped server), shutdown (ask the operating system to power off cleanly), reboot (ask it to restart cleanly), stop (cut the power: only when the server is not responding, since open files may be lost), reset (cut and restore the power: the same caveat). Prefer shutdown and reboot."}},"required":["state"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a power action.","properties":{"hostname":{"type":"string","description":"The server."},"requested":{"type":"string","description":"The power action the service accepted."},"state":{"type":["string","null"],"description":"The power state read back right after; a transition takes a little while, so follow with get_server. null when the read did not answer."},"note":{"type":["string","null"],"description":"What the service said about how it will carry the action out (a reboot may be a full power cycle when hardware changes are pending)."}},"required":["hostname","requested","state","note"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: The service is not taking actions on the server right now (an earlier change is still running): try_later. Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/rdns":{"post":{"operationId":"set_server_rdns","tags":["Servers"],"summary":"Set a server's reverse DNS","description":"Sets the name the server's primary IP address resolves back to (its PTR record): what mail servers check against the HELO name. Set the forward record for the name first. Only the primary address; additional addresses are not managed here.","x-mcp-tool":"set_server_rdns","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server whose primary address gets the reverse DNS name.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rdns":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The fully qualified name the primary IP address should resolve back to, e.g. mail.example.com. Set the forward record for it first."}},"required":["rdns"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a reverse DNS change.","properties":{"hostname":{"type":"string","description":"The server."},"ip_address":{"type":["string","null"],"description":"The primary address the name was set on."},"rdns":{"type":"string","description":"The name the address now resolves back to."}},"required":["hostname","ip_address","rdns"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/rename":{"post":{"operationId":"rename_server","tags":["Servers"],"summary":"Rename a server","description":"Changes the server's hostname on the service and, with update_rdns, the primary address's reverse DNS to match. From the answer onwards the server is addressed by the new name in every server operation; the old name stops resolving at once. Does not change the hostname inside the operating system. Refused (rejected, name_taken) when another server on the account already has the name.","x-mcp-tool":"rename_server","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server to rename, by its current hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The new hostname, fully qualified, e.g. vm2.example.com. It must not be the hostname of another server on the account. From then on the server is addressed by this name."},"update_rdns":{"type":"boolean","description":"true: the primary IP address's reverse DNS is set to the new name as well. Default false.","default":false}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of a rename.","properties":{"hostname":{"type":"string","description":"The server's new hostname: how every other server operation names it from now on."},"previous_hostname":{"type":"string","description":"What it was called."},"rdns_updated":{"type":"boolean","description":"Whether the primary address's reverse DNS was set to the new name too."}},"required":["hostname","previous_hostname","rdns_updated"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`rejected`: Another server on the account already has the name (name_taken), or the service is not taking actions on the server right now (try_later). Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/backups/restore":{"post":{"operationId":"restore_server_backup","tags":["Servers"],"summary":"Restore a server from a backup","description":"Writes a backup over the server's disk: everything on the disk now is lost and replaced by the backup's contents. Destructive, so the hostname is repeated as confirm_hostname and the server must be shut down first (rejected, shut_down_first, otherwise: use set_server_state with shutdown and wait for get_server to show it stopped). Take the backup's id from list_server_backups. The service queues the restore and answers at once; follow with get_server. Confirm with the user before calling.","x-mcp-tool":"restore_server_backup","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server to restore onto, by its hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"archive":{"type":"string","maxLength":255,"pattern":"^[A-Za-z0-9][A-Za-z0-9:.\\/_+-]{0,254}$","description":"The backup, by the id list_server_backups shows."},"force":{"type":"boolean","description":"true: restore even when the backup was taken from a different server configuration. Default false.","default":false},"confirm_hostname":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The hostname repeated exactly, as the caller's confirmation that this server's current disk is to be overwritten by the backup."}},"required":["archive","confirm_hostname"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of requesting a restore.","properties":{"hostname":{"type":"string","description":"The server."},"archive":{"type":"string","description":"The backup being restored."},"status":{"type":"string","description":"The service has queued the restore; get_server shows the server's state as it proceeds.","enum":["queued"]}},"required":["hostname","archive","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_hostname did not repeat the hostname; nothing was changed.\n`rejected`: The server must be shut down first (shut_down_first), or the service is not taking actions on it right now (try_later). Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/servers/{hostname}/reimage":{"post":{"operationId":"reimage_server","tags":["Servers"],"summary":"Reinstall a server's operating system","description":"Destroys everything on the server's disk and installs the operating system named by template afresh, authorising the given SSH public keys for root. There is no backup of its own: take one with create_server_backup first if anything on the disk matters. Destructive, so the hostname is repeated as confirm_hostname, and the template must be a slug list_server_operating_systems shows (rejected, template_unknown, otherwise). The service queues the reinstall and answers at once; follow with get_server until it is running on the new template. Confirm with the user before calling.","x-mcp-tool":"reimage_server","parameters":[{"name":"hostname","in":"path","required":true,"description":"The server to reinstall, by its hostname.","schema":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string","maxLength":64,"pattern":"^[a-z0-9][a-z0-9.-]{0,63}$","description":"The operating system, by the slug list_server_operating_systems shows, e.g. ubuntu-24-04."},"ssh_keys":{"type":"array","maxItems":10,"items":{"type":"string","maxLength":8192,"pattern":"^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp(256|384|521)|sk-ssh-ed25519@openssh\\.com|sk-ecdsa-sha2-nistp256@openssh\\.com) [A-Za-z0-9+\\/]+={0,2}( [^\\r\\n]{0,255})?$"},"description":"OpenSSH public keys to authorise for root on the fresh install, each as an authorized_keys line. At most 10. Optional, but without one the server is reachable only through the console."},"confirm_hostname":{"type":"string","maxLength":253,"pattern":"^[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+$","description":"The hostname repeated exactly, as the caller's confirmation that everything on this server's disk is to be destroyed and the operating system installed afresh."}},"required":["template","confirm_hostname"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The outcome of requesting a reinstall.","properties":{"hostname":{"type":"string","description":"The server."},"template":{"type":"string","description":"The operating system being installed."},"status":{"type":"string","description":"The service has queued the reinstall; get_server shows the server's state and template as it proceeds.","enum":["queued"]}},"required":["hostname","template","status"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`consent_required`: This connection was approved before server management was available through it; disconnect and connect again.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["consent_required","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No server with this hostname on the account; list_servers shows them.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"409":{"description":"`conflict`: Another change to the same target is already being processed; read it back before trying again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["conflict"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field. Or, with an `error` code:\n`not_confirmed`: confirm_hostname did not repeat the hostname; nothing was changed.\n`rejected`: The template is not one available for an unmanaged server (template_unknown), or the service is not taking actions on the server right now (try_later). Nothing was changed.\n`validation`: A field did not pass validation; the body names each failing field.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_supported","not_confirmed","rejected"]}}}]}]}}}},"429":{"description":"`too_many_attempts`: Too many changes in the last minute; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/tickets":{"get":{"operationId":"list_tickets","tags":["Support"],"summary":"List support tickets","description":"The account's support tickets, newest first. status=awaiting_response is the tickets where support is waiting on the customer, status=closed the resolved ones; omit status for everything. Each row's ticket_id is the input to the ticket detail and its messages. Tickets are read here, never opened or replied to. Paged with limit and offset.","x-mcp-tool":"list_tickets","parameters":[{"name":"status","in":"query","required":false,"description":"awaiting_response: support is waiting on the customer. open, client_replied, in_progress, scheduled: with support. closed: resolved. Omit for all.","schema":{"type":"string","enum":["open","awaiting_response","client_replied","in_progress","scheduled","closed"]}},{"name":"service_id","in":"query","required":false,"description":"Only tickets raised about this service (a service_id from the services list).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"tickets":{"type":"array","description":"The tickets of this page.","items":{"type":"object","description":"One support ticket as a list row.","properties":{"ticket_id":{"type":["string","null"],"description":"The ticket id; the input to the detail and the messages reads."},"reference":{"type":["string","null"],"description":"The ticket number support quotes."},"subject":{"type":["string","null"],"description":"What it is about."},"status":{"type":["string","null"],"description":"e.g. ticket_open, ticket_awaiting_response, ticket_closed."},"department":{"type":["string","null"],"description":"The support department handling it."},"assigned_to":{"type":["string","null"],"description":"The agent handling it, when one is assigned."},"service_id":{"type":["string","null"],"description":"The service the ticket is about, when it names one."},"created":{"type":["string","null"],"description":"When it was opened."},"updated":{"type":["string","null"],"description":"When it last changed."}},"required":["ticket_id","reference","subject","status","department","assigned_to","service_id","created","updated"],"additionalProperties":false}}},"required":["total","tickets"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/tickets/{ticket_id}":{"get":{"operationId":"get_ticket","tags":["Support"],"summary":"Get a support ticket","description":"One support ticket in full: subject, status, department, the agent handling it, the service it concerns and whether it is locked. The conversation is a separate, paged read on the same ticket.","x-mcp-tool":"get_ticket","parameters":[{"name":"ticket_id","in":"path","required":true,"description":"The ticket id from the tickets list.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"One support ticket in full. The conversation is a separate, paged read.","properties":{"ticket_id":{"type":["string","null"],"description":"The ticket id; the input to the detail and the messages reads."},"reference":{"type":["string","null"],"description":"The ticket number support quotes."},"subject":{"type":["string","null"],"description":"What it is about."},"status":{"type":["string","null"],"description":"e.g. ticket_open, ticket_awaiting_response, ticket_closed."},"department":{"type":["string","null"],"description":"The support department handling it."},"assigned_to":{"type":["string","null"],"description":"The agent handling it, when one is assigned."},"service_id":{"type":["string","null"],"description":"The service the ticket is about, when it names one."},"created":{"type":["string","null"],"description":"When it was opened."},"updated":{"type":["string","null"],"description":"When it last changed."},"service_identifier":{"type":["string","null"],"description":"The domain, hostname or account name of the service the ticket is about, when it names one."},"service_name":{"type":["string","null"],"description":"That service's product name."},"locked":{"type":["boolean","null"],"description":"Whether the ticket is locked against further replies."}},"required":["ticket_id","reference","subject","status","department","assigned_to","service_id","created","updated","service_identifier","service_name","locked"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No ticket with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/tickets/{ticket_id}/messages":{"get":{"operationId":"list_ticket_messages","tags":["Support"],"summary":"List a ticket's messages","description":"The conversation on one support ticket, oldest first: each message's body, who wrote it (the customer or support) and when, with attachments as file metadata only (downloading them is not available through this API). The support system's own log entries are left out. Paged with limit and offset.","x-mcp-tool":"list_ticket_messages","parameters":[{"name":"ticket_id","in":"path","required":true,"description":"The ticket id from the tickets list.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","description":"Rows matching the filter, across every page."},"messages":{"type":"array","description":"The messages of this page, oldest first.","items":{"type":"object","description":"One message of a ticket's conversation.","properties":{"message_id":{"type":["string","null"],"description":"The message id."},"body":{"type":["string","null"],"description":"The message, as written (HTML as the support system stores it)."},"created_at":{"type":["string","null"],"description":"When it was posted."},"author":{"type":"object","description":"Who wrote the message.","properties":{"name":{"type":["string","null"],"description":"Who wrote it."},"kind":{"type":"string","description":"customer: the account; support: an agent.","enum":["customer","support"]}},"required":["name","kind"],"additionalProperties":false},"attachments":{"type":"array","description":"The attachments, as metadata only; downloading them is not available through this API.","items":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The file name."},"size_bytes":{"type":["integer","null"],"description":"Its size."},"type":{"type":["string","null"],"description":"Its media type."}},"required":["name","size_bytes","type"],"additionalProperties":false}}},"required":["message_id","body","created_at","author","attachments"],"additionalProperties":false}}},"required":["total","messages"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No ticket with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/sessions":{"get":{"operationId":"list_sessions","tags":["Sessions"],"summary":"List sessions","description":"The account's live sessions: this CLI sign-in and every Connector connected through the browser flow, most recently used first. First-party CLI tokens only.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"The account's live sessions.","properties":{"data":{"type":"array","description":"The live sessions, most recently used first.","items":{"type":"object","description":"One of the account's live sessions.","properties":{"id":{"type":"string","description":"The session id, the input to DELETE /v1/sessions/{session_id}."},"client":{"type":"string","description":"Which client holds it: hosting-cli, or the Connector's name or host."},"last_used_at":{"type":["string","null"],"description":"When the session was last used.","format":"date-time"}},"required":["id","client","last_used_at"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`forbidden`: The bearer was not issued to the first-party CLI client.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["forbidden","insufficient_scope"]}}}]}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}},"/v1/sessions/{session_id}":{"delete":{"operationId":"revoke_session","tags":["Sessions"],"summary":"Revoke a session","description":"Ends one of the account's sessions, a Connector's or another CLI sign-in, revoking every token of it. Sessions of other accounts, and sessions already closed, are 404 so nothing is learned about them. First-party CLI tokens only.","parameters":[{"name":"session_id","in":"path","required":true,"description":"The session, as the sessions list shows it.","schema":{"type":"string","maxLength":128}}],"responses":{"204":{"description":"Done; no body"},"401":{"description":"`unauthorized`: No bearer token was sent.\n`invalid_token`: The bearer is invalid, expired or revoked, or its session was signed out.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"403":{"description":"`forbidden`: The bearer was not issued to the first-party CLI client.\n`insufficient_scope`: The bearer lacks the mcp:use scope.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["forbidden","insufficient_scope"]}}}]}}}},"404":{"description":"`not_found`: No live session with this id on the account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"422":{"description":"A field did not pass validation: the body names each failing field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"`too_many_attempts`: The per-client rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"502":{"description":"`upstream_error`: The upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"503":{"description":"`upstream_unavailable`: The upstream service is temporarily unavailable; retry shortly, after Retry-After when given.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}},"security":[{"bearer":[]},{"oauth2":["mcp:use"]}]}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"The access token from POST /v1/auth/login (or /v1/auth/mfa), refreshed with POST /v1/auth/refresh. Every /v1 and /mcp request carries it as `Authorization: Bearer <token>`."},"oauth2":{"type":"oauth2","description":"How a Connector signs in: the authorization code flow with PKCE (S256), the client identified by a registered client_id or by its Client ID Metadata Document URL. The pair it receives is used exactly like the CLI's.","flows":{"authorizationCode":{"authorizationUrl":"/oauth/authorize","tokenUrl":"/oauth/token","refreshUrl":"/oauth/token","scopes":{"mcp:use":"Read your hosting account details","offline_access":"Stay connected"}}}}},"schemas":{"Error":{"type":"object","description":"The one error body of the API, shaped like an OAuth error so every failure reads alike.","properties":{"error":{"type":"string","description":"A stable code to act on."},"error_description":{"type":"string","description":"A sentence for a person."}},"required":["error","error_description"]},"ValidationError":{"type":"object","description":"A request whose fields did not pass validation: nothing was looked up or changed.","properties":{"message":{"type":"string","description":"The first failure, as a sentence."},"errors":{"type":"object","description":"Every failing field with its messages.","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["message","errors"]}},"responses":{"Unauthorized":{"description":"401. No bearer, or a bearer that is invalid, expired, revoked or signed out. WWW-Authenticate says which.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["unauthorized","invalid_token"]}}}]}}}},"Forbidden":{"description":"403. The bearer lacks the scope, was issued to another client than the endpoint accepts, or belongs to a Connector connected before this ability existed (disconnect and connect again).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["insufficient_scope","forbidden","consent_required"]}}}]}}}},"NotFound":{"description":"404. Nothing matching the identifier on this account.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["not_found"]}}}]}}}},"TooManyRequests":{"description":"429. A rate limit was reached; Retry-After says when to try again.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["too_many_attempts"]}}}]}}}},"UpstreamError":{"description":"502. An upstream service answered something unexpected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_error"]}}}]}}}},"UpstreamUnavailable":{"description":"503. An upstream service is temporarily unavailable; retry shortly.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"error":{"enum":["upstream_unavailable"]}}}]}}}}}}}