{
  "openapi": "3.1.0",
  "info": {
    "title": "RedSwitches API",
    "version": "1.0.0-beta (V4.5)",
    "summary": "Dedicated servers: read, order from credit, manage and power.",
    "description": "The RedSwitches API (release V4.5, private beta, invite-only) lets your own tools read your account, order instant\ndedicated servers paid from account credit, and manage them: rename, reverse DNS, saved SSH keys and power.\n\n**Authentication.** `Authorization: Bearer <key>`. Keys look like `rsw_live_` followed by 38 letters and digits and\nare created by the account owner in the portal under Settings → API. A key sent in a URL is refused and revoked.\nThe permission an operation needs is in `x-permission` and in its security requirement.\n\n**Methods.** GET (and HEAD, same headers, no body) on every read; POST with a JSON body (at most 4 KB,\n`Content-Type: application/json`) and DELETE on the write routes. GET, HEAD and DELETE must not carry a body.\n\n**Ids** are typed strings: `srv_`, `ord_`, `inv_`, `ofr_`, `sshkey_`, `act_` (in paths), and `acc_`, `key_`, `os_`\nin bodies. A path id with another prefix, a leading zero or any encoding is 404. Another account's item and a\nmissing one give the identical 404.\n\n**Lists** (`/servers`, `/orders`, `/invoices`) are newest first with cursor pagination: `limit` 1 to 100 (default\n50) and `cursor` = the `next_cursor` of the previous page. Any other query parameter is 400 `invalid_parameter`.\n\n**Writes** need an `Idempotency-Key` header (except an order dry run). See the docs on idempotency.\n\n**Times** are UTC ISO 8601 with `Z`; dates are `YYYY-MM-DD`. **Money** is a decimal string (`\"129.00\"`) except\nin ordering, which uses minor units (`{\"amount\":\"15609\",\"currency\":\"EUR\"}`).\n\nExtensions: `x-permission`, `x-layer` (the part of the API RedSwitches can switch off), `x-errors` (codes specific\nto the operation, beyond the common authentication and limit codes), `x-beta` (beta endpoints), `x-staff-switch` (off unless\nRedSwitches switches it on), and `x-since` / `x-since-values` (being built, not in the code yet; none at present).\n",
    "contact": {
      "name": "RedSwitches support",
      "url": "https://dedicated.redswitches.com/"
    }
  },
  "servers": [
    {
      "url": "https://api.redswitches.com/v1",
      "description": "Live"
    },
    {
      "url": "https://dedicated.redswitches.com/api/v1",
      "description": "Old address, deprecated: still answers during beta. Use https://api.redswitches.com/v1.",
      "x-deprecated": true
    }
  ],
  "externalDocs": {
    "description": "Documentation",
    "url": "https://api.redswitches.com/docs/"
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "Offers"
    },
    {
      "name": "Servers"
    },
    {
      "name": "Reverse DNS"
    },
    {
      "name": "Power and actions"
    },
    {
      "name": "Orders"
    },
    {
      "name": "Invoices"
    },
    {
      "name": "SSH keys"
    },
    {
      "name": "Cancellation"
    },
    {
      "name": "Reinstall and rescue"
    }
  ],
  "paths": {
    "/auth/verify": {
      "get": {
        "operationId": "auth-verify",
        "summary": "Check the key",
        "description": "The key this request was made with: label, hint, granted and effective permissions, expiry.",
        "tags": [
          "Account"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The key.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyInfo"
                },
                "example": {
                  "id": "key_5",
                  "label": "monitoring",
                  "hint": "a1B2",
                  "env": "live",
                  "permissions": [
                    "read",
                    "power"
                  ],
                  "effective_permissions": [
                    "read",
                    "power"
                  ],
                  "expires_at": "2027-02-13T09:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/account": {
      "get": {
        "operationId": "account-get",
        "summary": "Get the account",
        "description": "Id, status and currency. `credit` only for a key with read_billing.",
        "tags": [
          "Account"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The account.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "example": {
                  "id": "acc_100",
                  "status": "active",
                  "currency": "EUR",
                  "credit": "250.00"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/offers": {
      "get": {
        "operationId": "offers-list",
        "summary": "List instant servers on offer",
        "description": "Instant servers in stock for this account, with prices in the account's currency. Not paginated.",
        "tags": [
          "Offers"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Offers.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfferList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/offers/{id}": {
      "get": {
        "operationId": "offers-get",
        "summary": "Get one offer",
        "description": "One offer of the list, or 404 when it is not on offer now.",
        "tags": [
          "Offers"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OfferId"
          }
        ],
        "responses": {
          "200": {
            "description": "The offer.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Offer"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      }
    },
    "/servers": {
      "get": {
        "operationId": "servers-list",
        "summary": "List servers",
        "description": "The account's servers, newest first. Cancelled and terminated services are not listed.",
        "tags": [
          "Servers"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerCursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of servers.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/servers/{id}": {
      "get": {
        "operationId": "servers-get",
        "summary": "Get a server",
        "description": "The list fields plus IP addresses, OS, hardware and delivery state. Stored blocks carry their own as_of or are \"unavailable\". No request ever calls the server's network live.",
        "tags": [
          "Servers"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          }
        ],
        "responses": {
          "200": {
            "description": "The server.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerDetail"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      }
    },
    "/servers/{id}/traffic": {
      "get": {
        "operationId": "servers-traffic",
        "summary": "Get traffic",
        "description": "Data used in the current period and the allowance. used_bytes is \"unavailable\" (never zero) when no current figure is stored or the window reaches back before this account held the server.",
        "tags": [
          "Servers"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          }
        ],
        "responses": {
          "200": {
            "description": "Traffic.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Traffic"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      }
    },
    "/servers/{id}/label": {
      "post": {
        "operationId": "servers-label",
        "summary": "Rename a server",
        "description": "Sets the server's label (cosmetic; never a host name). \"\" clears it.",
        "tags": [
          "Servers"
        ],
        "x-permission": "manage",
        "x-layer": "manage",
        "security": [
          {
            "bearerAuth": [
              "manage"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LabelRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Renamed.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LabelResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found"
        ]
      }
    },
    "/servers/{id}/rdns": {
      "get": {
        "operationId": "rdns-list",
        "summary": "List reverse DNS requests",
        "description": "This server's open reverse DNS requests made by this account (pending or applied).",
        "tags": [
          "Reverse DNS"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          }
        ],
        "responses": {
          "200": {
            "description": "Requests.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RdnsList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      },
      "post": {
        "operationId": "rdns-set",
        "summary": "Request a reverse DNS change",
        "description": "Queues a PTR change for an IP of this server. The IP must be on the server's stored IP list. At most one open request per IP and 20 per server per day. Applied shortly afterwards, not in the request. On servers where it is carried out as an action, and always for hostname \"\" (clear the PTR), the answer is RdnsQueued with an action id to poll; another hostname for an IP with an open action is 409 server_busy.",
        "tags": [
          "Reverse DNS"
        ],
        "x-permission": "manage",
        "x-layer": "manage",
        "security": [
          {
            "bearerAuth": [
              "manage"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RdnsRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted: an rDNS request applied by the scheduled job (RdnsAccepted), or an action to poll (RdnsQueued, with an act_ id).",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RdnsAccepted"
                    },
                    {
                      "$ref": "#/components/schemas/RdnsQueued"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "not_supported",
          "server_not_active",
          "server_busy",
          "ip_not_on_server",
          "action_limit"
        ]
      }
    },
    "/servers/{id}/power": {
      "post": {
        "operationId": "servers-power",
        "summary": "Power on, off or reboot",
        "description": "Records a power action and returns at once (202). Poll GET /actions/{id}. The key's server list must cover the server. One action per server at a time; ceilings per server and per account per rolling hour; a burst of power-offs pauses API power for the account.",
        "tags": [
          "Power and actions"
        ],
        "x-permission": "power",
        "x-layer": "power",
        "security": [
          {
            "bearerAuth": [
              "power"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PowerRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "permission_denied",
          "power_paused",
          "server_busy",
          "server_not_active",
          "not_supported",
          "action_limit"
        ]
      }
    },
    "/actions/{id}": {
      "get": {
        "operationId": "actions-get",
        "summary": "Get an action",
        "description": "An action of this account (made with any of its keys).",
        "tags": [
          "Power and actions"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ActionId"
          }
        ],
        "responses": {
          "200": {
            "description": "The action.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Action"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      }
    },
    "/orders": {
      "get": {
        "operationId": "orders-list",
        "summary": "List orders",
        "description": "The account's orders, newest first.",
        "tags": [
          "Orders"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderCursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of orders.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      },
      "post": {
        "operationId": "orders-create",
        "summary": "Order an instant server",
        "description": "Orders one instant server, paid from account credit. Run it first with `?dry_run=true` (no Idempotency-Key needed) and send the returned total as expected_total. Then poll GET /orders/{id} until every service is `ready`.",
        "tags": [
          "Orders"
        ],
        "x-permission": "order",
        "x-layer": "order",
        "security": [
          {
            "bearerAuth": [
              "order"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DryRun"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyOrder"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ordered and paid from credit; delivery queued.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCreated"
                }
              }
            }
          },
          "200": {
            "description": "Dry run: what the order would cost. Nothing created.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderDryRun"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "insufficient_credit",
          "ordering_not_enabled",
          "not_eligible",
          "cooling_off",
          "cap_reached",
          "ordering_paused",
          "price_changed",
          "sold_out",
          "order_not_placed",
          "order_under_review",
          "not_orderable"
        ],
        "x-query-post": {
          "dry_run": "true"
        },
        "x-idempotency": "Required unless dry_run=true."
      }
    },
    "/orders/{id}": {
      "get": {
        "operationId": "orders-get",
        "summary": "Get an order",
        "description": "An order with each service's delivery state and poll_after.",
        "tags": [
          "Orders"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderId"
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ]
      }
    },
    "/invoices": {
      "get": {
        "operationId": "invoices-list",
        "summary": "List invoices",
        "description": "The account's invoices, newest first (drafts hidden). Needs read_billing.",
        "tags": [
          "Invoices"
        ],
        "x-permission": "read_billing",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read_billing"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceCursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of invoices.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicePage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "permission_denied"
        ]
      }
    },
    "/invoices/{id}": {
      "get": {
        "operationId": "invoices-get",
        "summary": "Get an invoice",
        "description": "One invoice with its line items. Needs read_billing.",
        "tags": [
          "Invoices"
        ],
        "x-permission": "read_billing",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read_billing"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "responses": {
          "200": {
            "description": "The invoice.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDetail"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "permission_denied",
          "not_found"
        ]
      }
    },
    "/ssh-keys": {
      "get": {
        "operationId": "ssh-keys-list",
        "summary": "List saved SSH keys",
        "description": "The account's saved SSH keys.",
        "tags": [
          "SSH keys"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Keys.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Cache": {
                "$ref": "#/components/headers/X-Cache"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshKeyList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      },
      "post": {
        "operationId": "ssh-keys-create",
        "summary": "Save an SSH key",
        "description": "Saves a public key on the account. The owner is emailed. At most 20 key changes per account per day.",
        "tags": [
          "SSH keys"
        ],
        "x-permission": "ssh_keys",
        "x-layer": "manage",
        "security": [
          {
            "bearerAuth": [
              "ssh_keys"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SshKeyCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshKey"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "invalid_ssh_key",
          "ssh_key_conflict",
          "action_limit"
        ]
      }
    },
    "/ssh-keys/{id}": {
      "delete": {
        "operationId": "ssh-keys-delete",
        "summary": "Remove a saved SSH key",
        "description": "Removes a saved key from the account. Servers where it is already installed are not touched. The owner is emailed.",
        "tags": [
          "SSH keys"
        ],
        "x-permission": "ssh_keys",
        "x-layer": "manage",
        "security": [
          {
            "bearerAuth": [
              "ssh_keys"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SshKeyId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Removed.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshKeyDeleted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "action_limit"
        ]
      }
    },
    "/servers/{id}/cancel-request": {
      "get": {
        "operationId": "cancel-get",
        "summary": "Get the cancellation request",
        "description": "Beta. The server's cancellation state: none, requested (with dates) or withdrawal_requested.",
        "tags": [
          "Cancellation"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          }
        ],
        "responses": {
          "200": {
            "description": "State.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancellationState"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ],
        "x-beta": true
      },
      "post": {
        "operationId": "cancel-request",
        "summary": "Request cancellation",
        "description": "Beta. Files a cancellation at the end of the billing period (the server keeps running until then) for an active or suspended server. The owner is emailed. When a request already exists it is returned (200). Covered by the key's server list. At most 2 per account per day. 409 server_busy while a request to keep the server is less than a day old.",
        "tags": [
          "Cancellation"
        ],
        "x-permission": "cancel",
        "x-layer": "cancel",
        "security": [
          {
            "bearerAuth": [
              "cancel"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelRequestBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Requested.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancellationState"
                }
              }
            }
          },
          "200": {
            "description": "A request already existed.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancellationState"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "permission_denied",
          "server_not_active",
          "server_busy",
          "action_limit"
        ],
        "x-beta": true
      },
      "delete": {
        "operationId": "cancel-withdraw",
        "summary": "Ask to withdraw the cancellation",
        "description": "Beta. Asks RedSwitches staff to withdraw the cancellation (filed once; repeating it changes nothing). Nothing is un-cancelled automatically. 404 when there is no cancellation request.",
        "tags": [
          "Cancellation"
        ],
        "x-permission": "cancel",
        "x-layer": "cancel",
        "security": [
          {
            "bearerAuth": [
              "cancel"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Withdrawal requested.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancellationState"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "permission_denied"
        ],
        "x-beta": true
      }
    },
    "/servers/{id}/rescue": {
      "post": {
        "operationId": "servers-rescue",
        "summary": "Boot into rescue mode",
        "description": "Beta. Off unless RedSwitches switches rescue on. Records a rescue action (202) that boots the server into rescue mode, as the portal's Rescue tab does. With return_password true the rescue login can be read once from GET /actions/{id}/credentials after the action is done. Leave rescue with POST /servers/{id}/power {\"action\":\"reboot\"}. Covered by the key's server list. At most 4 per server per day. 503 unavailable while RedSwitches has reinstalls and rescues paused.",
        "tags": [
          "Reinstall and rescue"
        ],
        "x-permission": "rescue",
        "x-layer": "rescue",
        "security": [
          {
            "bearerAuth": [
              "rescue"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RescueRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RescueAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "permission_denied",
          "server_busy",
          "server_not_active",
          "not_supported",
          "action_limit",
          "unavailable"
        ],
        "x-beta": true,
        "x-staff-switch": "layer_rescue"
      }
    },
    "/actions/{id}/credentials": {
      "get": {
        "operationId": "actions-credentials",
        "summary": "Read an action's credentials once",
        "description": "Beta. The password (or rescue login) of a reinstall or rescue action that was made with return_password true. Needs read; only the key that started the action, after the action is done. The first read returns it and wipes it; unread credentials are wiped after 24 hours. Every read is audited and the owner is emailed. Afterwards, before the action is done, for another key, for an action without return_password, or when the password could not be kept (action reason password_unavailable): 404 not_found. While a switch is off (platform, layer, pause) the answer is 503 unavailable and the password is kept for a later read. HEAD is refused (405) so that nothing can consume the password without reading it. Do not retry this request after a network error or a 5xx answer: the lost answer may already have used the one read (retrying after 429 rate_limited is safe).",
        "tags": [
          "Power and actions"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ActionId"
          }
        ],
        "responses": {
          "200": {
            "description": "The credentials, this one time.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credentials"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found",
          "permission_denied",
          "unavailable"
        ],
        "x-beta": true
      }
    },
    "/servers/{id}/os": {
      "get": {
        "operationId": "servers-os",
        "summary": "List OS images for reinstall",
        "description": "Beta. The OS images the portal offers for this server, from a stored list.",
        "tags": [
          "Reinstall and rescue"
        ],
        "x-permission": "read",
        "x-layer": "read",
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          }
        ],
        "responses": {
          "200": {
            "description": "Images.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsImageList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "not_found"
        ],
        "x-beta": true
      }
    },
    "/servers/{id}/reinstall": {
      "post": {
        "operationId": "servers-reinstall",
        "summary": "Reinstall a server",
        "description": "Beta. Off unless RedSwitches switches reinstall on. Records a reinstall action (202) with the chosen saved SSH keys. No password is returned unless return_password is true (then readable once from GET /actions/{id}/credentials); otherwise, if one is set, it is emailed to the owner as in the portal. Covered by the key's server list. At most 2 per server and 5 per account per day. 503 unavailable while RedSwitches has reinstalls paused.",
        "tags": [
          "Reinstall and rescue"
        ],
        "x-permission": "reinstall",
        "x-layer": "reinstall",
        "security": [
          {
            "bearerAuth": [
              "reinstall"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ServerId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReinstallRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Content-Type": {
                "$ref": "#/components/headers/Content-Type"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/Cache-Control"
              },
              "X-Content-Type-Options": {
                "$ref": "#/components/headers/X-Content-Type-Options"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReinstallAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "x-errors": [
          "invalid_body",
          "idempotency_key_required",
          "idempotency_conflict",
          "in_progress",
          "not_found",
          "permission_denied",
          "server_busy",
          "server_not_active",
          "not_supported",
          "invalid_ssh_key",
          "action_limit",
          "unavailable"
        ],
        "x-beta": true,
        "x-staff-switch": "layer_reinstall"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rsw_live_ + 38 base62 characters",
        "description": "Scopes in a security requirement name the key permission the operation needs."
      }
    },
    "parameters": {
      "ServerId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`srv_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^srv_[1-9][0-9]{0,9}$",
          "examples": [
            "srv_123"
          ]
        }
      },
      "OrderId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`ord_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^ord_[1-9][0-9]{0,9}$",
          "examples": [
            "ord_123"
          ]
        }
      },
      "InvoiceId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`inv_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^inv_[1-9][0-9]{0,9}$",
          "examples": [
            "inv_123"
          ]
        }
      },
      "OfferId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`ofr_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^ofr_[1-9][0-9]{0,9}$",
          "examples": [
            "ofr_123"
          ]
        }
      },
      "SshKeyId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`sshkey_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^sshkey_[1-9][0-9]{0,9}$",
          "examples": [
            "sshkey_123"
          ]
        }
      },
      "ActionId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A typed id (`act_<number>`). Another prefix, a leading zero or anything encoded is 404.",
        "schema": {
          "type": "string",
          "pattern": "^act_[1-9][0-9]{0,9}$",
          "examples": [
            "act_123"
          ]
        }
      },
      "ServerCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "next_cursor of the previous page.",
        "schema": {
          "type": "string",
          "pattern": "^srv_[1-9][0-9]{0,9}$",
          "examples": [
            "srv_123"
          ]
        }
      },
      "OrderCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "next_cursor of the previous page.",
        "schema": {
          "type": "string",
          "pattern": "^ord_[1-9][0-9]{0,9}$",
          "examples": [
            "ord_123"
          ]
        }
      },
      "InvoiceCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "next_cursor of the previous page.",
        "schema": {
          "type": "string",
          "pattern": "^inv_[1-9][0-9]{0,9}$",
          "examples": [
            "inv_123"
          ]
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Items per page, 1 to 100 (default 50).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "DryRun": {
        "name": "dry_run",
        "in": "query",
        "required": false,
        "description": "`true` only: check and price the order; nothing is created or reserved. No Idempotency-Key needed.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "8 to 64 letters, digits, dashes or underscores. One per intended action; reuse it only to retry the same request.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{8,64}$"
        }
      },
      "IdempotencyKeyOrder": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Required for a real order (8 to 64 letters, digits, dashes or underscores); not needed with dry_run=true.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{8,64}$"
        }
      }
    },
    "headers": {
      "X-Request-Id": {
        "description": "The request's id (26 characters, Crockford base32, sortable by time). Quote it to support.",
        "schema": {
          "type": "string",
          "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
        }
      },
      "Content-Type": {
        "description": "Always `application/json`.",
        "schema": {
          "type": "string",
          "const": "application/json"
        }
      },
      "Cache-Control": {
        "description": "Always `no-store, private`.",
        "schema": {
          "type": "string",
          "const": "no-store, private"
        }
      },
      "X-Content-Type-Options": {
        "description": "Always `nosniff`.",
        "schema": {
          "type": "string",
          "const": "nosniff"
        }
      },
      "X-RateLimit-Limit": {
        "description": "Requests allowed in the current window (the tighter of the key's and the account's limits). Successful answers only.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Requests left in the current window. Successful answers only.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "Unix time (seconds) at which the current window ends. Successful answers only.",
        "schema": {
          "type": "integer"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before trying again: on 429 rate_limited, and on any error whose details carry retry_after (in_progress, cooling_off).",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "WWW-Authenticate": {
        "description": "`Bearer` on every 401.",
        "schema": {
          "type": "string",
          "const": "Bearer"
        }
      },
      "Allow": {
        "description": "The methods the path accepts (405).",
        "schema": {
          "type": "string"
        }
      },
      "X-Cache": {
        "description": "On the cacheable reads (account, offers, servers, server, traffic, orders, order, invoices, invoice, ssh-keys): `hit` when the answer came from the short-lived read cache (at most about a minute old), `miss` otherwise. The body is identical either way.",
        "schema": {
          "type": "string",
          "enum": [
            "hit",
            "miss"
          ]
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Error. Codes: `body_not_allowed`, `key_in_url`, `invalid_parameter`, `invalid_body`, `idempotency_key_required`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Error. Codes: `invalid_key`, `key_revoked`, `key_expired`, `test_key`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          },
          "WWW-Authenticate": {
            "$ref": "#/components/headers/WWW-Authenticate"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Error. Codes: `insufficient_credit`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Error. Codes: `ordering_not_enabled`, `not_eligible`, `cooling_off`, `cap_reached`, `ordering_paused`, `power_paused`, `api_not_enabled`, `account_blocked`, `not_invited`, `ip_not_allowed`, `account_inactive`, `owner_changed`, `email_not_verified`, `permission_denied`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Error. Codes: `not_found`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Error. Codes: `method_not_allowed`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          },
          "Allow": {
            "$ref": "#/components/headers/Allow"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "Error. Codes: `body_too_large`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Error. Codes: `in_progress`, `price_changed`, `sold_out`, `order_not_placed`, `order_under_review`, `server_busy`, `server_not_active`, `ssh_key_conflict`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unprocessable": {
        "description": "Error. Codes: `not_supported`, `ip_not_on_server`, `invalid_ssh_key`, `idempotency_conflict`, `not_orderable`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Error. Codes: `action_limit`, `rate_limited`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InternalError": {
        "description": "Error. Codes: `internal_error`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unavailable": {
        "description": "Error. Codes: `unavailable`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "Content-Type": {
            "$ref": "#/components/headers/Content-Type"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/Cache-Control"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/X-Content-Type-Options"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Money": {
        "type": "string",
        "pattern": "^-?[0-9]{1,13}\\.[0-9]{2}$",
        "description": "A decimal amount in major units, as a string (never a float). Example `\"129.00\"`.",
        "examples": [
          "129.00"
        ]
      },
      "MinorAmount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount",
          "currency"
        ],
        "description": "An amount in MINOR units (cents) as a string of digits, and its currency. Used by ordering: `{\"amount\":\"15609\",\"currency\":\"EUR\"}` is 156.09 EUR.",
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]{0,11})$",
            "examples": [
              "15609"
            ]
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        }
      },
      "Currency": {
        "type": "string",
        "pattern": "^[A-Z]{3}$",
        "description": "ISO 4217 code of the account's currency.",
        "examples": [
          "EUR"
        ]
      },
      "Unavailable": {
        "type": "string",
        "const": "unavailable",
        "description": "Nothing current is stored for this block. Never an empty list and never zero."
      },
      "Location": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "city",
          "country"
        ],
        "properties": {
          "city": {
            "type": "string",
            "maxLength": 60
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$",
            "description": "ISO 3166-1 alpha-2, or null when unknown."
          }
        }
      },
      "Permission": {
        "type": "string",
        "enum": [
          "read",
          "read_billing",
          "order",
          "manage",
          "ssh_keys",
          "power",
          "cancel",
          "reinstall",
          "rescue"
        ],
        "description": "read: servers, traffic, orders, offers, SSH keys, actions, rDNS requests. read_billing: also invoices and the credit balance. order: place orders paid from credit (needs a monthly spend cap). manage: rename, rDNS. ssh_keys: add and remove saved SSH keys. power: on, off, reboot (limited to the key's server list). cancel, reinstall and rescue (beta): cancellation requests, reinstalls and rescue boots (limited to the key's server list; reinstall and rescue only while RedSwitches has them switched on). Every permission except read needs read beside it."
      },
      "KeyInfo": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label",
          "hint",
          "env",
          "permissions",
          "effective_permissions",
          "expires_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^key_[1-9][0-9]{0,9}$",
            "examples": [
              "key_123"
            ]
          },
          "label": {
            "type": "string",
            "maxLength": 40
          },
          "hint": {
            "type": "string",
            "description": "The key's last four characters."
          },
          "env": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ]
          },
          "permissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Permission"
            },
            "description": "Permissions granted to the key."
          },
          "effective_permissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Permission"
            },
            "description": "Granted permissions that work right now (a permission does not work while RedSwitches has its part of the API switched off)."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          }
        }
      },
      "Account": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "currency"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^acc_[1-9][0-9]{0,9}$",
            "examples": [
              "acc_123"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "closed"
            ]
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "credit": {
            "$ref": "#/components/schemas/Money",
            "description": "Credit balance. Present only for a key with read_billing."
          }
        }
      },
      "OfferPrice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "cycle",
          "price",
          "setup"
        ],
        "properties": {
          "cycle": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "semiannually",
              "annually",
              "biennially",
              "triennially"
            ]
          },
          "price": {
            "$ref": "#/components/schemas/Money",
            "description": "Recurring price per cycle, excluding tax, for the default configuration."
          },
          "setup": {
            "$ref": "#/components/schemas/Money",
            "description": "One-time setup fee of that cycle."
          }
        }
      },
      "OsChoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^os_[1-9][0-9]{0,9}$",
            "examples": [
              "os_123"
            ]
          },
          "name": {
            "type": "string",
            "maxLength": 120
          }
        }
      },
      "Offer": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "location",
          "cpu",
          "ram",
          "disks",
          "port_speed",
          "traffic",
          "currency",
          "prices",
          "os",
          "stock",
          "as_of"
        ],
        "description": "An instant server on offer. Prices are per billing cycle, excluding tax, in the account's currency, for the default configuration. Use a dry-run order for the exact total.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^ofr_[1-9][0-9]{0,9}$",
            "examples": [
              "ofr_123"
            ]
          },
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "location": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Location"
              },
              {
                "type": "null"
              }
            ]
          },
          "cpu": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 160
          },
          "ram": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 80
          },
          "disks": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 160
          },
          "port_speed": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 80
          },
          "traffic": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 80
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "prices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OfferPrice"
            }
          },
          "os": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OsChoice"
            },
            "description": "The OS choices for an order (os_id)."
          },
          "stock": {
            "oneOf": [
              {
                "type": "integer",
                "minimum": 0,
                "maximum": 4
              },
              {
                "type": "string",
                "const": "5+"
              }
            ],
            "description": "Units in stock, 0 to 4, or \"5+\"."
          },
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "When this list was read (lists are cached for about 30 seconds)."
          }
        }
      },
      "OfferList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Offer"
            }
          }
        }
      },
      "Server": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label",
          "product",
          "location",
          "status",
          "primary_ip",
          "billing_cycle",
          "next_due_date",
          "recurring_amount",
          "currency",
          "created"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60
          },
          "product": {
            "type": "string",
            "maxLength": 120
          },
          "location": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Location"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "suspended"
            ]
          },
          "primary_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "IPv4 or IPv6 address, without a prefix length."
          },
          "billing_cycle": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "monthly",
              "quarterly",
              "semiannually",
              "annually",
              "biennially",
              "triennially",
              "one_time",
              "free",
              null
            ]
          },
          "next_due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "recurring_amount": {
            "$ref": "#/components/schemas/Money"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "created": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          }
        },
        "description": "A server of the account (cancelled and terminated services are not listed)."
      },
      "DeliveryState": {
        "type": "string",
        "enum": [
          "awaiting_payment",
          "assigning",
          "installing",
          "ready",
          "attention",
          "closed"
        ],
        "description": "Instant-deploy delivery state: awaiting_payment, assigning (a machine is being assigned), installing, ready, attention (needs a look by RedSwitches), closed (cancelled, refunded, ended or suspended)."
      },
      "IpBlock": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "as_of",
          "addresses"
        ],
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "addresses": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "ip",
                "primary"
              ],
              "properties": {
                "ip": {
                  "type": "string"
                },
                "primary": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "InstalledOs": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "as_of",
          "name",
          "installing"
        ],
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "installing": {
            "type": "boolean"
          }
        }
      },
      "Hardware": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "as_of",
          "cpu",
          "ram",
          "disks"
        ],
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "cpu": {
            "type": [
              "string",
              "null"
            ]
          },
          "ram": {
            "type": [
              "string",
              "null"
            ]
          },
          "disks": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ServerDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label",
          "product",
          "location",
          "status",
          "primary_ip",
          "billing_cycle",
          "next_due_date",
          "recurring_amount",
          "currency",
          "created",
          "ips",
          "os",
          "hardware",
          "delivery",
          "rescue"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60
          },
          "product": {
            "type": "string",
            "maxLength": 120
          },
          "location": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Location"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "suspended"
            ]
          },
          "primary_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "IPv4 or IPv6 address, without a prefix length."
          },
          "billing_cycle": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "monthly",
              "quarterly",
              "semiannually",
              "annually",
              "biennially",
              "triennially",
              "one_time",
              "free",
              null
            ]
          },
          "next_due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "recurring_amount": {
            "$ref": "#/components/schemas/Money"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "created": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "ips": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/IpBlock"
              },
              {
                "$ref": "#/components/schemas/Unavailable"
              }
            ]
          },
          "os": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "ordered",
              "installed"
            ],
            "properties": {
              "ordered": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The OS chosen on the order."
              },
              "installed": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/InstalledOs"
                  },
                  {
                    "$ref": "#/components/schemas/Unavailable"
                  }
                ],
                "description": "What the server last reported."
              }
            }
          },
          "hardware": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Hardware"
              },
              {
                "$ref": "#/components/schemas/Unavailable"
              }
            ]
          },
          "delivery": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DeliveryState"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a server that is not an instant deploy."
          },
          "rescue": {
            "type": "boolean",
            "description": "True while the server is booted into rescue mode (from stored state; false when not known). Leave rescue with a power reboot."
          }
        },
        "description": "One server: the list fields plus stored facts. Each stored block has its own as_of, or is the string \"unavailable\"."
      },
      "Traffic": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "used_bytes",
          "unavailable_reason",
          "period_start",
          "period_end",
          "basis",
          "as_of",
          "allowance_bytes",
          "unmetered"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "used_bytes": {
            "oneOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "$ref": "#/components/schemas/Unavailable"
              }
            ]
          },
          "unavailable_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "not_collected",
              "ownership_changed_in_window",
              null
            ],
            "description": "Why used_bytes is unavailable: nothing current is stored, or the measured window starts before this account held the server. Null when used_bytes is a number."
          },
          "period_start": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "period_end": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "basis": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "billing_period",
              "last_30_days",
              "since_ownership",
              null
            ],
            "description": "billing_period: the account's billing month. last_30_days: the network's rolling 30-day total. since_ownership: counted from when this account started holding the server."
          },
          "as_of": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "allowance_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null when unmetered or unknown."
          },
          "unmetered": {
            "type": "boolean"
          }
        }
      },
      "Order": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "date",
          "status",
          "payment",
          "invoice",
          "services",
          "poll_after"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^ord_[1-9][0-9]{0,9}$",
            "examples": [
              "ord_123"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "cancelled",
              "on_hold",
              "other"
            ]
          },
          "payment": {
            "type": "string",
            "enum": [
              "paid",
              "free",
              "unpaid",
              "partially_paid",
              "pending",
              "cancelled",
              "refunded",
              "collections",
              "unknown"
            ]
          },
          "invoice": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^inv_[1-9][0-9]{0,9}$"
          },
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "delivery"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^srv_[1-9][0-9]{0,9}$",
                  "examples": [
                    "srv_123"
                  ]
                },
                "delivery": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/DeliveryState"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Null for a service that is not an instant deploy."
                }
              }
            }
          },
          "poll_after": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 2,
            "description": "Seconds until it is worth asking again; null when nothing is still being delivered."
          }
        }
      },
      "ServerPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Server"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "description": "Pass as cursor for the next page; null on the last page."
          }
        }
      },
      "OrderPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Order"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^ord_[1-9][0-9]{0,9}$",
            "description": "Pass as cursor for the next page; null on the last page."
          }
        }
      },
      "InvoicePage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^inv_[1-9][0-9]{0,9}$",
            "description": "Pass as cursor for the next page; null on the last page."
          }
        }
      },
      "Invoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "number",
          "status",
          "date",
          "due_date",
          "paid_at",
          "currency",
          "subtotal",
          "tax",
          "total",
          "credit",
          "balance"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^inv_[1-9][0-9]{0,9}$",
            "examples": [
              "inv_123"
            ]
          },
          "number": {
            "type": "string",
            "maxLength": 40
          },
          "status": {
            "type": "string",
            "enum": [
              "paid",
              "unpaid",
              "cancelled",
              "refunded",
              "collections",
              "payment_pending",
              "other"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "tax": {
            "$ref": "#/components/schemas/Money"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "credit": {
            "$ref": "#/components/schemas/Money",
            "description": "Credit applied."
          },
          "balance": {
            "$ref": "#/components/schemas/Money",
            "description": "Still due."
          }
        },
        "description": "Draft invoices are never shown."
      },
      "InvoiceItem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "description",
          "amount",
          "taxed",
          "service"
        ],
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "amount": {
            "$ref": "#/components/schemas/Money"
          },
          "taxed": {
            "type": "boolean"
          },
          "service": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^srv_[1-9][0-9]{0,9}$"
          }
        }
      },
      "InvoiceDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "number",
          "status",
          "date",
          "due_date",
          "paid_at",
          "currency",
          "subtotal",
          "tax",
          "total",
          "credit",
          "balance",
          "items"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^inv_[1-9][0-9]{0,9}$",
            "examples": [
              "inv_123"
            ]
          },
          "number": {
            "type": "string",
            "maxLength": 40
          },
          "status": {
            "type": "string",
            "enum": [
              "paid",
              "unpaid",
              "cancelled",
              "refunded",
              "collections",
              "payment_pending",
              "other"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "tax": {
            "$ref": "#/components/schemas/Money"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "credit": {
            "$ref": "#/components/schemas/Money",
            "description": "Credit applied."
          },
          "balance": {
            "$ref": "#/components/schemas/Money",
            "description": "Still due."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceItem"
            }
          }
        }
      },
      "SshKey": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "type",
          "fingerprint",
          "added"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^sshkey_[1-9][0-9]{0,9}$",
            "examples": [
              "sshkey_123"
            ]
          },
          "name": {
            "type": "string",
            "maxLength": 64
          },
          "type": {
            "type": "string",
            "maxLength": 16,
            "examples": [
              "ssh-ed25519"
            ]
          },
          "fingerprint": {
            "type": [
              "string",
              "null"
            ]
          },
          "added": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          }
        }
      },
      "SshKeyList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SshKey"
            }
          }
        }
      },
      "SshKeyCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "public_key"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional. Up to 64 characters; no control characters, < or >."
          },
          "public_key": {
            "type": "string",
            "maxLength": 16384,
            "description": "One line, as in id_ed25519.pub."
          }
        }
      },
      "SshKeyDeleted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "deleted",
          "installed_servers_unchanged"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^sshkey_[1-9][0-9]{0,9}$",
            "examples": [
              "sshkey_123"
            ]
          },
          "deleted": {
            "type": "boolean",
            "const": true
          },
          "installed_servers_unchanged": {
            "type": "boolean",
            "const": true,
            "description": "Removing a saved key does not touch servers where it is already installed."
          }
        }
      },
      "LabelRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 60,
            "pattern": "^[\\p{L}\\p{N} ._\\-]{0,60}$",
            "description": "Letters, digits, spaces, dots, dashes, underscores; at most 60. White space is collapsed. \"\" clears the label. Control characters are refused."
          }
        }
      },
      "LabelResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "RdnsRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ip",
          "hostname"
        ],
        "properties": {
          "ip": {
            "type": "string",
            "description": "An IPv4 or IPv6 address assigned to this server."
          },
          "hostname": {
            "type": "string",
            "maxLength": 253,
            "description": "A full host name (lower-cased, trailing dot removed), or \"\" to clear the PTR record."
          }
        }
      },
      "RdnsAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "server_id",
          "ip",
          "hostname",
          "state",
          "already_requested"
        ],
        "properties": {
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "ip": {
            "type": "string"
          },
          "hostname": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "const": "pending"
          },
          "already_requested": {
            "type": "boolean",
            "description": "True when the same change was already waiting."
          }
        }
      },
      "RdnsList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "server_id",
          "data"
        ],
        "description": "The requests applied by the scheduled job come first (oldest first), then up to 20 changes carried out as actions (newest first). To find the newest entry for an IP, sort by requested.",
        "properties": {
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "ip",
                "hostname",
                "state",
                "requested",
                "action_id"
              ],
              "properties": {
                "ip": {
                  "type": "string"
                },
                "hostname": {
                  "type": "string"
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "applied",
                    "queued",
                    "running",
                    "done",
                    "failed",
                    "unknown"
                  ],
                  "description": "pending or applied; a change carried out as an action shows that action's state."
                },
                "requested": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "UTC, ISO 8601, always with Z."
                },
                "action_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "pattern": "^act_[1-9][0-9]{0,9}$",
                  "description": "The action carrying the change out, or null for a request applied by the scheduled job."
                }
              }
            }
          }
        }
      },
      "PowerRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "on",
              "off",
              "reboot"
            ]
          }
        }
      },
      "ActionAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "server_id",
          "action",
          "state",
          "poll_after"
        ],
        "description": "An action was recorded and will run shortly. Poll GET /actions/{id}.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "kind": {
            "type": "string",
            "const": "power"
          },
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "action": {
            "type": "string",
            "enum": [
              "on",
              "off",
              "reboot"
            ]
          },
          "state": {
            "type": "string",
            "const": "queued"
          },
          "poll_after": {
            "type": "integer",
            "examples": [
              10
            ]
          }
        }
      },
      "Action": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "server_id",
          "action",
          "state",
          "reason",
          "created",
          "started",
          "finished"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "kind": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "label",
              "rdns",
              "ssh_key_add",
              "ssh_key_remove",
              "power",
              "cancel_request",
              "cancel_withdrawal",
              "reinstall",
              "rescue",
              null
            ]
          },
          "server_id": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^srv_[1-9][0-9]{0,9}$"
          },
          "action": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "on",
              "off",
              "reboot",
              null
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "done",
              "failed",
              "unknown"
            ],
            "description": "unknown: the outcome could not be confirmed. No further API power action runs on that server until RedSwitches settles it."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "expired",
              "server_busy",
              "server_not_active",
              "server_changed",
              "power_paused",
              "not_supported",
              "provider_refused",
              "no_answer",
              "provider_unavailable",
              "settled_by_staff",
              "key_no_longer_allowed",
              "ip_not_on_server",
              "paused",
              "not_tracked",
              "password_unavailable",
              null
            ],
            "description": "For failed and unknown actions. A done action has none, except password_unavailable (a reinstall or rescue started, but the password asked for could not be kept) and not_tracked. Null otherwise or when there is no public word for it."
          },
          "created": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "started": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "finished": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          }
        }
      },
      "OrderCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "offer_id",
          "billing_cycle",
          "os_id"
        ],
        "description": "Exactly these fields; anything else is 400 invalid_body. Nothing from the body is echoed back.",
        "properties": {
          "offer_id": {
            "type": "string",
            "pattern": "^ofr_[1-9][0-9]{0,9}$",
            "examples": [
              "ofr_123"
            ]
          },
          "billing_cycle": {
            "type": "string",
            "enum": [
              "monthly"
            ],
            "description": "Only monthly in this release."
          },
          "os_id": {
            "type": "string",
            "pattern": "^os_[1-9][0-9]{0,9}$",
            "examples": [
              "os_123"
            ],
            "description": "One of the offer's os choices."
          },
          "ssh_key_id": {
            "type": "string",
            "pattern": "^sshkey_[1-9][0-9]{0,9}$",
            "examples": [
              "sshkey_123"
            ],
            "description": "Optional: a key saved on the account."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "pattern": "^[\\p{L}\\p{N} ._\\-]{1,60}$"
          },
          "expected_total": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "The total you expect to pay now, from a dry run. Required unless dry_run=true."
          }
        }
      },
      "OrderCreated": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "invoice_id",
          "server_ids",
          "status",
          "delivery",
          "billing_cycle",
          "total",
          "recurring",
          "paid_from_credit",
          "poll_after"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^ord_[1-9][0-9]{0,9}$",
            "examples": [
              "ord_123"
            ]
          },
          "invoice_id": {
            "type": "string",
            "pattern": "^inv_[1-9][0-9]{0,9}$",
            "examples": [
              "inv_123"
            ]
          },
          "server_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^srv_[1-9][0-9]{0,9}$",
              "examples": [
                "srv_123"
              ]
            }
          },
          "status": {
            "type": "string",
            "const": "paid"
          },
          "delivery": {
            "type": "string",
            "const": "queued"
          },
          "billing_cycle": {
            "type": "string",
            "enum": [
              "monthly"
            ]
          },
          "total": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "Paid now, tax included, minor units."
          },
          "recurring": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "Each following cycle, before tax, minor units."
          },
          "paid_from_credit": {
            "$ref": "#/components/schemas/MinorAmount"
          },
          "poll_after": {
            "type": "integer",
            "const": 30
          }
        }
      },
      "OrderDryRun": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "dry_run",
          "offer_id",
          "billing_cycle",
          "total",
          "recurring",
          "paid_from_credit"
        ],
        "properties": {
          "dry_run": {
            "type": "boolean",
            "const": true
          },
          "offer_id": {
            "type": "string",
            "pattern": "^ofr_[1-9][0-9]{0,9}$",
            "examples": [
              "ofr_123"
            ]
          },
          "billing_cycle": {
            "type": "string",
            "enum": [
              "monthly"
            ]
          },
          "total": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "The first payment (setup and tax included). Send this as expected_total."
          },
          "recurring": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "Each following cycle, before tax."
          },
          "paid_from_credit": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "What would be paid from credit (the same shape as the 201 answer)."
          }
        }
      },
      "ErrorCode": {
        "type": "string",
        "enum": [
          "body_not_allowed",
          "key_in_url",
          "invalid_parameter",
          "invalid_body",
          "body_too_large",
          "idempotency_key_required",
          "insufficient_credit",
          "ordering_not_enabled",
          "not_eligible",
          "cooling_off",
          "cap_reached",
          "ordering_paused",
          "power_paused",
          "in_progress",
          "price_changed",
          "sold_out",
          "order_not_placed",
          "order_under_review",
          "server_busy",
          "server_not_active",
          "ssh_key_conflict",
          "not_supported",
          "ip_not_on_server",
          "invalid_ssh_key",
          "idempotency_conflict",
          "not_orderable",
          "invalid_key",
          "key_revoked",
          "key_expired",
          "test_key",
          "api_not_enabled",
          "account_blocked",
          "not_invited",
          "ip_not_allowed",
          "account_inactive",
          "owner_changed",
          "email_not_verified",
          "permission_denied",
          "not_found",
          "method_not_allowed",
          "action_limit",
          "rate_limited",
          "internal_error",
          "unavailable"
        ]
      },
      "ErrorDetails": {
        "type": "object",
        "additionalProperties": false,
        "description": "Typed facts to act on, computed by RedSwitches (never an echo of the request).",
        "properties": {
          "total": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "price_changed: the current total."
          },
          "needed": {
            "$ref": "#/components/schemas/MinorAmount",
            "description": "insufficient_credit: the amount missing."
          },
          "cap": {
            "type": "string",
            "enum": [
              "servers_day",
              "servers_month",
              "open",
              "money_month",
              "renewal_month",
              "key_month"
            ],
            "description": "cap_reached: the limit the order would go over."
          },
          "order": {
            "type": "string",
            "pattern": "^ord_[1-9][0-9]{0,9}$",
            "examples": [
              "ord_123"
            ],
            "description": "order_under_review: the order that was created."
          },
          "retry_after": {
            "type": "integer",
            "minimum": 1,
            "description": "in_progress, cooling_off: seconds to wait."
          },
          "limit": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "$ref": "#/components/schemas/MinorAmount"
              }
            ],
            "description": "action_limit: the ceiling (an integer). cap_reached: the limit in force: an integer for servers_day, servers_month and open; an amount in the account's currency (minor units) for money_month, renewal_month and key_month."
          },
          "window": {
            "type": "string",
            "enum": [
              "day",
              "30_days",
              "open"
            ],
            "description": "cap_reached: the window of the limit: day (servers_day), 30_days (servers_month, money_month, renewal_month, key_month), open (paid orders not delivered yet; no time window)."
          },
          "per": {
            "type": "string",
            "enum": [
              "server_hour",
              "account_hour",
              "server_day",
              "account_day"
            ],
            "description": "action_limit: the window of the ceiling."
          },
          "field": {
            "type": "string",
            "description": "invalid_body: the documented field that failed (absent when the failure is not about one field)."
          },
          "reason": {
            "type": "string",
            "description": "invalid_body: what is accepted, in fixed words (never your value)."
          }
        }
      },
      "Error": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "code": {
                "$ref": "#/components/schemas/ErrorCode"
              },
              "message": {
                "type": "string",
                "description": "A fixed text per code. Never repeats anything the caller sent."
              },
              "request_id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "details": {
                "$ref": "#/components/schemas/ErrorDetails"
              }
            }
          }
        }
      },
      "RdnsQueued": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "server_id",
          "ip",
          "hostname",
          "state",
          "already_requested",
          "poll_after"
        ],
        "description": "The change is carried out as an action. Poll GET /actions/{id}.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "ip": {
            "type": "string"
          },
          "hostname": {
            "type": "string",
            "description": "\"\" when the PTR is being cleared."
          },
          "state": {
            "type": "string",
            "const": "queued"
          },
          "already_requested": {
            "type": "boolean",
            "description": "True when the same change was already open; its action is returned."
          },
          "poll_after": {
            "type": "integer",
            "examples": [
              10
            ]
          }
        }
      },
      "CancelRequestBody": {
        "type": "object",
        "additionalProperties": false,
        "description": "The body may be omitted or {}.",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 255,
            "description": "Optional. Up to 255 characters; no control characters, < > { }."
          }
        }
      },
      "CancellationState": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "server_id",
          "state",
          "requested",
          "effective",
          "type"
        ],
        "description": "The server's cancellation request. A request made through the API takes effect at the end of the billing period.",
        "properties": {
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "none",
              "requested",
              "withdrawal_requested"
            ]
          },
          "requested": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "effective": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "When the server ends (its next due date)."
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "end_of_billing_period",
              "immediate",
              null
            ]
          }
        }
      },
      "OsImageList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "server_id",
          "as_of",
          "data",
          "reason"
        ],
        "description": "data is null (reason not_collected) until the list has been read for this server's current hardware.",
        "properties": {
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "as_of": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "UTC, ISO 8601, always with Z."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "not_collected",
              null
            ]
          },
          "data": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "name"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^img_[A-Za-z0-9_.-]{1,64}$",
                  "examples": [
                    "img_1042"
                  ],
                  "description": "An OS image id for reinstall (another namespace than the order's os_<n> choices)."
                },
                "name": {
                  "type": "string",
                  "maxLength": 120
                }
              }
            }
          }
        }
      },
      "ReinstallRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "os_id",
          "ssh_key_ids"
        ],
        "properties": {
          "os_id": {
            "type": "string",
            "pattern": "^img_[A-Za-z0-9_.-]{1,64}$",
            "examples": [
              "img_1042"
            ],
            "description": "An image id from GET /servers/{id}/os (img_…; the order's os_… ids are refused with 400)."
          },
          "ssh_key_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10,
            "items": {
              "type": "string",
              "pattern": "^sshkey_[1-9][0-9]{0,9}$",
              "examples": [
                "sshkey_123"
              ]
            },
            "description": "1 to 10 saved keys to install."
          },
          "hostname": {
            "type": "string",
            "maxLength": 253,
            "description": "Optional. Lower-case letters, digits, dots and dashes."
          },
          "raid": {
            "type": "string",
            "enum": [
              "none",
              "raid0",
              "raid1",
              "raid10"
            ],
            "description": "Optional; only on servers that offer a RAID choice (else 422 not_supported)."
          },
          "return_password": {
            "type": "boolean",
            "default": false,
            "description": "Optional, default false. True: the root password set by the reinstall can be read ONCE from GET /actions/{id}/credentials after the action is done (within 24 hours). False: it is never returned (emailed to the owner as in the portal)."
          }
        }
      },
      "RescueRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "The body may be {}.",
        "properties": {
          "return_password": {
            "type": "boolean",
            "default": false,
            "description": "Optional, default false. True: the rescue login can be read ONCE from GET /actions/{id}/credentials after the action is done (within 24 hours). False: the rescue login is delivered as in the portal."
          }
        }
      },
      "RescueAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "server_id",
          "state",
          "return_password",
          "poll_after"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "kind": {
            "type": "string",
            "const": "rescue"
          },
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "state": {
            "type": "string",
            "const": "queued"
          },
          "return_password": {
            "type": "boolean"
          },
          "poll_after": {
            "type": "integer",
            "examples": [
              30
            ]
          }
        }
      },
      "Credentials": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "action_id",
          "server_id",
          "username",
          "password"
        ],
        "description": "Returned once. Store it at once: the next read is 404. The owner is emailed that a password was retrieved (never the password).",
        "properties": {
          "action_id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "username": {
            "type": "string",
            "examples": [
              "root"
            ]
          },
          "password": {
            "type": "string"
          }
        }
      },
      "ReinstallAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "server_id",
          "os_id",
          "state",
          "return_password",
          "poll_after"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^act_[1-9][0-9]{0,9}$",
            "examples": [
              "act_123"
            ]
          },
          "kind": {
            "type": "string",
            "const": "reinstall"
          },
          "server_id": {
            "type": "string",
            "pattern": "^srv_[1-9][0-9]{0,9}$",
            "examples": [
              "srv_123"
            ]
          },
          "os_id": {
            "type": "string",
            "pattern": "^img_[A-Za-z0-9_.-]{1,64}$",
            "examples": [
              "img_1042"
            ],
            "description": "An OS image id for reinstall (another namespace than the order's os_<n> choices)."
          },
          "state": {
            "type": "string",
            "const": "queued"
          },
          "return_password": {
            "type": "boolean"
          },
          "poll_after": {
            "type": "integer",
            "examples": [
              30
            ]
          }
        }
      }
    }
  },
  "x-errors": [
    {
      "code": "body_not_allowed",
      "status": 400,
      "message": "This request must not have a body.",
      "when": "A GET, HEAD or DELETE request carried a body."
    },
    {
      "code": "key_in_url",
      "status": 400,
      "message": "API keys are accepted only in the Authorization header. A working key sent in a URL is revoked.",
      "when": "A key-shaped string was found anywhere in the URL. Every working key found there is revoked and its owner is emailed."
    },
    {
      "code": "invalid_parameter",
      "status": 400,
      "message": "A query parameter is not allowed here or its value is not valid. See the API documentation for this endpoint.",
      "when": "An unknown, repeated, empty or malformed query parameter."
    },
    {
      "code": "invalid_body",
      "status": 400,
      "message": "The request body is not valid JSON of the documented shape for this endpoint. Unknown fields are refused.",
      "when": "Missing body, not JSON, not one object, a duplicate name, an unknown field, a wrong type, a value of the wrong shape, Content-Type not application/json, or over 4 KB. When one field is at fault, details.field and details.reason name it and the message becomes \"The request body is not valid: <field>: <reason>.\" (fixed texts; your value is never echoed)."
    },
    {
      "code": "body_too_large",
      "status": 413,
      "message": "The request body is larger than 16 KB.",
      "when": "Refused before the API reads it."
    },
    {
      "code": "idempotency_key_required",
      "status": 400,
      "message": "This request needs an Idempotency-Key header of 8 to 64 letters, digits, dashes or underscores.",
      "when": "A POST or DELETE without a valid Idempotency-Key header (not needed for an order dry run)."
    },
    {
      "code": "insufficient_credit",
      "status": 402,
      "message": "The account credit that may be spent through the API does not cover this order. Add funds in the client area.",
      "when": "details.needed holds the amount missing."
    },
    {
      "code": "ordering_not_enabled",
      "status": 403,
      "message": "Ordering through the API is not turned on for this account. The owner turns it on on the API page.",
      "when": "The account's ordering switch is off."
    },
    {
      "code": "not_eligible",
      "status": 403,
      "message": "This account cannot order through the API right now. The account owner can see the reason on the API page.",
      "when": "An eligibility check failed (for example the key has no spend cap)."
    },
    {
      "code": "cooling_off",
      "status": 403,
      "message": "Ordering opens 24 hours after it was turned on and after a new ordering key.",
      "when": "details.retry_after and the Retry-After header: seconds until ordering opens."
    },
    {
      "code": "cap_reached",
      "status": 403,
      "message": "This order would go over a limit of this key or of the account. Nothing was ordered.",
      "when": "details.cap names the limit, details.limit its value and details.window its window. Account limits are set by RedSwitches; contact support to raise one."
    },
    {
      "code": "ordering_paused",
      "status": 403,
      "message": "Ordering through the API is paused by RedSwitches. Nothing was ordered. Try again later.",
      "when": "RedSwitches paused API ordering."
    },
    {
      "code": "power_paused",
      "status": 403,
      "message": "Power actions through the API are paused for this account. RedSwitches staff have been told.",
      "when": "Power is paused for the account, for example after a burst of power-offs."
    },
    {
      "code": "in_progress",
      "status": 409,
      "message": "A request with this Idempotency-Key is still being processed. Ask again with the same key in a few seconds.",
      "when": "details.retry_after and the Retry-After header: seconds to wait. Retry with the same Idempotency-Key and body."
    },
    {
      "code": "price_changed",
      "status": 409,
      "message": "The total is not the expected_total that was sent. Nothing was ordered. The current total is in the details.",
      "when": "details.total holds the current total."
    },
    {
      "code": "sold_out",
      "status": 409,
      "message": "This server is not in stock any more. Nothing was ordered.",
      "when": ""
    },
    {
      "code": "order_not_placed",
      "status": 409,
      "message": "The order could not be completed and nothing was charged. RedSwitches staff have been told.",
      "when": ""
    },
    {
      "code": "order_under_review",
      "status": 409,
      "message": "This order needs a check by RedSwitches staff before it continues. Do not repeat it; you will hear from us.",
      "when": "details.order names the order when one was created."
    },
    {
      "code": "server_busy",
      "status": 409,
      "message": "Another action on this server is queued, running or unsettled. Wait until it has finished, then try again.",
      "when": "Also while the server is being delivered or installed."
    },
    {
      "code": "server_not_active",
      "status": 409,
      "message": "This server is not active (pending, suspended or ended), so this action is not available.",
      "when": ""
    },
    {
      "code": "ssh_key_conflict",
      "status": 409,
      "message": "That key is already saved on this account, or the account holds the most keys it can.",
      "when": ""
    },
    {
      "code": "not_supported",
      "status": 422,
      "message": "This server does not support that through the API.",
      "when": ""
    },
    {
      "code": "ip_not_on_server",
      "status": 422,
      "message": "That IP address is not assigned to this server.",
      "when": ""
    },
    {
      "code": "invalid_ssh_key",
      "status": 422,
      "message": "That is not a valid SSH public key.",
      "when": ""
    },
    {
      "code": "idempotency_conflict",
      "status": 422,
      "message": "This Idempotency-Key was used for a different request. Use a new key for a new order.",
      "when": "Same key and Idempotency-Key, different body or target."
    },
    {
      "code": "not_orderable",
      "status": 422,
      "message": "This offer cannot be ordered with these choices through the API.",
      "when": "Unknown or hidden offer, an OS that is not one of the offer's, an SSH key not on the account, a billing cycle the key does not allow."
    },
    {
      "code": "invalid_key",
      "status": 401,
      "message": "Missing or invalid API key. Send it as \"Authorization: Bearer <key>\".",
      "when": ""
    },
    {
      "code": "key_revoked",
      "status": 401,
      "message": "This API key has been revoked.",
      "when": "Also after a security event on the account (password, email or two-factor change, API access turned off)."
    },
    {
      "code": "key_expired",
      "status": 401,
      "message": "This API key has expired.",
      "when": ""
    },
    {
      "code": "test_key",
      "status": 401,
      "message": "Test keys cannot be used on the live API.",
      "when": ""
    },
    {
      "code": "api_not_enabled",
      "status": 403,
      "message": "API access is not enabled for this account.",
      "when": ""
    },
    {
      "code": "account_blocked",
      "status": 403,
      "message": "API access for this account is blocked. Please contact support.",
      "when": ""
    },
    {
      "code": "not_invited",
      "status": 403,
      "message": "API access is by invitation only for now.",
      "when": ""
    },
    {
      "code": "ip_not_allowed",
      "status": 403,
      "message": "This key cannot be used from your IP address.",
      "when": "The key has an IP allow-list that does not include the caller."
    },
    {
      "code": "account_inactive",
      "status": 403,
      "message": "This account is not active.",
      "when": ""
    },
    {
      "code": "owner_changed",
      "status": 403,
      "message": "This API key was created by a user who no longer owns the account. The owner must create a new key.",
      "when": ""
    },
    {
      "code": "email_not_verified",
      "status": 403,
      "message": "The account owner must verify their email address before the API can be used.",
      "when": ""
    },
    {
      "code": "permission_denied",
      "status": 403,
      "message": "This API key does not have the permission this endpoint needs.",
      "when": "Also when a power key's server list does not cover the server."
    },
    {
      "code": "not_found",
      "status": 404,
      "message": "Nothing was found at this address: no such endpoint, or no such item on this account.",
      "when": "Another account's item gives the identical answer."
    },
    {
      "code": "method_not_allowed",
      "status": 405,
      "message": "This endpoint does not take this method. The Allow header lists the methods it takes.",
      "when": "The Allow header lists the methods of the path (HEAD is not taken by GET /actions/{id}/credentials)."
    },
    {
      "code": "action_limit",
      "status": 429,
      "message": "This would go over a limit of the account for this action (see the details). Nothing was changed. Try again later.",
      "when": "details.limit and details.per."
    },
    {
      "code": "rate_limited",
      "status": 429,
      "message": "Too many requests. Wait for the number of seconds in the Retry-After header.",
      "when": ""
    },
    {
      "code": "internal_error",
      "status": 500,
      "message": "Something went wrong on our side. Quote the request id when you contact support.",
      "when": ""
    },
    {
      "code": "unavailable",
      "status": 503,
      "message": "The API is temporarily unavailable.",
      "when": "The API, a part of it or a dependency is switched off or not answering. Nothing was done."
    }
  ],
  "x-rate-limits": {
    "key_per_minute": 120,
    "account_per_minute": 300,
    "bad_auth_per_ip_per_minute": 30,
    "note": "Defaults, over a sliding one-minute window. X-RateLimit-Reset is the end of the current fixed minute."
  }
}
