{
  "openapi": "3.1.0",
  "info": {
    "title": "WebPros Public API",
    "version": "1"
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://dashboard.webpros.com/api/v1"
    }
  ],
  "tags": [
    {
      "name": "Accounts",
      "description": "Team and invitation management."
    },
    {
      "name": "API tokens",
      "description": "Managing the API tokens of the calling user. Requires a token carrying the\n`manage-api-tokens` claim.\n"
    },
    {
      "name": "MCP keys",
      "description": "Managing the MCP key the request is authenticated with."
    },
    {
      "name": "Server Inventory",
      "description": "Connecting servers to Server Inventory and reading the connected ones."
    }
  ],
  "paths": {
    "/accounts/email/invite": {
      "post": {
        "tags": [
          "Accounts"
        ],
        "summary": "Sends an invitation email and returns a team GUID for the given email address",
        "description": "Supported `type` values:\n\n  `premium-email:partner` — meta is optional and ignored if provided.\n\n  `premium-email:smb` — meta is required and must include `entitlementId`, `planName` and `domain`.\n\nNote: An invitation email is sent on every valid call to this endpoint.\n",
        "operationId": "emailInvite",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PremiumEmailInviteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PremiumEmailInviteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/dashboard/api-tokens": {
      "get": {
        "tags": [
          "API tokens"
        ],
        "summary": "Get the list of the API tokens of the calling user",
        "operationId": "listApiTokens",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/ApiTokenNameFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTokenListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The token does not carry the `manage-api-tokens` claim",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "API tokens"
        ],
        "summary": "Create a new API token",
        "description": "Creates an API token for the calling user and returns it together with its\nsecret. The secret is returned **only** by this call and cannot be read\nagain afterwards.\n\nA token may carry zero, one, or several claims. An empty `claims` array\ncreates an unrestricted token; every other value scopes the new token. A\nrestricted caller cannot create a token broader than itself — attempting\nit fails with `403`. Read-only tokens (an `mcp` claim with\n`readonly: true`) cannot create tokens at all.\n",
        "operationId": "createApiToken",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiTokenRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTokenWithSecretResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, or a claim references an unknown server",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The token does not carry the `manage-api-tokens` claim, is read-only,\nor the requested claims are broader than the caller's own.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          }
        }
      }
    },
    "/dashboard/api-tokens/{tokenId}": {
      "get": {
        "tags": [
          "API tokens"
        ],
        "summary": "Get a single API token of the calling user by its identifier",
        "operationId": "getApiToken",
        "parameters": [
          {
            "$ref": "#/components/parameters/TokenId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The token does not carry the `manage-api-tokens` claim",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "API token not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "API tokens"
        ],
        "summary": "Delete an API token of the calling user by its identifier",
        "description": "A token cannot delete itself, and a read-only token (an `mcp` claim with\n`readonly: true`) cannot delete tokens at all.\n",
        "operationId": "deleteApiToken",
        "parameters": [
          {
            "$ref": "#/components/parameters/TokenId"
          }
        ],
        "responses": {
          "204": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The token does not carry the `manage-api-tokens` claim, is read-only,\nor the removal is not allowed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "API token not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/dashboard/mcp-keys/current": {
      "delete": {
        "tags": [
          "MCP keys"
        ],
        "summary": "Revoke the MCP key the request is authenticated with",
        "description": "Deletes the calling MCP key, so it stops working right away. Read-only keys\n(an `mcp` claim with `readonly: true`) can revoke themselves too.\n",
        "operationId": "revokeCurrentMcpKey",
        "responses": {
          "204": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized, or the key is already revoked or expired"
          },
          "403": {
            "description": "The token does not carry the `mcp` claim, or the removal is not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          }
        }
      }
    },
    "/si/product-info/plesk/supported-versions": {
      "get": {
        "tags": [
          "Server Inventory"
        ],
        "summary": "Get the list of supported Plesk versions",
        "operationId": "getSupportedPleskVersions",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "uniqueItems": true,
                      "items": {
                        "type": "string",
                        "minLength": 1
                      },
                      "example": [
                        "1.2.3",
                        "1.2.4"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/si/servers": {
      "get": {
        "tags": [
          "Server Inventory"
        ],
        "summary": "Get list of servers from Server Inventory",
        "operationId": "listServers",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "totalCount",
                    "data"
                  ],
                  "properties": {
                    "totalCount": {
                      "type": "integer",
                      "example": 1
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "guid",
                          "product",
                          "address",
                          "active"
                        ],
                        "properties": {
                          "guid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "product": {
                            "type": "string",
                            "enum": [
                              "plesk",
                              "cpanel"
                            ]
                          },
                          "address": {
                            "type": "string",
                            "format": "uri",
                            "example": "https://example.com"
                          },
                          "active": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/si/servers/challenge": {
      "post": {
        "tags": [
          "Server Inventory"
        ],
        "summary": "Generate a challenge for adding a server.",
        "operationId": "createAddServerChallenge",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address",
                  "product"
                ],
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "product": {
                    "type": "string",
                    "enum": [
                      "plesk",
                      "cpanel"
                    ]
                  },
                  "allowUnsecureConnection": {
                    "type": "boolean"
                  }
                },
                "example": {
                  "address": "https://server-with-plesk.test:8443",
                  "product": "plesk"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "challenge",
                        "scope",
                        "callback_url"
                      ],
                      "properties": {
                        "challenge": {
                          "type": "string"
                        },
                        "scope": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "callback_url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/si/api-key": {
      "post": {
        "tags": [
          "Server Inventory"
        ],
        "summary": "Add a server to Server Inventory.",
        "operationId": "addServerApiKey",
        "description": "Send this request to the absolute `callback_url` returned by\n`/si/servers/challenge`. The challenge token is passed either as the\n`code` query parameter or as the `code` property of the request body.\n",
        "security": [],
        "parameters": [
          {
            "in": "query",
            "name": "code",
            "description": "A challenge value from /si/servers/challenge response.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "api_key",
                  "scope"
                ],
                "properties": {
                  "api_key": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "array",
                    "description": "A scope value from /si/servers/challenge response.",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid challenge token"
          }
        }
      }
    },
    "/si/servers/{guid}": {
      "delete": {
        "tags": [
          "Server Inventory"
        ],
        "summary": "Delete a server from Server Inventory by GUID.",
        "operationId": "deleteServer",
        "parameters": [
          {
            "in": "path",
            "name": "guid",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Server GUID."
          }
        ],
        "responses": {
          "204": {
            "description": "OK"
          },
          "404": {
            "description": "Server not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API token issued to a user. A token carrying no claims is\nunrestricted and may call any operation; a token carrying claims may only\ncall the operations that require exactly those claims.\n"
      }
    },
    "parameters": {
      "Page": {
        "in": "query",
        "name": "page",
        "required": false,
        "description": "Pagination page number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000000,
          "default": 1
        }
      },
      "PageSize": {
        "in": "query",
        "name": "pageSize",
        "required": false,
        "description": "Pagination page size.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 10
        }
      },
      "ApiTokenNameFilter": {
        "in": "query",
        "name": "filter",
        "required": false,
        "description": "Case-insensitive substring matched against the token name.",
        "schema": {
          "type": "string",
          "maxLength": 1000
        }
      },
      "TokenId": {
        "in": "path",
        "name": "tokenId",
        "required": true,
        "description": "API token identifier.",
        "schema": {
          "type": "integer"
        },
        "example": 42
      }
    },
    "schemas": {
      "PremiumEmailInviteType": {
        "title": "Premium email invitation type",
        "description": "Determines which invitation flow is used and whether the `meta` object is required.",
        "type": "string",
        "enum": [
          "premium-email:partner",
          "premium-email:smb"
        ]
      },
      "PremiumEmailInviteRequest": {
        "title": "Premium email invite request",
        "description": "Request payload for sending a premium email invitation.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/PremiumEmailInvitePartnerRequest"
          },
          {
            "$ref": "#/components/schemas/PremiumEmailInviteSmbRequest"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "premium-email:partner": "#/components/schemas/PremiumEmailInvitePartnerRequest",
            "premium-email:smb": "#/components/schemas/PremiumEmailInviteSmbRequest"
          }
        }
      },
      "PremiumEmailInviteBaseRequest": {
        "title": "Premium email invite base request",
        "description": "Common fields for all premium email invitation requests.",
        "type": "object",
        "required": [
          "email",
          "type"
        ],
        "properties": {
          "email": {
            "description": "Email address that will receive the invitation.",
            "type": "string",
            "format": "email",
            "example": "john@example.com"
          },
          "type": {
            "$ref": "#/components/schemas/PremiumEmailInviteType"
          }
        }
      },
      "PremiumEmailInvitePartnerRequest": {
        "title": "Partner invitation request",
        "description": "Invitation request for the partner flow. The `meta` object is ignored.",
        "example": {
          "email": "john@example.com",
          "type": "premium-email:partner"
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/PremiumEmailInviteBaseRequest"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "premium-email:partner"
              }
            }
          }
        ]
      },
      "PremiumEmailInviteSmbRequest": {
        "title": "SMB invitation request",
        "description": "Invitation request for the SMB flow. The `meta` object is required.",
        "example": {
          "email": "john@example.com",
          "type": "premium-email:smb",
          "meta": {
            "entitlementId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
            "planName": "Business Email 10",
            "domain": "example.com"
          }
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/PremiumEmailInviteBaseRequest"
          },
          {
            "type": "object",
            "required": [
              "meta"
            ],
            "properties": {
              "type": {
                "const": "premium-email:smb"
              },
              "meta": {
                "description": "Additional data required for the SMB invitation flow.",
                "type": "object",
                "required": [
                  "entitlementId",
                  "planName",
                  "domain"
                ],
                "properties": {
                  "entitlementId": {
                    "description": "Premium Email entitlement id.",
                    "type": "string",
                    "format": "uuid",
                    "example": "d290f1ee-6c54-4b01-90e6-d701748f0851"
                  },
                  "planName": {
                    "description": "Premium Email plan name.",
                    "type": "string",
                    "example": "Business Email 10"
                  },
                  "domain": {
                    "description": "Domain that will be used for the Premium Email subscription.",
                    "type": "string",
                    "example": "example.com"
                  }
                }
              }
            }
          }
        ]
      },
      "PremiumEmailInviteResponse": {
        "title": "Premium email invite response",
        "description": "HTTP response wrapper returned after the invitation email is queued successfully.",
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "description": "Payload containing the team GUID associated with the invited email address.",
            "$ref": "#/components/schemas/PremiumEmailInviteResponseData"
          }
        },
        "example": {
          "data": {
            "guid": "91dd39cb-69b8-4dfc-aef0-0ba335ba9581"
          }
        }
      },
      "PremiumEmailInviteResponseData": {
        "title": "Premium email invite response data",
        "description": "Response payload returned after the invitation email is queued successfully.",
        "type": "object",
        "required": [
          "guid"
        ],
        "properties": {
          "guid": {
            "description": "Team GUID associated with the invited email address.",
            "type": "string",
            "format": "uuid",
            "example": "91dd39cb-69b8-4dfc-aef0-0ba335ba9581"
          }
        }
      },
      "ApiTokenClaimName": {
        "title": "API token claim name",
        "description": "The permission key of a claim. `mcp` scopes a token to the MCP surface,\noptionally to a single server and panel user; `manage-api-tokens` grants\nthe ability to manage API tokens.\n",
        "type": "string",
        "enum": [
          "mcp",
          "manage-api-tokens"
        ]
      },
      "McpClaimAttributes": {
        "title": "MCP claim attributes",
        "description": "Scopes an `mcp` claim to a single server, and optionally to a single panel\nuser on that server. Omitting `panelUser` scopes the token to the server\nalone.\n",
        "type": "object",
        "required": [
          "serverGuid"
        ],
        "properties": {
          "serverGuid": {
            "description": "GUID of the server the token is scoped to.",
            "type": "string",
            "minLength": 1,
            "example": "91dd39cb-69b8-4dfc-aef0-0ba335ba9581"
          },
          "panelUser": {
            "description": "Login of the panel user the token is scoped to.",
            "type": "string",
            "minLength": 1,
            "example": "john"
          }
        }
      },
      "McpClaimRequest": {
        "title": "MCP claim",
        "description": "Scopes the token to the MCP surface. `readonly` restricts it to read\ntools and methods; it is independent of the server scope in `attributes`.\n",
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "const": "mcp"
          },
          "readonly": {
            "type": "boolean"
          },
          "attributes": {
            "$ref": "#/components/schemas/McpClaimAttributes"
          }
        }
      },
      "ManageApiTokensClaimRequest": {
        "title": "Manage API tokens claim",
        "description": "Grants the ability to manage API tokens. Carries no attributes.",
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "const": "manage-api-tokens"
          }
        }
      },
      "ApiTokenClaimRequest": {
        "title": "API token claim request",
        "description": "A single claim the new token should carry.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/McpClaimRequest"
          },
          {
            "$ref": "#/components/schemas/ManageApiTokensClaimRequest"
          }
        ],
        "discriminator": {
          "propertyName": "name",
          "mapping": {
            "mcp": "#/components/schemas/McpClaimRequest",
            "manage-api-tokens": "#/components/schemas/ManageApiTokensClaimRequest"
          }
        }
      },
      "ApiTokenClaim": {
        "title": "API token claim",
        "description": "A permission granted to an API token.",
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/ApiTokenClaimName"
          },
          "readonly": {
            "description": "Only meaningful on the `mcp` claim — the token may invoke read operations only.",
            "type": "boolean"
          },
          "attributes": {
            "description": "Claim-specific data. The `mcp` claim carries `serverGuid` and an optional `panelUser`.",
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "CreateApiTokenRequest": {
        "title": "Create API token request",
        "type": "object",
        "required": [
          "name",
          "claims"
        ],
        "properties": {
          "name": {
            "description": "Token name.",
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "claims": {
            "description": "Zero, one, or several claims. An empty array creates an unrestricted\ntoken. A claim name may appear at most once.\n",
            "type": "array",
            "maxItems": 2,
            "items": {
              "$ref": "#/components/schemas/ApiTokenClaimRequest"
            }
          }
        },
        "example": {
          "name": "My MCP token",
          "claims": [
            {
              "name": "mcp",
              "readonly": true,
              "attributes": {
                "serverGuid": "91dd39cb-69b8-4dfc-aef0-0ba335ba9581"
              }
            }
          ]
        }
      },
      "ApiToken": {
        "title": "API token",
        "type": "object",
        "required": [
          "id",
          "name",
          "type",
          "claims",
          "createdAt",
          "lastUsedAt",
          "expireAt"
        ],
        "properties": {
          "id": {
            "description": "Autogenerated token identifier.",
            "type": "integer",
            "example": 42
          },
          "name": {
            "description": "Token name.",
            "type": "string",
            "example": "My MCP token"
          },
          "type": {
            "description": "Token type.",
            "type": "string",
            "enum": [
              "user",
              "system"
            ]
          },
          "claims": {
            "description": "Claims the token carries. Empty for an unrestricted token.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiTokenClaim"
            }
          },
          "createdAt": {
            "description": "Token creation timestamp.",
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "description": "Token last usage timestamp. `null` if the token has never been used.",
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expireAt": {
            "description": "Token expiration timestamp. `null` if the token does not expire.",
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApiTokenWithSecret": {
        "title": "API token with secret",
        "description": "An API token together with its secret, returned only when the token is created.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiToken"
          },
          {
            "type": "object",
            "required": [
              "token"
            ],
            "properties": {
              "token": {
                "description": "The raw token. Returned only once, when the token is created.",
                "type": "string"
              }
            }
          }
        ]
      },
      "ApiTokenResponse": {
        "title": "API token response",
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ApiToken"
          }
        }
      },
      "ApiTokenWithSecretResponse": {
        "title": "API token with secret response",
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ApiTokenWithSecret"
          }
        }
      },
      "ApiTokenListResponse": {
        "title": "API token list response",
        "type": "object",
        "required": [
          "data",
          "totalCount"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiToken"
            }
          },
          "totalCount": {
            "description": "Total number of tokens matching the request, ignoring pagination.",
            "type": "integer",
            "example": 1
          }
        }
      },
      "ValidationError": {
        "title": "Validation error",
        "type": "object",
        "required": [
          "type",
          "errors"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "path",
                "message"
              ],
              "properties": {
                "type": {
                  "type": "string"
                },
                "path": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        },
        "example": {
          "type": "validation-error",
          "errors": [
            {
              "type": "isNotEmpty",
              "path": "someProperty",
              "message": "someProperty should not be empty"
            }
          ]
        }
      },
      "ForbiddenError": {
        "title": "Forbidden error",
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string"
          }
        },
        "example": {
          "type": "forbidden"
        }
      },
      "NotFoundError": {
        "title": "Not found error",
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string"
          }
        },
        "example": {
          "type": "not-found"
        }
      }
    }
  }
}