# plsk.org documentation > plsk.org is a disposable Plesk playground for AI agents: MCP and REST access to a small, short-lived hosting subscription. This file holds every page; the account API reference is generated from https://api.plsk.org/openapi.json. --- Source: https://docs.plsk.org/ Updated: 2026-11-08 # Overview plsk.org provides short-lived Plesk hosting subscriptions that are operated through MCP and REST interfaces. A subscription is a Plesk customer on a shared server with a site at `https://.lab.plsk.org`, a file system, PHP 8.5, MySQL, and the Plesk REST API scoped to that customer. | Property | Value | |---|---| | Provisioning time | approximately 25 s | | Lifetime of a subscription | 14 days from the moment it is ready | | Active subscriptions per account | 5 | See [Limits](/limits) for resource limits. ## Endpoints All interfaces are served from `https://api.plsk.org`. | Base path | Interface | Credential | Reference | |---|---|---|---| | `/v1` | Account API: subscriptions, subscription keys, feedback. | Account key `plsa_…` | [Account API](/api/account) | | `/api/plesk/v2` (alias `/api/v2`) | Plesk REST API of one subscription. | Subscription key `plsk_…` | [Plesk REST API](/api/plesk) | | `/api/modules/wp-toolkit/v1` | WP Toolkit REST API of one subscription. | Subscription key `plsk_…` | [WP Toolkit REST API](/api/wp-toolkit) | | `/mcp` | MCP server (Streamable HTTP). | OAuth 2.0 access token `plso_…` | [MCP reference](/mcp) | Machine-readable descriptions: | Path | Content | |---|---| | `/openapi.json` | OpenAPI document of the account API and the gateway. | | `/plesk-openapi.json` | OpenAPI document of the Plesk REST API, with the gateway as its server. No credential required. | | `/.well-known/api-catalog` | API catalog (RFC 9727). | | `/.well-known/oauth-protected-resource/mcp` | OAuth protected resource metadata of the MCP server. | ## Documentation - [API reference](/api): authentication, request handling, error format. - [MCP reference](/mcp): tools, parameters, scopes. - Examples: [MCP session](/quickstart-agent), [REST session](/quickstart-rest), [static site](/examples/static-site), [PHP and MySQL](/examples/php-mysql), [WordPress](/examples/wordpress), [subdomains and certificates](/examples/subdomains). - [Troubleshooting](/troubleshooting). - [Limits](/limits), [Feedback](/feedback). --- Source: https://docs.plsk.org/api Updated: 2026-11-08 # API reference Base URL: `https://api.plsk.org`. ## Interfaces | Base path | Interface | Credential | |---|---|---| | `/v1` | Account API. See [Account API](/api/account). | Account key | | `/api/plesk/v2` | Plesk REST API of one subscription. See [Plesk REST API](/api/plesk). | Subscription key | | `/api/modules/wp-toolkit/v1` | WP Toolkit REST API of one subscription. See [WP Toolkit REST API](/api/wp-toolkit). | Subscription key | | `/mcp` | MCP server. See [MCP reference](/mcp). | OAuth access token | Aliases: `/api/v2` is equivalent to `/api/plesk/v2`. ## Authentication A key is sent in one of two headers: ``` X-API-Key: Authorization: Bearer ``` | Credential | Prefix | Issued by | Valid for | Applies to | |---|---|---|---|---| | Account key | `plsa_` | Cabinet, section Agents | 1 day, 7 days or 30 days | `/v1` | | Subscription key | `plsk_` | `POST /v1/subscriptions/{id}/keys` | 1 day, 7 days or until the subscription expires | `/api/plesk/v2`, `/api/modules/*` | | Access token | `plso_` | OAuth 2.0 authorization code flow at `https://my.plsk.org` | at most 30 days | `/mcp` | An account key has a scope. `read` permits listing and reading. `manage` additionally permits creating, retrying and deleting subscriptions and managing keys. `POST /v1/feedback` accepts either scope. A subscription key is bound to one subscription and expires no later than that subscription. A subscription has at most one active key. The key value is returned once, at creation. ## Request handling For `/api/plesk/v2` and `/api/modules/*` the gateway performs these steps: 1. Validates the key: it exists, is not revoked and not expired, and the subscription is available. 2. Applies the rate limit of the key. 3. Validates the target against the rules below. 4. Replaces the key with the Plesk credential of the subscription and forwards the request. 5. Returns the status, headers and body of the Plesk response. `Set-Cookie` and hop-by-hop headers are removed. Path, query, method and body are forwarded unchanged. Request headers are forwarded except credentials, routing headers and hop-by-hop headers. Targets that are not forwarded: | Target | Result | |---|---| | `/api/plesk/v2/auth/...` (Plesk API keys, panel sessions) | `403 blocked_path` | | `/api/modules//...` for an extension other than `wp-toolkit` | `403 blocked_path` | | Dot segments, encoded slashes or backslashes, control characters, fragments, targets longer than 8192 characters | `400 bad_path` | ## Limits | Limit | Value | |---|---| | Requests per key | 120 per minute | | Request body | 10 MiB | | Upstream timeout | 60 s | ## Errors Errors produced by the platform use this format: ``` {"error": {"code": "", "message": ""}} ``` | Status | Code | Condition | |---|---|---| | 400 | `bad_path` | The target is not acceptable. | | 400 | `bad_request` | The request is malformed. | | 401 | `invalid_key` | The key is missing, unknown, revoked or expired. The response carries `WWW-Authenticate: Bearer realm="plsk"`. | | 403 | `blocked_path` | The target is not offered by the gateway. | | 413 | `body_too_large` | The body exceeds 10 MiB. | | 429 | `rate_limited` | The rate limit is exceeded. The response carries `Retry-After` in seconds. | | 500 | `internal_error` | Internal error. | | 502 | `upstream_unavailable` | Plesk could not be reached. | | 504 | `upstream_timeout` | Plesk did not answer within the timeout. | Status codes and bodies produced by Plesk are returned as received. See [Troubleshooting](/troubleshooting) for their interpretation. ## Account API conventions - `POST /v1/subscriptions` requires the header `Idempotency-Key` (1 to 64 characters from `A-Z a-z 0-9 _ -`). A repeated request with the same key returns the existing subscription with status 200; the first request returns 201. - `DELETE /v1/subscriptions/{id}` and `POST /v1/subscriptions/{id}/retry` return 202. - Account API errors use the format above with the codes listed in [Account API](/api/account). --- Source: https://docs.plsk.org/api/plesk Updated: 2026-11-08 # Plesk REST API Base URL: `https://api.plsk.org/api/plesk/v2`. Credential: subscription key. Authentication, rate limit and error format: [API reference](/api). The gateway forwards requests to the Plesk REST API of the server that hosts the subscription. Paths, parameters, bodies and responses are those of Plesk. Plesk executes the request as the Plesk customer that owns the subscription; operations that this customer is not permitted to perform are refused by Plesk. The OpenAPI document is available without a credential at `https://api.plsk.org/plesk-openapi.json`. Its `servers` entry is the gateway. Operations under `/auth` are not served. ## Operations used with subscriptions | Method | Path | Purpose | |---|---|---| | `GET` | `/domains` | List the domains of the subscription. | | `POST` | `/domains` | Create a subdomain. | | `GET` | `/domains/{id}/fs` | Metadata of a file or directory (`path`). | | `GET` | `/domains/{id}/fs/list` | List a directory (`path`). | | `GET` | `/domains/{id}/fs/content` | Read a file (`path`). | | `PUT` | `/domains/{id}/fs/content` | Write a file (`path`). | | `PATCH` | `/domains/{id}/fs/content` | Append a chunk to a file (`path`). | | `POST` | `/domains/{id}/fs/mkdir` | Create a directory. | | `POST` | `/domains/{id}/fs/copy` | Copy a file or directory. | | `POST` | `/domains/{id}/fs/move` | Move or rename a file or directory. | | `DELETE` | `/domains/{id}/fs` | Delete a file or directory (`path`). | | `GET` `POST` | `/databases` | List or create databases. | | `DELETE` | `/databases/{id}` | Delete a database. | | `GET` `POST` | `/dbusers` | List or create database users. | | `PUT` `DELETE` | `/dbusers/{id}` | Update or delete a database user. | ## Request bodies File write (`PUT` and `PATCH` `/domains/{id}/fs/content?path=`): ``` {"encoding": "plain" | "base64", "content": ""} ``` Subdomain (`POST /domains`): ``` {"name": "