{"openapi":"3.1.0","info":{"title":"Hosting API","version":"1.6.4","summary":"The hosting.com account API: services, billing, domains, websites, email 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, `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://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, reached on the control panel as the customer: sites, shell access, applications, runtime, databases, mapped domains and certificates."},{"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":"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. 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.","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":"Which second factor was asked for, e.g. an authenticator app or an emailed code."},"expires_in":{"type":"integer","description":"Seconds the challenge stays open."}},"required":["mfa_required","challenge_id","provider","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"]}}}]}}}},"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. 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 code from the second factor."}},"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"]}}}]}}}},"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/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. 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."},"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","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."},"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","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."},"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","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."},"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","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"]}]}},"/v1/domains/search":{"get":{"operationId":"check_domain_availability","tags":["Domains"],"summary":"Check domain availability","description":"Whether a domain can be registered, with its prices. Give sld (the label before the dot) on its own for suggestions across the TLDs on sale, or with tld for one exact name. Results come from the brand's catalogue, so only the TLDs it sells appear. Prices are in currency_code when given, otherwise the account's default currency, or the brand's if the account has none.","x-mcp-tool":"check_domain_availability","parameters":[{"name":"sld","in":"query","required":true,"description":"Second-level label without the dot, e.g. \"example\" for example.com.","schema":{"type":"string","pattern":"^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"}},{"name":"tld","in":"query","required":false,"description":"A specific TLD without the leading dot, e.g. \"com\" or \"co.uk\". Omit for suggestions across the TLDs on sale.","schema":{"type":"string","pattern":"^[A-Za-z0-9-]{2,63}(?:\\.[A-Za-z0-9-]{2,63})*$"}},{"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}$"}},{"name":"limit","in":"query","required":false,"description":"Maximum results, 1 to 50.","schema":{"type":"integer","minimum":1,"maximum":50,"default":10}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"A domain availability search.","properties":{"results":{"type":"array","description":"One row per name checked: the exact name when a TLD was given, else suggestions across the TLDs on sale.","items":{"type":"object","properties":{"domain":{"type":["string","null"],"description":"The full name checked."},"sld":{"type":["string","null"],"description":"The label before the dot."},"tld":{"type":["string","null"],"description":"The TLD."},"available":{"type":["boolean","null"],"description":"Whether it can be registered."},"premium":{"type":["boolean","null"],"description":"Whether the registry prices it as a premium name."},"prices":{"type":"array","description":"The prices the catalogue offers it at.","items":{"type":"object","properties":{"amount":{"type":["number","null"],"description":"The price."},"renewal_amount":{"type":["number","null"],"description":"The price of a renewal for the same period, when it differs."},"currency":{"type":["string","null"],"description":"ISO 4217 code of amount."},"period_months":{"type":["integer","null"],"description":"The registration period the price buys."}},"required":["amount","renewal_amount","currency","period_months"],"additionalProperties":false}}},"required":["domain","sld","tld","available","premium","prices"],"additionalProperties":false}}},"required":["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":"`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."},"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","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/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 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.","items":{"type":"string"}},"status":{"type":["string","null"],"description":"active or disabled."},"suspended":{"type":"boolean","description":"Whether the website is suspended."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"plan":{"type":["string","null"],"description":"The hosting plan name on the control panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running."},"created_at":{"type":["string","null"],"description":"When the website was created."},"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","status","suspended","kind","plan","php_version","pending_backup","created_at","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."},"status":{"type":"string","description":"ok: its websites are in the list. unavailable: its control panel could not be reached just now. not_supported: not manageable through this connection.","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","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":"Adds a website for a domain on one of the account's hosting services, on the control panel, as the account holder. The websites list shows which hosting services can hold websites (service_id is required when there is more than one) and whether the domain is already a website. Refused, with nothing created, when the domain is already in use on the platform or the hosting plan allows no more websites. The hosting writes the domain's DNS records itself. The answer's preview_domain is where the finished site can be seen before its domain resolves.","x-mcp-tool":"create_website","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 the new website will answer to, e.g. example.com or shop.example.com. It must not already be a website on the account."},"service_id":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]*$","description":"The hosting service to create the website on, as the websites list identifies it. Required when the account has more than one hosting service that can hold websites; omit when it has one."},"php_version":{"type":"string","pattern":"^php[0-9]{2}$","description":"The PHP version to start on, as the control panel names it, e.g. php83. Omit for the hosting plan's default."}},"required":["domain"]}}}},"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.","items":{"type":"string"}},"status":{"type":["string","null"],"description":"active or disabled."},"suspended":{"type":"boolean","description":"Whether the website is suspended."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"plan":{"type":["string","null"],"description":"The hosting plan name on the control panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running."},"created_at":{"type":["string","null"],"description":"When the website was created."},"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.","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"}},"size_bytes":{"type":["integer","null"],"description":"Disk in use."},"tags":{"type":"array","description":"The panel's tags on the website.","items":{"type":"string"}},"preview_domain":{"type":["string","null"],"description":"A hostname the new site can be opened on before its own domain resolves; null when the control panel could not give one."},"created":{"type":"boolean","description":"true: the website now exists on the control panel."},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","aliases","status","suspended","kind","plan","php_version","pending_backup","created_at","service_id","service_label","subdomains","document_root","server_ips","size_bytes","tags","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 hosting service on the account can hold websites, 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`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}":{"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.","items":{"type":"string"}},"status":{"type":["string","null"],"description":"active or disabled."},"suspended":{"type":"boolean","description":"Whether the website is suspended."},"kind":{"type":"string","description":"normal, or staging for a staging copy."},"plan":{"type":["string","null"],"description":"The hosting plan name on the control panel."},"php_version":{"type":["string","null"],"description":"As the control panel names it, e.g. php83."},"pending_backup":{"type":["string","null"],"description":"backup or restore while one is running."},"created_at":{"type":["string","null"],"description":"When the website was created."},"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.","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"}},"size_bytes":{"type":["integer","null"],"description":"Disk in use."},"tags":{"type":"array","description":"The panel's tags on the website.","items":{"type":"string"}}},"required":["domain","aliases","status","suspended","kind","plan","php_version","pending_backup","created_at","service_id","service_label","subdomains","document_root","server_ips","size_bytes","tags"],"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."},"deleted":{"type":"boolean","description":"true: the control panel has marked the website deleted."}},"required":["domain","service_id","service_label","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."},"ssh":{"type":"object","description":"Where to connect over SSH and SFTP.","properties":{"host":{"type":["string","null"],"description":"The hostname to connect to."},"port":{"type":"integer","description":"The SSH port."},"user":{"type":["string","null"],"description":"The website's own shell user."}},"required":["host","port","user"],"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."}},"required":["domain","service_id","service_label","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 authorised SSH keys.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"keys":{"type":"array","description":"The keys authorised to log in as the shell user; the keys themselves are not repeated.","items":{"type":"object","properties":{"key_id":{"type":["string","null"],"description":"The handle the remove operation takes."},"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."},"created_at":{"type":["string","null"],"description":"When it was added."}},"required":["key_id","name","type","fingerprint","created_at"],"additionalProperties":false}}},"required":["domain","service_id","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 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 panel 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 authorised.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"key_id":{"type":["string","null"],"description":"The handle the remove operation takes."},"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 authorised."},"next_steps":{"type":"array","description":"What follows in a deploy.","items":{"type":"string"}}},"required":["domain","service_id","key_id","name","type","fingerprint","added","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}/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."},"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","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}/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."},"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 the control panel 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.","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 the control panel sees it.","properties":{"domain":{"type":"string","description":"The website's domain."},"service_id":{"type":"string","description":"The hosting service."},"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","description":"Whether maintenance mode is on."},"plugins":{"type":["integer","null"],"description":"How many plugins it has."},"users":{"type":["integer","null"],"description":"How many users it has."},"woocommerce":{"type":["boolean","null"],"description":"Whether WooCommerce is installed."}},"required":["domain","service_id","app","path","version","site_url","maintenance_mode","plugins","users","woocommerce"],"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"]}}}]}}}},"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.","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; 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/update":{"post":{"operationId":"update_wordpress_version","tags":["Websites"],"summary":"Update WordPress core","description":"Updates a website's WordPress core to the latest version the control panel offers. Answers the version afterwards when the panel reports it.","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":"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.","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}/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."},"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","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."}},"required":["app_id","kind","command","working_directory","start_mode","node_version","path","port","websockets"],"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/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/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"]}}}]}}}}}}}