{
  "openapi": "3.0.0",
  "paths": {
    "/v1/auth/login": {
      "post": {
        "description": "Returns a session token for `Authorization: Bearer`. On an account with two-factor on, `accessToken` is null and `twoFactor.pendingToken` goes to POST /v1/auth/two-factor. Throttled to 10 a minute; failures count towards the account lockout.",
        "operationId": "Auth_login",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1LoginBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Session"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sign in with email and password",
        "tags": [
          "Account"
        ]
      }
    },
    "/v1/auth/two-factor": {
      "post": {
        "description": "Each code works once; five wrong codes lock the account for 15 minutes.",
        "operationId": "Auth_twoFactor",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1TwoFactorBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Session"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish a sign-in that asked for a two-factor code",
        "tags": [
          "Account"
        ]
      }
    },
    "/v1/backups/{backupId}/restore": {
      "post": {
        "description": "Destructive: replaces the live data, after taking a safety backup first (its id is on the restore). Requires ADMIN.",
        "operationId": "Backups_restore",
        "parameters": [
          {
            "name": "backupId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Restore"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Restore a backup over its database",
        "tags": [
          "Backups"
        ]
      }
    },
    "/v1/build-detection": {
      "get": {
        "description": "Best effort: fields come back null when the repo cannot be inspected. The same detection runs again when the service is created.",
        "operationId": "Services_detect",
        "parameters": [
          {
            "name": "gitUrl",
            "required": false,
            "in": "query",
            "description": "A public HTTPS git URL.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "repoFullName",
            "required": false,
            "in": "query",
            "description": "owner/name of a repo our GitHub App can see.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "installationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "branch",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rootDir",
            "required": false,
            "in": "query",
            "description": "A folder inside the repo, e.g. \"apps/api\".",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DetectedBuild"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview the build settings a repo would get",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/build-detection/apps": {
      "get": {
        "description": "The members of a monorepo, a frontend next to a backend, or just the root app, each with its proposed build settings.",
        "operationId": "Services_detectApps",
        "parameters": [
          {
            "name": "gitUrl",
            "required": false,
            "in": "query",
            "description": "A public HTTPS git URL.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "repoFullName",
            "required": false,
            "in": "query",
            "description": "owner/name of a repo our GitHub App can see.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "installationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "branch",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rootDir",
            "required": false,
            "in": "query",
            "description": "A folder inside the repo, e.g. \"apps/api\".",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DetectedRepoApps"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Find the deployable apps in a repo",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/cron-runs/{runId}": {
      "get": {
        "operationId": "CronJobs_getRun",
        "parameters": [
          {
            "name": "runId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CronRun"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a cron run",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/cron-runs/{runId}/logs": {
      "get": {
        "operationId": "CronJobs_logs",
        "parameters": [
          {
            "name": "runId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CronRunLogList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A cron run's output, oldest line first",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/custom-domains/{domainId}": {
      "delete": {
        "description": "A redeploy drops the route, so the domain stops serving.",
        "operationId": "CustomDomains_remove",
        "parameters": [
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Detach a custom domain",
        "tags": [
          "Custom domains"
        ]
      }
    },
    "/v1/custom-domains/{domainId}/verify": {
      "post": {
        "operationId": "CustomDomains_verify",
        "parameters": [
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CustomDomain"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Re-check a custom domain's DNS now",
        "tags": [
          "Custom domains"
        ]
      }
    },
    "/v1/deploys/{deployId}": {
      "get": {
        "operationId": "Deploys_get",
        "parameters": [
          {
            "name": "deployId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Deploy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a deploy",
        "tags": [
          "Deploys"
        ]
      }
    },
    "/v1/deploys/{deployId}/cancel": {
      "post": {
        "description": "The version already live keeps serving.",
        "operationId": "Deploys_cancel",
        "parameters": [
          {
            "name": "deployId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Deploy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel a deploy that has not gone live",
        "tags": [
          "Deploys"
        ]
      }
    },
    "/v1/deploys/{deployId}/logs": {
      "get": {
        "description": "Readable once the build has finished.",
        "operationId": "DeployLogs_list",
        "parameters": [
          {
            "name": "deployId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DeployLogList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A deploy's build log, oldest line first",
        "tags": [
          "Deploys"
        ]
      }
    },
    "/v1/deploys/{deployId}/rollback": {
      "post": {
        "description": "Replays the stored image rather than rebuilding. Only a deploy that went live can be rolled back to.",
        "operationId": "Deploys_rollback",
        "parameters": [
          {
            "name": "deployId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Deploy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Roll back to a previous deploy's image",
        "tags": [
          "Deploys"
        ]
      }
    },
    "/v1/dns-records/{recordId}": {
      "patch": {
        "operationId": "Domains_updateRecord",
        "parameters": [
          {
            "name": "recordId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1DnsRecordBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsRecord"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace a record",
        "tags": [
          "Domains & DNS"
        ]
      },
      "delete": {
        "operationId": "Domains_deleteRecord",
        "parameters": [
          {
            "name": "recordId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a record",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/dns-zones/{zoneId}": {
      "delete": {
        "operationId": "Domains_deleteZone",
        "parameters": [
          {
            "name": "zoneId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stop hosting a zone, with all its records",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/dns-zones/{zoneId}/export": {
      "get": {
        "operationId": "Domains_exportZone",
        "parameters": [
          {
            "name": "zoneId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The zone as a BIND zone file",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/dns-zones/{zoneId}/records": {
      "get": {
        "operationId": "Domains_records",
        "parameters": [
          {
            "name": "zoneId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsRecordList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A zone's records",
        "tags": [
          "Domains & DNS"
        ]
      },
      "post": {
        "operationId": "Domains_addRecord",
        "parameters": [
          {
            "name": "zoneId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1DnsRecordBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsRecord"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a record; published straight away",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/dns-zones/{zoneId}/verify": {
      "post": {
        "operationId": "Domains_verifyZone",
        "parameters": [
          {
            "name": "zoneId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsZone"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check ownership now and publish when proven",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/environments/{environmentId}": {
      "get": {
        "description": "The same membership and project-scope check as listing the project. `kind` is DEV, UAT or PROD when the name is exactly that tier.",
        "operationId": "Environments_get",
        "parameters": [
          {
            "name": "environmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1EnvironmentDetail"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an environment, with its project and tier",
        "tags": [
          "Environments"
        ]
      },
      "delete": {
        "description": "Irreversible: tears down every service in it, data included. Requires ADMIN.",
        "operationId": "Environments_remove",
        "parameters": [
          {
            "name": "environmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete an environment and everything in it",
        "tags": [
          "Environments"
        ]
      }
    },
    "/v1/environments/{environmentId}/services": {
      "get": {
        "operationId": "Services_list",
        "parameters": [
          {
            "name": "environmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ServiceList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the services in an environment",
        "tags": [
          "Services"
        ]
      },
      "post": {
        "description": "A web service, static site, cron job or database. Subject to the compute gate and to your balance for paid sizes.",
        "operationId": "Services_create",
        "parameters": [
          {
            "name": "environmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateServiceBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Service"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a service and queue its first deploy",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/function-uploads": {
      "post": {
        "operationId": "Functions_upload",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1FunctionUploadBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StaticUpload"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reserve an upload for a function's code (a .zip, up to 20 MB)",
        "tags": [
          "Functions"
        ]
      }
    },
    "/v1/functions": {
      "post": {
        "description": "Creates the function on its first deploy. The previous version keeps serving until the new one is live, and stays if the deploy fails.",
        "operationId": "Functions_deploy",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1DeployFunctionBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DeployFunctionResult"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Deploy an uploaded zip as the next version of a function",
        "tags": [
          "Functions"
        ]
      }
    },
    "/v1/functions/{functionId}": {
      "get": {
        "operationId": "Functions_get",
        "parameters": [
          {
            "name": "functionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Function"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a function, with its live and newest versions",
        "tags": [
          "Functions"
        ]
      },
      "delete": {
        "description": "Its URL stops answering and its logs go with it.",
        "operationId": "Functions_remove",
        "parameters": [
          {
            "name": "functionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a function",
        "tags": [
          "Functions"
        ]
      }
    },
    "/v1/invoices/{invoiceId}": {
      "get": {
        "operationId": "Billing_invoice",
        "parameters": [
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1InvoiceView"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "One invoice with its line items",
        "tags": [
          "Billing"
        ]
      }
    },
    "/v1/me": {
      "get": {
        "operationId": "Auth_me",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Me"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The signed-in person (or the owner of the API key)",
        "tags": [
          "Account"
        ]
      }
    },
    "/v1/previews/{previewId}": {
      "get": {
        "operationId": "PrPreviews_get",
        "parameters": [
          {
            "name": "previewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1PrPreview"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "One preview",
        "tags": [
          "Previews"
        ]
      },
      "delete": {
        "operationId": "PrPreviews_teardown",
        "parameters": [
          {
            "name": "previewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1PrPreview"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Tear a preview down now",
        "tags": [
          "Previews"
        ]
      }
    },
    "/v1/pricing": {
      "get": {
        "operationId": "Pricing_catalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1PricingCatalog"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Instance tiers, unit rates and free allowances",
        "tags": [
          "Catalogue"
        ]
      }
    },
    "/v1/projects/{projectId}": {
      "get": {
        "operationId": "Projects_get",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Project"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a project, with its environments",
        "tags": [
          "Projects"
        ]
      },
      "patch": {
        "operationId": "Projects_update",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1UpdateProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Project"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change a project's name, display name or description",
        "tags": [
          "Projects"
        ]
      },
      "delete": {
        "description": "Irreversible: tears down every service in every environment, data included. Requires ADMIN.",
        "operationId": "Projects_remove",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a project and everything in it",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/projects/{projectId}/environments": {
      "post": {
        "operationId": "Environments_create",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateEnvironmentBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Environment"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an environment in a project",
        "tags": [
          "Environments"
        ]
      },
      "get": {
        "operationId": "Projects_environments",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1EnvironmentList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a project's environments",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/projects/{projectId}/functions": {
      "get": {
        "operationId": "Functions_list",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environmentId",
            "required": false,
            "in": "query",
            "description": "Defaults to the project's production environment.",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1FunctionList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a project environment's functions by name",
        "tags": [
          "Functions"
        ]
      }
    },
    "/v1/projects/{projectId}/usage": {
      "get": {
        "operationId": "Metrics_project",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ProjectUsage"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A project's resource use, per service",
        "tags": [
          "Metrics"
        ]
      }
    },
    "/v1/regions": {
      "get": {
        "description": "`freeTier` says whether the Free size can be placed there; `isDefault` marks the default.",
        "operationId": "Regions_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DeployLocationList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The regions a service can be created in",
        "tags": [
          "Catalogue"
        ]
      }
    },
    "/v1/registered-domains/{domainId}": {
      "patch": {
        "operationId": "Domains_update",
        "parameters": [
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1UpdateDomainBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1RegisteredDomain"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Turn auto-renew on or off, or change the nameservers",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/registered-domains/{domainId}/renewal-quote": {
      "get": {
        "operationId": "Domains_renewalQuote",
        "parameters": [
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "years",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainRenewalQuote"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "What renewing would cost, and the new expiry",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/registered-domains/{domainId}/renewals": {
      "post": {
        "operationId": "Domains_renew",
        "parameters": [
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1RenewDomainBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainCheckout"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start renewing a domain; returns a checkout link",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/restores/{restoreId}": {
      "get": {
        "operationId": "Backups_getRestore",
        "parameters": [
          {
            "name": "restoreId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Restore"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a restore",
        "tags": [
          "Backups"
        ]
      }
    },
    "/v1/services": {
      "get": {
        "description": "A flat list (id, name, project, type), ordered by project. `search` matches the service and project name.",
        "operationId": "Services_listMine",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ServiceSummaryList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Every service across your workspaces",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}": {
      "get": {
        "operationId": "Services_get",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Service"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a service",
        "tags": [
          "Services"
        ]
      },
      "patch": {
        "description": "Each part is optional and applied in order: name, build, source. Build and source changes apply on the next deploy unless `source.redeploy` is true.",
        "operationId": "Services_update",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1UpdateServiceBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Service"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rename a service, or change its build settings or source",
        "tags": [
          "Services"
        ]
      },
      "delete": {
        "description": "Irreversible: removes its containers, volumes, DNS and secrets — a database's data goes with it. Requires ADMIN.",
        "operationId": "Services_remove",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a service",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/backups": {
      "get": {
        "operationId": "Backups_list",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1BackupList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a database's backups, newest first",
        "tags": [
          "Backups"
        ]
      },
      "post": {
        "description": "Returns the backup in PENDING; poll it until COMPLETED.",
        "operationId": "Backups_create",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Backup"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Back a database up now",
        "tags": [
          "Backups"
        ]
      }
    },
    "/v1/services/{serviceId}/connection": {
      "get": {
        "description": "The password is empty for a read-only role. 404 for a service that is not a database, or not provisioned yet.",
        "operationId": "Services_connection",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Connection"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A database's connection details",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/cron": {
      "patch": {
        "description": "Takes effect from the next scheduled run.",
        "operationId": "CronJobs_update",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1UpdateCronBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CronSettings"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change a cron job's schedule or command",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/services/{serviceId}/cron/resume": {
      "post": {
        "operationId": "CronJobs_resume",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resume scheduled runs",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/services/{serviceId}/cron/suspend": {
      "post": {
        "description": "Manual runs still work while paused.",
        "operationId": "CronJobs_suspend",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pause scheduled runs",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/services/{serviceId}/custom-domains": {
      "get": {
        "operationId": "CustomDomains_list",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CustomDomainList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a service's custom domains, oldest first",
        "tags": [
          "Custom domains"
        ]
      },
      "post": {
        "description": "Create the records in `dnsTarget` at your DNS provider, then verify. The route and certificate apply on a redeploy that starts automatically.",
        "operationId": "CustomDomains_add",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1AddCustomDomainBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CustomDomain"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Attach a custom domain to a web service",
        "tags": [
          "Custom domains"
        ]
      }
    },
    "/v1/services/{serviceId}/database/exports": {
      "post": {
        "operationId": "DbConsole_exportDatabase",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1DatabaseExportBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Export"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export the whole database to a download link",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/database/objects": {
      "get": {
        "operationId": "DbConsole_objects",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DatabaseObjectList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Tables and views (SQL) or collections (MongoDB)",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/database/query": {
      "post": {
        "description": "Runs as the service's own database user: it can write and drop as well as read.",
        "operationId": "DbConsole_query",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1DatabaseQueryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1QueryResult"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Run a statement and get the result grid",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/database/tables": {
      "get": {
        "operationId": "DbConsole_tables",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1TableStatList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Tables with estimated row counts",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/database/tables/{table}/columns": {
      "get": {
        "operationId": "DbConsole_columns",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "table",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "schema",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1TableSchema"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A table's columns and primary key",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/database/tables/{table}/exports": {
      "post": {
        "operationId": "DbConsole_exportTable",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "table",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1TableExportBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Export"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export one table as CSV, JSON or SQL to a download link",
        "tags": [
          "Database console"
        ]
      }
    },
    "/v1/services/{serviceId}/deploys": {
      "get": {
        "operationId": "Deploys_list",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DeployList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a service's deploys, newest first",
        "tags": [
          "Deploys"
        ]
      },
      "post": {
        "description": "Builds the tracked branch (or pulls the image) and rolls it out. Also how to restart a service. Poll the deploy until it is RUNNING or FAILED.",
        "operationId": "Deploys_trigger",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Deploy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Deploy a service now",
        "tags": [
          "Deploys"
        ]
      }
    },
    "/v1/services/{serviceId}/env-vars": {
      "get": {
        "description": "Values are blanked for a read-only role. Linked values come from a sibling database.",
        "operationId": "Services_envVars",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1EnvVarList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a service's environment variables, by key",
        "tags": [
          "Services"
        ]
      },
      "patch": {
        "description": "Upserts by key. Keys not listed are left as they are.",
        "operationId": "Services_setEnvVars",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1SetEnvVarsBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1EnvVarChange"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create or replace environment variables",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/env-vars/{key}": {
      "delete": {
        "operationId": "Services_deleteEnvVar",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1EnvVarChange"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove one environment variable",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/metrics": {
      "get": {
        "operationId": "Metrics_series",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "range",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/MetricRange"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MetricSeries"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A service's resource time series",
        "tags": [
          "Metrics"
        ]
      }
    },
    "/v1/services/{serviceId}/previews": {
      "get": {
        "operationId": "PrPreviews_list",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1PrPreviewList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A service's pull-request previews",
        "tags": [
          "Previews"
        ]
      }
    },
    "/v1/services/{serviceId}/previews-enabled": {
      "put": {
        "operationId": "PrPreviews_setEnabled",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1PreviewsSettingBody"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Turn pull-request previews on or off",
        "tags": [
          "Previews"
        ]
      }
    },
    "/v1/services/{serviceId}/resume": {
      "post": {
        "operationId": "Services_resume",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Service"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Bring a suspended service back on the same URL",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/runs": {
      "get": {
        "operationId": "CronJobs_runs",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CronRunList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a cron job's runs, newest first",
        "tags": [
          "Cron jobs"
        ]
      },
      "post": {
        "description": "Needs a built image: deploy the job first.",
        "operationId": "CronJobs_run",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CronRun"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Run a cron job now",
        "tags": [
          "Cron jobs"
        ]
      }
    },
    "/v1/services/{serviceId}/secret-files": {
      "get": {
        "description": "Contents are blanked for a read-only role.",
        "operationId": "Services_secretFiles",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1SecretFileList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a service's secret files",
        "tags": [
          "Services"
        ]
      },
      "put": {
        "description": "Mounted into the container on the next deploy.",
        "operationId": "Services_setSecretFile",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1SecretFileInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1SecretFileChange"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create or replace one secret file",
        "tags": [
          "Services"
        ]
      },
      "delete": {
        "operationId": "Services_deleteSecretFile",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "required": true,
            "in": "query",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1SecretFileChange"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove one secret file by path",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/static-deploys": {
      "post": {
        "description": "In place, on the same URL. Returns the new deploy.",
        "operationId": "StaticSites_redeploy",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1RedeployStaticSiteBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Deploy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace a static site's content from a fresh upload",
        "tags": [
          "Static sites"
        ]
      }
    },
    "/v1/services/{serviceId}/suspend": {
      "post": {
        "description": "Variables, domains, build settings, history and volumes are kept. Compute stops being billed.",
        "operationId": "Services_suspend",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Service"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stop a service, keeping everything else",
        "tags": [
          "Services"
        ]
      }
    },
    "/v1/services/{serviceId}/usage": {
      "get": {
        "operationId": "Metrics_service",
        "parameters": [
          {
            "name": "serviceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ServiceUsage"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A service's latest resource sample",
        "tags": [
          "Metrics"
        ]
      }
    },
    "/v1/static-sites": {
      "post": {
        "operationId": "StaticSites_create",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateStaticSiteBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StaticSite"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish an uploaded artifact as a new static site",
        "tags": [
          "Static sites"
        ]
      }
    },
    "/v1/static-uploads": {
      "post": {
        "operationId": "StaticSites_upload",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1StaticUploadBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StaticUpload"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reserve an upload for a .zip or .html artifact",
        "tags": [
          "Static sites"
        ]
      }
    },
    "/v1/workspaces": {
      "get": {
        "operationId": "Workspaces_list",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1WorkspaceList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the workspaces you belong to",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}": {
      "get": {
        "operationId": "Workspaces_get",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Workspace"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a workspace",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/api-keys": {
      "get": {
        "operationId": "ApiTokens_list",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ApiTokenList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's API keys (hints only, never the key)",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/balance": {
      "get": {
        "operationId": "Wallet_balance",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1WalletBalance"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The wallet balance paid services run on, in kobo",
        "tags": [
          "Billing"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/buckets": {
      "get": {
        "operationId": "Storage_list",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StorageBucketList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's buckets in one region",
        "tags": [
          "Storage"
        ]
      },
      "post": {
        "operationId": "Storage_create",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateBucketBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StorageBucket"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a bucket",
        "tags": [
          "Storage"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucket}": {
      "delete": {
        "description": "Refused while it holds objects unless `force=true`, which deletes them too.",
        "operationId": "Storage_remove",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "force",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a bucket",
        "tags": [
          "Storage"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucket}/cors": {
      "get": {
        "operationId": "Storage_cors",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1CorsRuleList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A bucket's CORS rules",
        "tags": [
          "Storage"
        ]
      },
      "put": {
        "operationId": "Storage_setCors",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/V1CorsRuleInput"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace a bucket's CORS rules",
        "tags": [
          "Storage"
        ]
      },
      "delete": {
        "operationId": "Storage_deleteCors",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a bucket's CORS rules",
        "tags": [
          "Storage"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucket}/policy": {
      "get": {
        "operationId": "Storage_policy",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1BucketPolicy"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A bucket's policy document, or null",
        "tags": [
          "Storage"
        ]
      },
      "put": {
        "operationId": "Storage_setPolicy",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1BucketPolicyBody"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace a bucket's policy",
        "tags": [
          "Storage"
        ]
      },
      "delete": {
        "operationId": "Storage_deletePolicy",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "required": false,
            "in": "query",
            "description": "The bucket's region; the workspace default when omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a bucket's policy (makes it private)",
        "tags": [
          "Storage"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/dns-zones": {
      "get": {
        "operationId": "Domains_zones",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsZoneList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's DNS zones",
        "tags": [
          "Domains & DNS"
        ]
      },
      "post": {
        "description": "The zone stays unpublished until ownership is proven: add `verificationRecord`, or point the nameservers at us, then verify.",
        "operationId": "Domains_createZone",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateDnsZoneBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DnsZone"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Host a domain’s DNS with us",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/domain-availability": {
      "get": {
        "operationId": "Domains_availability",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domains",
            "required": true,
            "in": "query",
            "description": "Up to 20 full names, e.g. domains=acme.ng&domains=acme.com",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainSearchRowList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Whether exact names can be bought, and for how much",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/domain-orders": {
      "get": {
        "operationId": "Domains_orders",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainOrderList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Domain purchases and renewals, newest first",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/domain-search": {
      "get": {
        "operationId": "Domains_search",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "required": true,
            "in": "query",
            "schema": {
              "example": "acme",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainSearchResults"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Search for a domain to buy, with prices in kobo",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/github/branches": {
      "get": {
        "operationId": "Github_branches",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "repo",
            "required": true,
            "in": "query",
            "description": "owner/name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1BranchList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A repository's branch names",
        "tags": [
          "GitHub"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/github/install-url": {
      "get": {
        "operationId": "Github_installUrl",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1GithubInstallUrl"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The link that installs the GitHub App for this workspace",
        "tags": [
          "GitHub"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/github/repositories": {
      "get": {
        "operationId": "Github_repositories",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Only rows whose name contains this. Send the same value with every page of one walk.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1RepositoryList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Repositories the workspace's GitHub App installations can see",
        "tags": [
          "GitHub"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/invites": {
      "get": {
        "operationId": "Members_pending",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1InviteList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pending invites (without their join links)",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/invoices": {
      "get": {
        "operationId": "Billing_invoices",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1InvoiceList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's monthly invoices, newest first",
        "tags": [
          "Billing"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/mail/domains": {
      "get": {
        "operationId": "Mail_domains",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MailDomainList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's sending domains",
        "tags": [
          "Email"
        ]
      },
      "post": {
        "description": "Returns the DNS records to publish, then verify it.",
        "operationId": "Mail_create",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateMailDomainBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MailDomainDetail"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a sending domain",
        "tags": [
          "Email"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/mail/domains/{domainId}": {
      "get": {
        "operationId": "Mail_get",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MailDomainDetail"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A sending domain with its DNS records",
        "tags": [
          "Email"
        ]
      },
      "delete": {
        "operationId": "Mail_remove",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a sending domain",
        "tags": [
          "Email"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/mail/domains/{domainId}/verify": {
      "post": {
        "operationId": "Mail_verify",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domainId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MailDomainDetail"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check a sending domain's DNS records now",
        "tags": [
          "Email"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/mail/keys": {
      "get": {
        "operationId": "Mail_keys",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MailApiKeyList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's mail keys (hints only, never the key)",
        "tags": [
          "Email"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/members": {
      "get": {
        "operationId": "Members_members",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1MemberList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's members",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/projects": {
      "get": {
        "operationId": "Projects_list",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Ignored when a cursor is given.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "The `nextCursor` of the previous page, unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ProjectList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List a workspace's projects, newest first",
        "tags": [
          "Projects"
        ]
      },
      "post": {
        "operationId": "Projects_create",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1CreateProjectBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1Project"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a project",
        "tags": [
          "Projects"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/registered-domains": {
      "get": {
        "operationId": "Domains_owned",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1RegisteredDomainList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Domains this workspace owns through us",
        "tags": [
          "Domains & DNS"
        ]
      },
      "post": {
        "description": "Returns a checkout link; the domain is registered once it is paid. The price is our catalogue price for the term.",
        "operationId": "Domains_purchase",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (1–255 printable characters). A retry with the same key and body returns the first response instead of acting twice, for 24 hours.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V1PurchaseDomainBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1DomainCheckout"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start buying a domain",
        "tags": [
          "Domains & DNS"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/roles": {
      "get": {
        "operationId": "Members_teamRoles",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1TeamRoleList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A workspace's named roles",
        "tags": [
          "Workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/storage/access-keys": {
      "get": {
        "operationId": "Storage_accessKeys",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1StorageAccessKeyList"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The workspace's storage access keys (IDs only, never secrets)",
        "tags": [
          "Storage"
        ]
      }
    },
    "/v1/workspaces/{workspaceId}/usage": {
      "get": {
        "operationId": "Billing_usage",
        "parameters": [
          {
            "name": "workspaceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1WorkspaceUsageMeters"
                }
              }
            }
          },
          "default": {
            "description": "Any failure: always this envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V1ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "This month's metered usage against the free allowances",
        "tags": [
          "Billing"
        ]
      }
    }
  },
  "info": {
    "title": "Naijacloud API",
    "description": "The public REST API. Authenticate with `Authorization: Bearer nc_live_…` (create a key in the dashboard under Settings → API keys). Conventions — pagination, errors, idempotency, rate limits, versioning — are described at https://naijacloud.com/docs/api.",
    "version": "v1",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://api.naijacloud.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "nc_live_…",
        "type": "http"
      }
    },
    "schemas": {
      "ApiTokenScope": {
        "type": "string",
        "enum": [
          "DATABASES",
          "DEPLOYS",
          "EMAIL_SEND",
          "PLATFORM_API",
          "READ",
          "WRITE"
        ]
      },
      "BackupFailureReason": {
        "type": "string",
        "enum": [
          "DATABASE_NOT_RUNNING",
          "DATABASE_NOT_FOUND",
          "NOT_PROVISIONED",
          "NOT_SUPPORTED",
          "DUMP_FAILED",
          "RESTORE_FAILED",
          "DISK_FULL",
          "OUT_OF_MEMORY",
          "UPLOAD_FAILED",
          "DOWNLOAD_FAILED",
          "BACKUP_FILE_MISSING",
          "STORAGE_NOT_CONFIGURED",
          "SERVER_UNREACHABLE",
          "TIMEOUT",
          "SERVER_NEEDS_UPDATE",
          "ALREADY_RUNNING",
          "NO_LONGER_EXISTS",
          "SAFETY_BACKUP_FAILED",
          "UNKNOWN"
        ]
      },
      "BackupStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "RUNNING",
          "COMPLETED",
          "FAILED"
        ]
      },
      "BackupTrigger": {
        "type": "string",
        "enum": [
          "HOURLY",
          "DAILY",
          "WEEKLY",
          "MANUAL",
          "PRE_RESTORE"
        ]
      },
      "BucketVisibility": {
        "type": "string",
        "enum": [
          "PRIVATE",
          "PUBLIC_READ"
        ]
      },
      "CronLogStream": {
        "type": "string",
        "enum": [
          "OUTPUT",
          "SYSTEM"
        ]
      },
      "CronRunStatus": {
        "type": "string",
        "enum": [
          "QUEUED",
          "RUNNING",
          "SUCCEEDED",
          "FAILED",
          "TIMED_OUT",
          "SKIPPED"
        ]
      },
      "CronRunTrigger": {
        "type": "string",
        "enum": [
          "SCHEDULED",
          "MANUAL"
        ]
      },
      "CustomDomainStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "ACTIVE"
        ]
      },
      "DatabaseExportFormat": {
        "type": "string",
        "enum": [
          "SQL",
          "ARCHIVE"
        ]
      },
      "DeployErrorCode": {
        "type": "string",
        "enum": [
          "MISSING_SCRIPT",
          "COMMAND_NOT_FOUND",
          "MODULE_NOT_FOUND",
          "BUILD_FAILED",
          "CRASH",
          "OOM",
          "PORT_NOT_LISTENING",
          "HEALTH_TIMEOUT",
          "IMAGE_REJECTED",
          "BUILD_OOM",
          "NODE_BUSY",
          "NODE_LOW_DISK",
          "DATA_SERVICE_ON_OTHER_NODE",
          "FREE_BUILD_LIMIT",
          "UNKNOWN"
        ]
      },
      "DeployStatus": {
        "type": "string",
        "enum": [
          "QUEUED",
          "BUILDING",
          "TESTING",
          "DEPLOYING",
          "RUNNING",
          "FAILED",
          "CANCELLED",
          "REPLACED",
          "SUPERSEDED"
        ]
      },
      "DeployTrigger": {
        "type": "string",
        "enum": [
          "PUSH",
          "MANUAL",
          "ROLLBACK",
          "FIRST_DEPLOY",
          "SYSTEM"
        ],
        "description": "What started it: a push, a person, a rollback, …"
      },
      "DnsRecordOrigin": {
        "type": "string",
        "enum": [
          "MAIL",
          "SERVICE",
          "USER"
        ]
      },
      "DnsRecordType": {
        "type": "string",
        "enum": [
          "A",
          "AAAA",
          "ALIAS",
          "CAA",
          "CNAME",
          "MX",
          "NS",
          "SRV",
          "TXT"
        ]
      },
      "DnsZoneVerificationMethod": {
        "type": "string",
        "enum": [
          "LEGACY",
          "NS",
          "PURCHASE",
          "TXT"
        ],
        "description": "How ownership of the domain was proven; null while pending."
      },
      "DomainOrderKind": {
        "type": "string",
        "enum": [
          "REGISTER",
          "RENEW"
        ]
      },
      "DomainOrderStatus": {
        "type": "string",
        "enum": [
          "ABANDONED",
          "FULFILLED",
          "PAID",
          "PENDING",
          "REFUNDED",
          "REFUND_DUE"
        ]
      },
      "DomainUnavailableReason": {
        "type": "string",
        "enum": [
          "CHECK_FAILED",
          "PRICING_UNAVAILABLE",
          "TAKEN",
          "TLD_COMING_SOON",
          "TLD_UNSUPPORTED"
        ],
        "description": "The same answer as a code. Branch on this, not on the sentence — the sentence is copy and will be reworded, and \"somebody else has it\" and \"we cannot sell it yet\" are opposite answers that look alike."
      },
      "EnvVarScope": {
        "type": "string",
        "enum": [
          "ALL",
          "PROD",
          "UAT",
          "DEV"
        ],
        "description": "When the variable is available. Defaults to build and runtime."
      },
      "EnvironmentKind": {
        "type": "string",
        "enum": [
          "DEV",
          "UAT",
          "PROD"
        ],
        "description": "DEV, UAT or PROD when the name is exactly that tier (any case); null for a custom name such as \"staging\". The tier decides which scoped variables apply."
      },
      "FunctionStatus": {
        "type": "string",
        "enum": [
          "DEPLOYING",
          "LIVE",
          "SLEEPING",
          "FAILED",
          "ERRORING",
          "STOPPED"
        ]
      },
      "FunctionVersionStatus": {
        "type": "string",
        "enum": [
          "DEPLOYING",
          "LIVE",
          "REPLACED",
          "FAILED"
        ]
      },
      "InvoiceStatus": {
        "type": "string",
        "enum": [
          "OPEN",
          "PAID",
          "VOID"
        ]
      },
      "LogLevel": {
        "type": "string",
        "enum": [
          "INFO",
          "WARN",
          "ERROR"
        ]
      },
      "LogStream": {
        "type": "string",
        "enum": [
          "STDOUT",
          "STDERR",
          "SYSTEM"
        ]
      },
      "MailDomainStatus": {
        "type": "string",
        "enum": [
          "BROKEN",
          "PENDING",
          "SUSPENDED",
          "VERIFIED"
        ]
      },
      "MailKeyScope": {
        "type": "string",
        "enum": [
          "FULL",
          "SEND"
        ]
      },
      "MetricRange": {
        "type": "string",
        "enum": [
          "LAST_30_MIN",
          "LAST_HOUR",
          "LAST_6H",
          "LAST_24H",
          "LAST_7D",
          "LAST_30D"
        ]
      },
      "MonorepoStrategy": {
        "type": "string",
        "enum": [
          "ISOLATED",
          "WORKSPACE"
        ]
      },
      "NameserverMode": {
        "type": "string",
        "enum": [
          "CUSTOM",
          "NC"
        ]
      },
      "PrPreviewStatus": {
        "type": "string",
        "enum": [
          "ACTIVE",
          "CLOSED",
          "CREATING",
          "FAILED",
          "UPDATING"
        ]
      },
      "RegisteredDomainStatus": {
        "type": "string",
        "enum": [
          "ACTIVE",
          "DELETED",
          "EXPIRING",
          "FAILED",
          "GRACE",
          "PENDING_PAYMENT",
          "REDEMPTION",
          "REGISTERING"
        ]
      },
      "RepoScanStatus": {
        "type": "string",
        "enum": [
          "OK",
          "RATE_LIMITED",
          "NOT_FOUND",
          "NOT_GITHUB",
          "FAILED"
        ],
        "description": "Why a scan came back empty, when it did."
      },
      "RestoreStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "RUNNING",
          "COMPLETED",
          "FAILED"
        ]
      },
      "Role": {
        "type": "string",
        "enum": [
          "ADMIN",
          "MEMBER",
          "OWNER"
        ]
      },
      "ServiceHealth": {
        "type": "string",
        "enum": [
          "HEALTHY",
          "CRASH_LOOPING",
          "STOPPED",
          "MISSING",
          "UNKNOWN"
        ]
      },
      "ServiceStatus": {
        "type": "string",
        "enum": [
          "PROVISIONING",
          "ACTIVE",
          "ERROR"
        ]
      },
      "ServiceSuspension": {
        "type": "string",
        "enum": [
          "NONE",
          "USER",
          "BILLING",
          "ABUSE"
        ],
        "description": "Why nothing is running, if anything: NONE, USER (suspended by a person), BILLING or ABUSE."
      },
      "ServiceTier": {
        "type": "string",
        "enum": [
          "FREE",
          "PRO",
          "STANDARD",
          "STARTER"
        ]
      },
      "ServiceType": {
        "type": "string",
        "enum": [
          "WEB",
          "STATIC",
          "CRON",
          "POSTGRES",
          "MYSQL",
          "MARIADB",
          "MONGODB",
          "REDIS",
          "VALKEY"
        ]
      },
      "SourceType": {
        "type": "string",
        "enum": [
          "GITHUB_APP",
          "PUBLIC_GIT",
          "DOCKER_IMAGE"
        ]
      },
      "TableExportFormat": {
        "type": "string",
        "enum": [
          "CSV",
          "JSON",
          "SQL"
        ]
      },
      "TeamPermission": {
        "type": "string",
        "enum": [
          "BILLING",
          "DATABASES",
          "DEPLOYS",
          "EMAIL",
          "STORAGE",
          "TEAM"
        ]
      },
      "UsageCategory": {
        "type": "string",
        "enum": [
          "ANALYTICS",
          "BANDWIDTH",
          "CACHE",
          "COMPUTE",
          "DATABASE",
          "EMAIL",
          "PREVIEW",
          "STORAGE"
        ]
      },
      "V1AddCustomDomainBody": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "example": "www.example.com"
          }
        },
        "required": [
          "domain"
        ]
      },
      "V1ApiToken": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "id": {
            "type": "string"
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiTokenScope"
            }
          },
          "teamId": {
            "type": "string",
            "nullable": true
          },
          "tokenHint": {
            "type": "string",
            "description": "The head of the key including its prefix, to identify it in a list."
          },
          "tokenTail": {
            "type": "string",
            "nullable": true,
            "description": "Last characters of the key, to identify it against a value stored in a .env file or a CI secret. Null for keys issued before this was recorded."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "createdAt",
          "expiresAt",
          "id",
          "lastUsedAt",
          "name",
          "revokedAt",
          "scopes",
          "teamId",
          "tokenHint",
          "tokenTail",
          "updatedAt"
        ]
      },
      "V1ApiTokenList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1ApiToken"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1ArgusPlanPrice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Plan id: free, pro or scale."
          },
          "label": {
            "type": "string",
            "description": "Plan name, e.g. Pro."
          },
          "monthlyKobo": {
            "type": "number",
            "description": "Monthly price in kobo. Accrues by the hour from the wallet (monthly ÷ 730), like a service."
          },
          "includedErrors": {
            "type": "number",
            "description": "Errors included each month before per-error pricing."
          }
        },
        "required": [
          "id",
          "label",
          "monthlyKobo",
          "includedErrors"
        ]
      },
      "V1Backup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BackupStatus"
              }
            ]
          },
          "trigger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BackupTrigger"
              }
            ]
          },
          "sizeBytes": {
            "type": "number",
            "nullable": true
          },
          "region": {
            "type": "string",
            "nullable": true,
            "description": "Storage region, e.g. \"eu\"."
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BackupFailureReason"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When retention deletes it."
          }
        },
        "required": [
          "id",
          "serviceId",
          "status",
          "trigger",
          "sizeBytes",
          "region",
          "error",
          "errorCode",
          "createdAt",
          "startedAt",
          "completedAt",
          "expiresAt"
        ]
      },
      "V1BackupList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Backup"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1Branch": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ]
      },
      "V1BranchList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Branch"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1BucketPolicy": {
        "type": "object",
        "properties": {
          "policy": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "policy"
        ]
      },
      "V1BucketPolicyBody": {
        "type": "object",
        "properties": {
          "policy": {
            "type": "string",
            "description": "An S3 bucket policy document, as JSON text."
          }
        },
        "required": [
          "policy"
        ]
      },
      "V1Column": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "nullable": {
            "type": "boolean"
          },
          "default": {
            "type": "string",
            "nullable": true
          },
          "isPrimaryKey": {
            "type": "boolean"
          },
          "references": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1ForeignKey"
              }
            ]
          }
        },
        "required": [
          "name",
          "type",
          "nullable",
          "default",
          "isPrimaryKey",
          "references"
        ]
      },
      "V1Connection": {
        "type": "object",
        "properties": {
          "scheme": {
            "type": "string",
            "example": "postgresql"
          },
          "host": {
            "type": "string",
            "description": "Host reachable from your other services."
          },
          "port": {
            "type": "number"
          },
          "database": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "password": {
            "type": "string",
            "description": "Empty for a read-only role: it may see where the database is, not log in."
          },
          "url": {
            "type": "string",
            "description": "Internal connection URL."
          },
          "externalUrl": {
            "type": "string",
            "nullable": true,
            "description": "Public URL, when external access is on."
          }
        },
        "required": [
          "scheme",
          "host",
          "port",
          "database",
          "username",
          "password",
          "url",
          "externalUrl"
        ]
      },
      "V1CorsRule": {
        "type": "object",
        "properties": {
          "allowedHeaders": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowedMethods": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowedOrigins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exposeHeaders": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "maxAgeSeconds": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "allowedHeaders",
          "allowedMethods",
          "allowedOrigins",
          "exposeHeaders",
          "maxAgeSeconds"
        ]
      },
      "V1CorsRuleInput": {
        "type": "object",
        "properties": {
          "allowedOrigins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowedMethods": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowedHeaders": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exposeHeaders": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "maxAgeSeconds": {
            "type": "integer"
          }
        },
        "required": [
          "allowedOrigins",
          "allowedMethods"
        ]
      },
      "V1CorsRuleList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CorsRule"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1CreateBucketBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "3–63 lowercase letters, digits, dots and hyphens; unique across Naijacloud."
          },
          "visibility": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BucketVisibility"
              }
            ]
          }
        },
        "required": [
          "name"
        ]
      },
      "V1CreateDnsZoneBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "acme.ng"
          }
        },
        "required": [
          "name"
        ]
      },
      "V1CreateEnvironmentBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "staging"
          }
        },
        "required": [
          "name"
        ]
      },
      "V1CreateMailDomainBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "mail.acme.ng"
          },
          "region": {
            "type": "string",
            "example": "eu-west"
          }
        },
        "required": [
          "name"
        ]
      },
      "V1CreateProjectBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "shop"
          },
          "displayName": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "region": {
            "type": "string",
            "example": "af-west",
            "description": "Region key. New services in the project are placed there unless they name another."
          }
        },
        "required": [
          "name"
        ]
      },
      "V1CreateServiceBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "api"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          },
          "region": {
            "type": "string",
            "example": "eu-west"
          },
          "tier": {
            "description": "Instance size. FREE uses the workspace free slot.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceTier"
              }
            ]
          },
          "sourceType": {
            "description": "Optional: inferred from image, gitUrl or repoFullName when omitted.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SourceType"
              }
            ]
          },
          "repoFullName": {
            "type": "string",
            "example": "acme/shop"
          },
          "gitUrl": {
            "type": "string",
            "example": "https://github.com/acme/shop"
          },
          "image": {
            "type": "string",
            "example": "ghcr.io/acme/api:1.2.3"
          },
          "imageCommand": {
            "type": "string"
          },
          "installationId": {
            "type": "string"
          },
          "branch": {
            "type": "string",
            "example": "main"
          },
          "rootDir": {
            "type": "string",
            "example": "apps/api"
          },
          "monorepoStrategy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MonorepoStrategy"
              }
            ]
          },
          "watchPaths": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "port": {
            "type": "number",
            "minimum": 1,
            "maximum": 65535
          },
          "healthCheckPath": {
            "type": "string",
            "example": "/healthz"
          },
          "buildCommand": {
            "type": "string"
          },
          "startCommand": {
            "type": "string"
          },
          "runtimeVersion": {
            "type": "string"
          },
          "staticOutputDir": {
            "type": "string",
            "example": "dist"
          },
          "staticSpa": {
            "type": "boolean"
          },
          "staticUploadId": {
            "type": "string"
          },
          "staticIndexPath": {
            "type": "string"
          },
          "subdomain": {
            "type": "string"
          },
          "schedule": {
            "type": "string",
            "description": "CRON only: a five-field cron expression, in UTC."
          },
          "command": {
            "type": "string",
            "description": "CRON only: the command each run executes."
          },
          "envVars": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1EnvVarInput"
            }
          },
          "secretFiles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1SecretFileInput"
            }
          },
          "dbName": {
            "type": "string"
          },
          "dbUser": {
            "type": "string"
          },
          "dbPassword": {
            "type": "string"
          },
          "connectionEnvName": {
            "type": "string"
          },
          "injectConnectionUrl": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "V1CreateStaticSiteBody": {
        "type": "object",
        "properties": {
          "indexPath": {
            "type": "string",
            "description": "The page to serve at \"/\" when it is not index.html."
          },
          "spaFallback": {
            "type": "boolean",
            "description": "Serve the index page for unknown paths (single-page apps)."
          },
          "uploadId": {
            "type": "string",
            "format": "uuid"
          },
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "description": "The environment to create the site in. Omitted, it lands in the workspace's static-sites project."
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "uploadId"
        ]
      },
      "V1CreditPlanPrice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Plan id: launch, production, growth or team."
          },
          "label": {
            "type": "string",
            "description": "Plan name, e.g. Production."
          },
          "monthlyKobo": {
            "type": "number",
            "description": "What the card is charged each month, in kobo. It all goes into the balance."
          },
          "bonusKobo": {
            "type": "number",
            "description": "Bonus credit added with each payment, in kobo (monthlyKobo × bonusPercent ÷ 100, rounded down)."
          },
          "spendKobo": {
            "type": "number",
            "description": "What the customer gets to spend each month, in kobo: monthlyKobo + bonusKobo."
          },
          "goodFor": {
            "type": "string",
            "description": "One line for the plan card: what it typically covers."
          }
        },
        "required": [
          "id",
          "label",
          "monthlyKobo",
          "bonusKobo",
          "spendKobo",
          "goodFor"
        ]
      },
      "V1CronRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "number",
            "nullable": true,
            "description": "Run number for this job, from 1."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CronRunStatus"
              }
            ]
          },
          "trigger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CronRunTrigger"
              }
            ]
          },
          "exitCode": {
            "type": "number",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "commitSha": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "serviceId",
          "seq",
          "status",
          "trigger",
          "exitCode",
          "error",
          "commitSha",
          "createdAt",
          "startedAt",
          "finishedAt"
        ]
      },
      "V1CronRunList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CronRun"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1CronRunLogLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "line": {
            "type": "string"
          },
          "stream": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CronLogStream"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "line",
          "stream",
          "createdAt"
        ]
      },
      "V1CronRunLogList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CronRunLogLine"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1CronSettings": {
        "type": "object",
        "properties": {
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "schedule": {
            "type": "string",
            "nullable": true,
            "example": "0 3 * * *"
          },
          "command": {
            "type": "string",
            "nullable": true
          },
          "suspended": {
            "type": "boolean",
            "description": "Scheduled runs are paused."
          }
        },
        "required": [
          "serviceId",
          "schedule",
          "command",
          "suspended"
        ]
      },
      "V1CustomDomain": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "domain": {
            "type": "string",
            "example": "www.example.com"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomDomainStatus"
              }
            ]
          },
          "lastCheck": {
            "type": "string",
            "nullable": true,
            "description": "What the last DNS check found."
          },
          "dnsTarget": {
            "$ref": "#/components/schemas/V1DnsTarget"
          },
          "verifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "ownershipVerifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When you proved you own the domain. Null until the ownership TXT record in dnsTarget.records is published; the domain does not route before then."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "serviceId",
          "domain",
          "status",
          "lastCheck",
          "dnsTarget",
          "verifiedAt",
          "ownershipVerifiedAt",
          "createdAt"
        ]
      },
      "V1CustomDomainList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CustomDomain"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DatabaseExportBody": {
        "type": "object",
        "properties": {
          "format": {
            "default": "SQL",
            "allOf": [
              {
                "$ref": "#/components/schemas/DatabaseExportFormat"
              }
            ]
          }
        }
      },
      "V1DatabaseObject": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "schema": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "table, view or collection"
          }
        },
        "required": [
          "name",
          "schema",
          "kind"
        ]
      },
      "V1DatabaseObjectList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DatabaseObject"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DatabaseQueryBody": {
        "type": "object",
        "properties": {
          "statement": {
            "type": "string",
            "description": "SQL (Postgres/MySQL/MariaDB) or a mongosh expression (MongoDB). Runs as the service's own database user, so it can write and drop as well as read."
          },
          "maxRows": {
            "type": "number",
            "minimum": 1,
            "maximum": 10000
          }
        },
        "required": [
          "statement"
        ]
      },
      "V1DatabaseStats": {
        "type": "object",
        "properties": {
          "cacheHitRatio": {
            "type": "number",
            "nullable": true
          },
          "connections": {
            "type": "integer",
            "nullable": true
          },
          "engine": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          },
          "itemCount": {
            "type": "number",
            "nullable": true
          },
          "itemLabel": {
            "type": "string",
            "nullable": true
          },
          "opsPerSec": {
            "type": "number",
            "nullable": true
          },
          "opsTotal": {
            "type": "number",
            "nullable": true
          },
          "storageBytes": {
            "type": "number",
            "nullable": true
          }
        },
        "required": [
          "cacheHitRatio",
          "connections",
          "engine",
          "itemCount",
          "itemLabel",
          "opsPerSec",
          "opsTotal",
          "storageBytes"
        ]
      },
      "V1Deploy": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeployStatus"
              }
            ]
          },
          "trigger": {
            "nullable": true,
            "description": "What started it: a push, a person, a rollback, …",
            "allOf": [
              {
                "$ref": "#/components/schemas/DeployTrigger"
              }
            ]
          },
          "branch": {
            "type": "string",
            "nullable": true
          },
          "commitSha": {
            "type": "string",
            "nullable": true
          },
          "commitMessage": {
            "type": "string",
            "nullable": true
          },
          "authorName": {
            "type": "string",
            "nullable": true
          },
          "buildCommand": {
            "type": "string",
            "nullable": true
          },
          "startCommand": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "Why it failed, written for you."
          },
          "errorCode": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/DeployErrorCode"
              }
            ]
          },
          "durationMs": {
            "type": "number",
            "nullable": true,
            "description": "From the start of work (not queueing) to the end, in ms."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "serviceId",
          "status",
          "trigger",
          "branch",
          "commitSha",
          "commitMessage",
          "authorName",
          "buildCommand",
          "startCommand",
          "error",
          "errorCode",
          "durationMs",
          "createdAt",
          "startedAt",
          "finishedAt"
        ]
      },
      "V1DeployFunctionBody": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "description": "Defaults to the project's production environment."
          },
          "name": {
            "type": "string",
            "example": "hello"
          },
          "uploadId": {
            "type": "string",
            "format": "uuid"
          },
          "entrypoint": {
            "type": "string",
            "example": "index.ts"
          },
          "command": {
            "type": "string",
            "description": "The command that deployed it, shown on the live version."
          },
          "tier": {
            "description": "Only used when this deploy creates the environment's functions runtime. Without it the runtime is Free while the workspace has its free runtime open.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceTier"
              }
            ]
          }
        },
        "required": [
          "projectId",
          "name",
          "uploadId"
        ]
      },
      "V1DeployFunctionResult": {
        "type": "object",
        "properties": {
          "function": {
            "$ref": "#/components/schemas/V1Function"
          },
          "version": {
            "$ref": "#/components/schemas/V1FunctionVersion"
          },
          "deploy": {
            "$ref": "#/components/schemas/V1Deploy"
          }
        },
        "required": [
          "function",
          "version",
          "deploy"
        ]
      },
      "V1DeployList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Deploy"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DeployLocation": {
        "type": "object",
        "properties": {
          "freeTier": {
            "type": "boolean",
            "description": "Whether a Free-size service can run in this region. Free services run only where the platform's free capacity is; pick a paid size elsewhere."
          },
          "isDefault": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          },
          "region": {
            "type": "string"
          }
        },
        "required": [
          "freeTier",
          "isDefault",
          "label",
          "region"
        ]
      },
      "V1DeployLocationList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DeployLocation"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DeployLogLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "line": {
            "type": "string"
          },
          "stream": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LogStream"
              }
            ]
          },
          "level": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LogLevel"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "line",
          "stream",
          "level",
          "createdAt"
        ]
      },
      "V1DeployLogList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DeployLogLine"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DetectedApp": {
        "type": "object",
        "properties": {
          "rootDir": {
            "type": "string",
            "description": "The folder, \".\" for the repo root."
          },
          "name": {
            "type": "string"
          },
          "deployable": {
            "type": "boolean"
          },
          "build": {
            "$ref": "#/components/schemas/V1DetectedBuild"
          }
        },
        "required": [
          "rootDir",
          "name",
          "deployable",
          "build"
        ]
      },
      "V1DetectedBuild": {
        "type": "object",
        "properties": {
          "runtime": {
            "type": "string",
            "nullable": true
          },
          "runtimeVersion": {
            "type": "string",
            "nullable": true
          },
          "framework": {
            "type": "string",
            "nullable": true
          },
          "packageManager": {
            "type": "string",
            "nullable": true
          },
          "buildCommand": {
            "type": "string",
            "nullable": true
          },
          "startCommand": {
            "type": "string",
            "nullable": true
          },
          "port": {
            "type": "number",
            "nullable": true
          },
          "staticOutputDir": {
            "type": "string",
            "nullable": true
          },
          "staticSpa": {
            "type": "boolean",
            "nullable": true
          },
          "monorepoStrategy": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/MonorepoStrategy"
              }
            ]
          },
          "workspaceName": {
            "type": "string",
            "nullable": true
          },
          "watchPaths": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "runtime",
          "runtimeVersion",
          "framework",
          "packageManager",
          "buildCommand",
          "startCommand",
          "port",
          "staticOutputDir",
          "staticSpa",
          "monorepoStrategy",
          "workspaceName",
          "watchPaths"
        ]
      },
      "V1DetectedRepoApps": {
        "type": "object",
        "properties": {
          "status": {
            "description": "Why a scan came back empty, when it did.",
            "allOf": [
              {
                "$ref": "#/components/schemas/RepoScanStatus"
              }
            ]
          },
          "workspace": {
            "type": "boolean",
            "description": "Whether the repo is a workspace monorepo."
          },
          "orchestrator": {
            "type": "string",
            "nullable": true
          },
          "truncated": {
            "type": "boolean"
          },
          "apps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DetectedApp"
            }
          }
        },
        "required": [
          "status",
          "workspace",
          "orchestrator",
          "truncated",
          "apps"
        ]
      },
      "V1DnsRecord": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "editable": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "origin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DnsRecordOrigin"
              }
            ]
          },
          "priority": {
            "type": "integer",
            "nullable": true
          },
          "ttl": {
            "type": "integer"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DnsRecordType"
              }
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "zoneId": {
            "type": "string"
          }
        },
        "required": [
          "content",
          "createdAt",
          "editable",
          "id",
          "name",
          "origin",
          "priority",
          "ttl",
          "type",
          "updatedAt",
          "zoneId"
        ]
      },
      "V1DnsRecordBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "\"@\" for the zone apex, or a label."
          },
          "type": {
            "type": "string",
            "description": "A, AAAA, CNAME, MX, TXT, …"
          },
          "content": {
            "type": "string"
          },
          "ttl": {
            "type": "integer",
            "minimum": 60,
            "maximum": 604800
          },
          "priority": {
            "type": "integer"
          }
        },
        "required": [
          "name",
          "type",
          "content"
        ]
      },
      "V1DnsRecordList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DnsRecord"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DnsTarget": {
        "type": "object",
        "properties": {
          "cname": {
            "type": "string",
            "description": "CNAME target for a subdomain."
          },
          "aRecord": {
            "type": "string",
            "nullable": true,
            "description": "A-record address, when an apex domain cannot use a CNAME."
          },
          "isApex": {
            "type": "boolean"
          },
          "records": {
            "description": "Records to create.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DnsRecord"
            }
          },
          "conflicts": {
            "description": "Existing records that block verification; remove them.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DnsRecord"
            }
          },
          "managedByNaijacloud": {
            "type": "boolean",
            "description": "True when the domain's DNS is on Naijacloud nameservers in this workspace. The records are then added for you; there is nothing to create."
          }
        },
        "required": [
          "cname",
          "aRecord",
          "isApex",
          "records",
          "conflicts",
          "managedByNaijacloud"
        ]
      },
      "V1DnsZone": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "published": {
            "type": "boolean"
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "teamId": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "verificationMethod": {
            "nullable": true,
            "description": "How ownership of the domain was proven; null while pending.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DnsZoneVerificationMethod"
              }
            ]
          },
          "verificationRecord": {
            "nullable": true,
            "description": "The TXT record that proves ownership while the zone is pending verification; null once ownership is proven.",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1DnsZoneVerificationRecord"
              }
            ]
          },
          "verifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When ownership of the domain was proven. Null while the zone is pending verification: it is not published and its name is not yet exclusively held."
          }
        },
        "required": [
          "createdAt",
          "id",
          "lastError",
          "name",
          "published",
          "publishedAt",
          "teamId",
          "updatedAt",
          "verificationMethod",
          "verificationRecord",
          "verifiedAt"
        ]
      },
      "V1DnsZoneList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DnsZone"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DnsZoneVerificationRecord": {
        "type": "object",
        "properties": {
          "host": {
            "type": "string",
            "description": "Record name relative to the domain, e.g. _naijacloud-verify"
          },
          "name": {
            "type": "string",
            "description": "Fully-qualified record name, e.g. _naijacloud-verify.example.com"
          },
          "type": {
            "type": "string",
            "description": "Always TXT."
          },
          "value": {
            "type": "string",
            "description": "The exact value the TXT record must hold."
          }
        },
        "required": [
          "host",
          "name",
          "type",
          "value"
        ]
      },
      "V1DomainCheckout": {
        "type": "object",
        "properties": {
          "amountKobo": {
            "type": "number",
            "description": "What they will be charged, in kobo"
          },
          "checkoutUrl": {
            "type": "string",
            "description": "The hosted payment page to send the customer to"
          },
          "reference": {
            "type": "string",
            "description": "Our reference for the order; echoed back on payment"
          }
        },
        "required": [
          "amountKobo",
          "checkoutUrl",
          "reference"
        ]
      },
      "V1DomainOrder": {
        "type": "object",
        "properties": {
          "amountKobo": {
            "type": "number"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "domain": {
            "type": "string"
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DomainOrderKind"
              }
            ]
          },
          "reference": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DomainOrderStatus"
              }
            ]
          },
          "teamId": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "years": {
            "type": "number"
          }
        },
        "required": [
          "amountKobo",
          "createdAt",
          "domain",
          "failureReason",
          "id",
          "kind",
          "reference",
          "status",
          "teamId",
          "updatedAt",
          "years"
        ]
      },
      "V1DomainOrderList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DomainOrder"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1DomainRenewalQuote": {
        "type": "object",
        "properties": {
          "amountKobo": {
            "type": "number",
            "description": "What the customer pays, in kobo. Firm — the checkout is created for exactly this amount."
          },
          "domain": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "The current expiry date, or null if we hold none"
          },
          "newExpiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "What the expiry becomes once paid. Extends the current date rather than restarting from today, so renewing early loses nothing."
          },
          "years": {
            "type": "integer",
            "description": "Years this quote covers"
          }
        },
        "required": [
          "amountKobo",
          "domain",
          "expiresAt",
          "newExpiresAt",
          "years"
        ]
      },
      "V1DomainSearchResults": {
        "type": "object",
        "properties": {
          "available": {
            "description": "What they asked for and can have, cheapest first",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DomainSearchRow"
            }
          },
          "availableCount": {
            "type": "integer",
            "description": "How many rows across all groups can be bought"
          },
          "query": {
            "type": "string",
            "description": "The bare name searched, after stripping any URL"
          },
          "suggestions": {
            "description": "Name variants they could have instead, cheapest first. Always available — a suggestion somebody else owns is not a suggestion.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DomainSearchRow"
            }
          },
          "unavailable": {
            "description": "What they cannot have, each row carrying its own reason. Returned rather than dropped: somebody who typed a .ng needs to see why.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DomainSearchRow"
            }
          }
        },
        "required": [
          "available",
          "availableCount",
          "query",
          "suggestions",
          "unavailable"
        ]
      },
      "V1DomainSearchRow": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Whether this domain can be bought here, right now"
          },
          "domain": {
            "type": "string"
          },
          "premium": {
            "type": "boolean",
            "description": "Premium names are priced individually by the registry and cost far more than the standard rate"
          },
          "priceKobo": {
            "type": "number",
            "nullable": true,
            "description": "What the customer pays, in kobo, for `years`. Firm, not an estimate — the checkout is created for exactly this amount, so the row, the payment page and the receipt agree. Null when it cannot be sold or cannot be priced right now."
          },
          "unavailableCode": {
            "nullable": true,
            "description": "The same answer as a code. Branch on this, not on the sentence — the sentence is copy and will be reworded, and \"somebody else has it\" and \"we cannot sell it yet\" are opposite answers that look alike.",
            "allOf": [
              {
                "$ref": "#/components/schemas/DomainUnavailableReason"
              }
            ]
          },
          "unavailableReason": {
            "type": "string",
            "nullable": true,
            "description": "Why it cannot be bought, in words meant for the customer"
          },
          "years": {
            "type": "integer",
            "description": "Years the price covers — some registries only allow one"
          }
        },
        "required": [
          "available",
          "domain",
          "premium",
          "priceKobo",
          "unavailableCode",
          "unavailableReason",
          "years"
        ]
      },
      "V1DomainSearchRowList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1DomainSearchRow"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1EnvVar": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "DATABASE_URL"
          },
          "value": {
            "type": "string",
            "description": "Blanked for read-only roles. Linked values are read-only."
          },
          "scope": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EnvVarScope"
              }
            ]
          },
          "secret": {
            "type": "boolean"
          },
          "linked": {
            "type": "boolean",
            "description": "Linked in from a sibling database's connection string; change it there."
          }
        },
        "required": [
          "key",
          "value",
          "scope",
          "secret",
          "linked"
        ]
      },
      "V1EnvVarChange": {
        "type": "object",
        "properties": {
          "envVars": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1EnvVar"
            }
          },
          "needsRedeploy": {
            "type": "boolean",
            "description": "True when a redeploy is needed for the change to apply."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "envVars",
          "needsRedeploy",
          "warnings"
        ]
      },
      "V1EnvVarInput": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "API_URL"
          },
          "value": {
            "type": "string"
          },
          "scope": {
            "description": "When the variable is available. Defaults to build and runtime.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EnvVarScope"
              }
            ]
          },
          "secret": {
            "type": "boolean"
          }
        },
        "required": [
          "key",
          "value"
        ]
      },
      "V1EnvVarList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1EnvVar"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1Environment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "production"
          },
          "isPreview": {
            "type": "boolean",
            "description": "True for a pull-request preview environment."
          },
          "paused": {
            "type": "boolean",
            "description": "True while this environment is paused on its own. A paused project stops it too without setting this."
          },
          "pausedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "projectId",
          "name",
          "isPreview",
          "paused",
          "pausedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "V1EnvironmentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "production"
          },
          "isPreview": {
            "type": "boolean",
            "description": "True for a pull-request preview environment."
          },
          "paused": {
            "type": "boolean",
            "description": "True while this environment is paused on its own. A paused project stops it too without setting this."
          },
          "pausedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "nullable": true,
            "description": "DEV, UAT or PROD when the name is exactly that tier (any case); null for a custom name such as \"staging\". The tier decides which scoped variables apply.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EnvironmentKind"
              }
            ]
          },
          "project": {
            "$ref": "#/components/schemas/V1EnvironmentProject"
          }
        },
        "required": [
          "id",
          "projectId",
          "name",
          "isPreview",
          "paused",
          "pausedAt",
          "createdAt",
          "updatedAt",
          "kind",
          "project"
        ]
      },
      "V1EnvironmentList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Environment"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1EnvironmentProject": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "workspaceId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "name"
        ]
      },
      "V1ErrorBody": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/V1ErrorDetail"
          }
        },
        "required": [
          "error"
        ]
      },
      "V1ErrorDetail": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "NOT_FOUND",
            "description": "Stable and derived from the status: BAD_REQUEST, UNAUTHENTICATED, PAYMENT_REQUIRED, FORBIDDEN, NOT_FOUND, CONFLICT, IDEMPOTENCY_KEY_REUSED, RATE_LIMITED, INTERNAL_SERVER_ERROR."
          },
          "message": {
            "type": "string",
            "description": "Written for you to read, or a generic sentence with a reference."
          },
          "requestId": {
            "type": "string",
            "description": "Equals the x-request-id response header. Quote it to support."
          }
        },
        "required": [
          "code",
          "message",
          "requestId"
        ]
      },
      "V1Export": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "A short-lived presigned download URL."
          },
          "filename": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "number",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "url",
          "filename",
          "format",
          "sizeBytes",
          "expiresAt"
        ]
      },
      "V1ForeignKey": {
        "type": "object",
        "properties": {
          "schema": {
            "type": "string",
            "nullable": true
          },
          "table": {
            "type": "string"
          },
          "column": {
            "type": "string"
          }
        },
        "required": [
          "schema",
          "table",
          "column"
        ]
      },
      "V1FreeAllowanceCard": {
        "type": "object",
        "properties": {
          "analyticsEvents": {
            "type": "number"
          },
          "egressBytes": {
            "type": "number"
          },
          "emailMessages": {
            "type": "number"
          },
          "monthlyCreditKobo": {
            "type": "number"
          },
          "previewFreeHours": {
            "type": "integer"
          },
          "previewRateMultiplier": {
            "type": "number"
          },
          "sessionReplays": {
            "type": "number"
          },
          "storageBytes": {
            "type": "number"
          }
        },
        "required": [
          "analyticsEvents",
          "egressBytes",
          "emailMessages",
          "monthlyCreditKobo",
          "previewFreeHours",
          "previewRateMultiplier",
          "sessionReplays",
          "storageBytes"
        ]
      },
      "V1Function": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "send-receipt"
          },
          "url": {
            "type": "string",
            "example": "https://shop-fn.naijacloud.app/functions/v1/send-receipt"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FunctionStatus"
              }
            ]
          },
          "statusDetail": {
            "type": "string",
            "nullable": true
          },
          "region": {
            "type": "string",
            "nullable": true,
            "example": "eu-west"
          },
          "tier": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceTier"
              }
            ]
          },
          "runtimeServiceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The hidden web service every function in the environment runs in."
          },
          "environmentId": {
            "type": "string",
            "format": "uuid"
          },
          "liveVersion": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1FunctionVersion"
              }
            ]
          },
          "latestVersion": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1FunctionVersion"
              }
            ]
          },
          "calls24h": {
            "type": "number",
            "nullable": true
          },
          "errors24h": {
            "type": "number",
            "nullable": true
          },
          "limits": {
            "$ref": "#/components/schemas/V1FunctionLimits"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "status",
          "statusDetail",
          "region",
          "tier",
          "runtimeServiceId",
          "environmentId",
          "liveVersion",
          "latestVersion",
          "calls24h",
          "errors24h",
          "limits",
          "createdAt",
          "updatedAt"
        ]
      },
      "V1FunctionLimits": {
        "type": "object",
        "properties": {
          "memoryMb": {
            "type": "number"
          },
          "maxDurationSeconds": {
            "type": "number",
            "description": "Longest one call may run before a 504."
          },
          "maxCodeBytes": {
            "type": "number",
            "description": "Largest upload per deploy, in bytes."
          }
        },
        "required": [
          "memoryMb",
          "maxDurationSeconds",
          "maxCodeBytes"
        ]
      },
      "V1FunctionList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Function"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1FunctionUploadBody": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "description": "Defaults to the project's production environment."
          },
          "name": {
            "type": "string",
            "example": "hello"
          },
          "sizeBytes": {
            "type": "number",
            "description": "Size of the zip in bytes.",
            "minimum": 1
          }
        },
        "required": [
          "projectId",
          "name",
          "sizeBytes"
        ]
      },
      "V1FunctionVersion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "number",
            "description": "From 1, per function."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FunctionVersionStatus"
              }
            ]
          },
          "sizeBytes": {
            "type": "number"
          },
          "entrypoint": {
            "type": "string",
            "example": "index.ts"
          },
          "command": {
            "type": "string",
            "nullable": true
          },
          "deployedByName": {
            "type": "string",
            "nullable": true
          },
          "deployId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The runtime deploy carrying it; its logs are the build log."
          },
          "errorMessage": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "number",
          "status",
          "sizeBytes",
          "entrypoint",
          "command",
          "deployedByName",
          "deployId",
          "errorMessage",
          "createdAt"
        ]
      },
      "V1GithubInstallUrl": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Open in a browser to install the Naijacloud GitHub App for this workspace."
          }
        },
        "required": [
          "url"
        ]
      },
      "V1Invite": {
        "type": "object",
        "properties": {
          "acceptedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "email": {
            "type": "string"
          },
          "expired": {
            "type": "boolean",
            "description": "True once the link has lapsed; it can still be resent."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "invitedByName": {
            "type": "string",
            "nullable": true,
            "description": "Who sent (or last resent) the invite, by name or email. Null once that person has left the workspace."
          },
          "projectIds": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Role"
              }
            ]
          },
          "roleName": {
            "type": "string",
            "nullable": true,
            "description": "The named workspace role the invite grants, or null when it grants only its rank."
          },
          "teamId": {
            "type": "string"
          },
          "teamRoleId": {
            "type": "string",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "acceptedAt",
          "createdAt",
          "email",
          "expired",
          "expiresAt",
          "id",
          "invitedByName",
          "projectIds",
          "role",
          "roleName",
          "teamId",
          "teamRoleId",
          "updatedAt"
        ]
      },
      "V1InviteList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Invite"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1InvoiceLineItemView": {
        "type": "object",
        "properties": {
          "amountKobo": {
            "type": "number"
          },
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageCategory"
              }
            ]
          },
          "description": {
            "type": "string"
          },
          "hours": {
            "type": "number"
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "amountKobo",
          "category",
          "description",
          "hours",
          "id"
        ]
      },
      "V1InvoiceList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1InvoiceView"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1InvoiceView": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "creditKobo": {
            "type": "number"
          },
          "debitedKobo": {
            "type": "number"
          },
          "id": {
            "type": "string"
          },
          "issuedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lineItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1InvoiceLineItemView"
            }
          },
          "number": {
            "type": "integer"
          },
          "periodEnd": {
            "type": "string",
            "format": "date-time"
          },
          "periodStart": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InvoiceStatus"
              }
            ]
          },
          "totalKobo": {
            "type": "number"
          },
          "unbilledKobo": {
            "type": "number"
          },
          "usageKobo": {
            "type": "number"
          }
        },
        "required": [
          "code",
          "creditKobo",
          "debitedKobo",
          "id",
          "issuedAt",
          "lineItems",
          "number",
          "periodEnd",
          "periodStart",
          "status",
          "totalKobo",
          "unbilledKobo",
          "usageKobo"
        ]
      },
      "V1LoginBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string"
          }
        },
        "required": [
          "email",
          "password"
        ]
      },
      "V1MailApiKey": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "isLive": {
            "type": "boolean"
          },
          "keyHint": {
            "type": "string",
            "description": "First characters of the key, to identify it in a list."
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "scope": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MailKeyScope"
              }
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "createdAt",
          "id",
          "isLive",
          "keyHint",
          "lastUsedAt",
          "name",
          "revokedAt",
          "scope",
          "updatedAt"
        ]
      },
      "V1MailApiKeyList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1MailApiKey"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1MailDnsRecord": {
        "type": "object",
        "properties": {
          "fqdn": {
            "type": "string",
            "description": "The full DNS name this record must exist at, e.g. nm._domainkey.send.acme.com."
          },
          "host": {
            "type": "string",
            "description": "Host relative to the sending domain; \"@\" is the sending domain itself."
          },
          "name": {
            "type": "string"
          },
          "priority": {
            "type": "number",
            "nullable": true
          },
          "problem": {
            "type": "string",
            "nullable": true
          },
          "required": {
            "type": "boolean"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "verified": {
            "type": "boolean"
          },
          "zoneHost": {
            "type": "string",
            "nullable": true,
            "description": "Host relative to the DNS zone the customer edits (MailDomainDetail.zone); \"@\" is the zone root."
          }
        },
        "required": [
          "fqdn",
          "host",
          "name",
          "priority",
          "problem",
          "required",
          "type",
          "value",
          "verified",
          "zoneHost"
        ]
      },
      "V1MailDnsZone": {
        "type": "object",
        "properties": {
          "dnsZoneId": {
            "type": "string",
            "nullable": true,
            "description": "The Naijacloud DNS zone id, when hostedOnNaijacloud."
          },
          "hostedOnNaijacloud": {
            "type": "boolean",
            "description": "True when this zone is on Naijacloud DNS in the same workspace, so publishMailDomainRecords can add the records in one step."
          },
          "name": {
            "type": "string",
            "description": "The zone the records are added to, e.g. acme.com for send.acme.com. zoneHost on each record is relative to it."
          }
        },
        "required": [
          "dnsZoneId",
          "hostedOnNaijacloud",
          "name"
        ]
      },
      "V1MailDomain": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "dailyQuota": {
            "type": "integer"
          },
          "dkimPublicKey": {
            "type": "string"
          },
          "failingRecords": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "id": {
            "type": "string"
          },
          "lastCheckedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MailDomainStatus"
              }
            ]
          },
          "suspendedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "suspendedReason": {
            "type": "string",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "verifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "createdAt",
          "dailyQuota",
          "dkimPublicKey",
          "failingRecords",
          "id",
          "lastCheckedAt",
          "name",
          "region",
          "status",
          "suspendedAt",
          "suspendedReason",
          "updatedAt",
          "verifiedAt"
        ]
      },
      "V1MailDomainDetail": {
        "type": "object",
        "properties": {
          "alignmentWarning": {
            "type": "string",
            "nullable": true,
            "description": "Set when the customer DMARC policy would break signing."
          },
          "domain": {
            "$ref": "#/components/schemas/V1MailDomain"
          },
          "propagating": {
            "type": "boolean",
            "nullable": true,
            "description": "Set when DNS is right but not yet propagated."
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1MailDnsRecord"
            }
          },
          "zone": {
            "nullable": true,
            "description": "The DNS zone the records go into; each record carries zoneHost relative to it.",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1MailDnsZone"
              }
            ]
          }
        },
        "required": [
          "alignmentWarning",
          "domain",
          "propagating",
          "records",
          "zone"
        ]
      },
      "V1MailDomainList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1MailDomain"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1Me": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "emailVerifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the email address was confirmed; null until then."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "email",
          "firstName",
          "lastName",
          "emailVerifiedAt",
          "createdAt"
        ]
      },
      "V1Member": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user": {
            "$ref": "#/components/schemas/V1MemberUser"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkspaceRole"
              }
            ]
          },
          "teamRoleId": {
            "type": "string",
            "nullable": true,
            "description": "The named workspace role, when one is set."
          },
          "projectIds": {
            "nullable": true,
            "description": "The projects a project-scoped member may reach.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "user",
          "role",
          "teamRoleId",
          "projectIds",
          "createdAt"
        ]
      },
      "V1MemberList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Member"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1MemberUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "email",
          "firstName",
          "lastName"
        ]
      },
      "V1MetricPoint": {
        "type": "object",
        "properties": {
          "blockReadBytesPerSec": {
            "type": "number"
          },
          "blockWriteBytesPerSec": {
            "type": "number"
          },
          "cacheHitRatio": {
            "type": "number",
            "nullable": true
          },
          "connections": {
            "type": "integer",
            "nullable": true
          },
          "cpuPercent": {
            "type": "number"
          },
          "memoryBytes": {
            "type": "number"
          },
          "memoryLimitBytes": {
            "type": "number"
          },
          "memoryPercent": {
            "type": "number"
          },
          "networkRxBytesPerSec": {
            "type": "number"
          },
          "networkTxBytesPerSec": {
            "type": "number"
          },
          "opsPerSec": {
            "type": "number",
            "nullable": true
          },
          "storageBytes": {
            "type": "number",
            "nullable": true
          },
          "t": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "blockReadBytesPerSec",
          "blockWriteBytesPerSec",
          "cacheHitRatio",
          "connections",
          "cpuPercent",
          "memoryBytes",
          "memoryLimitBytes",
          "memoryPercent",
          "networkRxBytesPerSec",
          "networkTxBytesPerSec",
          "opsPerSec",
          "storageBytes",
          "t"
        ]
      },
      "V1MetricSeries": {
        "type": "object",
        "properties": {
          "bucketSeconds": {
            "type": "integer"
          },
          "points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1MetricPoint"
            }
          },
          "range": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MetricRange"
              }
            ]
          },
          "serviceId": {
            "type": "string"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          }
        },
        "required": [
          "bucketSeconds",
          "points",
          "range",
          "serviceId",
          "type"
        ]
      },
      "V1PrPreview": {
        "type": "object",
        "properties": {
          "authorLogin": {
            "type": "string",
            "nullable": true
          },
          "baseRef": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "environmentId": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "headRef": {
            "type": "string"
          },
          "headSha": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string"
          },
          "lastDeploymentId": {
            "type": "string",
            "nullable": true
          },
          "prNumber": {
            "type": "integer"
          },
          "previewPostgresServiceId": {
            "type": "string",
            "nullable": true
          },
          "previewWebServiceId": {
            "type": "string",
            "nullable": true
          },
          "projectId": {
            "type": "string"
          },
          "repoFullName": {
            "type": "string"
          },
          "sourceServiceId": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PrPreviewStatus"
              }
            ]
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "url": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "authorLogin",
          "baseRef",
          "createdAt",
          "environmentId",
          "error",
          "headRef",
          "headSha",
          "id",
          "lastDeploymentId",
          "prNumber",
          "previewPostgresServiceId",
          "previewWebServiceId",
          "projectId",
          "repoFullName",
          "sourceServiceId",
          "status",
          "title",
          "updatedAt",
          "url"
        ]
      },
      "V1PrPreviewList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1PrPreview"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1PreviewsSettingBody": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Open a preview environment for every pull request."
          }
        },
        "required": [
          "enabled"
        ]
      },
      "V1PricingCatalog": {
        "type": "object",
        "properties": {
          "computeGraceDays": {
            "type": "integer",
            "description": "Days a workspace may sit at an empty balance before its paid apps (web services and cron jobs) are stopped."
          },
          "currency": {
            "type": "string"
          },
          "dataGraceDays": {
            "type": "integer",
            "description": "Days a workspace may sit at an empty balance before its paid databases and caches are stopped. Their data is kept."
          },
          "freeAllowances": {
            "$ref": "#/components/schemas/V1FreeAllowanceCard"
          },
          "maxTopUpKobo": {
            "type": "number",
            "nullable": true,
            "description": "The largest single wallet top-up accepted, in kobo. Null when there is no maximum."
          },
          "minTopUpKobo": {
            "type": "number",
            "description": "The smallest single wallet top-up accepted, in kobo. Shown on the Add funds sheet before anyone types."
          },
          "neverBilled": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "serviceTiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1ServiceTierPrice"
            }
          },
          "stopsPaidServices": {
            "type": "boolean",
            "description": "Whether an empty balance stops paid apps and databases after the grace periods. False while only preview environments are stopped."
          },
          "regionMultipliers": {
            "description": "Price multiplier per region for newly created services.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1RegionPriceMultiplier"
            }
          },
          "topUpBonusCapKobo": {
            "type": "number",
            "description": "The most top-up bonus one workspace can receive in any rolling 12 months, in kobo."
          },
          "topUpBonusTiers": {
            "description": "Extra credit on a single large top-up, highest tier first. Credited as its own ledger entry once the payment settles.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1TopUpBonusTier"
            }
          },
          "unitRates": {
            "$ref": "#/components/schemas/V1UnitRateCard"
          },
          "usdReferenceRate": {
            "type": "number",
            "description": "Naira per US dollar used only to convert competitor prices for comparison. Never used to bill."
          },
          "argusPlans": {
            "description": "Argus plans, cheapest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1ArgusPlanPrice"
            }
          },
          "argusPlansBilled": {
            "type": "boolean",
            "description": "Whether choosing a paid Argus plan charges the wallet today. False until Argus plan billing is switched on."
          },
          "creditPlans": {
            "description": "Monthly credit plans, cheapest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CreditPlanPrice"
            }
          },
          "creditPlanBonusPercent": {
            "type": "number",
            "description": "The bonus percent on every credit-plan payment. Never stacks with the top-up bonus."
          },
          "creditPlansEnabled": {
            "type": "boolean",
            "description": "Whether monthly credit plans can be bought today. False until they are switched on."
          }
        },
        "required": [
          "computeGraceDays",
          "currency",
          "dataGraceDays",
          "freeAllowances",
          "maxTopUpKobo",
          "minTopUpKobo",
          "neverBilled",
          "serviceTiers",
          "stopsPaidServices",
          "regionMultipliers",
          "topUpBonusCapKobo",
          "topUpBonusTiers",
          "unitRates",
          "usdReferenceRate",
          "argusPlans",
          "argusPlansBilled",
          "creditPlans",
          "creditPlanBonusPercent",
          "creditPlansEnabled"
        ]
      },
      "V1Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "workspaceId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "shop"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "defaultRegion": {
            "type": "string",
            "nullable": true,
            "description": "Region new services in this project are placed in, e.g. \"af-west\"."
          },
          "paused": {
            "type": "boolean"
          },
          "pausedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "environments": {
            "description": "Included when one project is fetched; omitted from lists.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Environment"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "name",
          "displayName",
          "description",
          "defaultRegion",
          "paused",
          "pausedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "V1ProjectList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Project"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1ProjectUsage": {
        "type": "object",
        "properties": {
          "avgCpuPercent": {
            "type": "number"
          },
          "projectId": {
            "type": "string"
          },
          "serviceCount": {
            "type": "integer"
          },
          "services": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1ServiceUsage"
            }
          },
          "totalMemoryBytes": {
            "type": "number"
          },
          "totalStorageBytes": {
            "type": "number"
          }
        },
        "required": [
          "avgCpuPercent",
          "projectId",
          "serviceCount",
          "services",
          "totalMemoryBytes",
          "totalStorageBytes"
        ]
      },
      "V1PurchaseDomainBody": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "example": "acme.com.ng"
          },
          "years": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 1
          },
          "contact": {
            "type": "object",
            "additionalProperties": true,
            "description": "The registrant: the same contact fields as the dashboard checkout. The price is never taken from the request."
          }
        },
        "required": [
          "domain",
          "years",
          "contact"
        ]
      },
      "V1QueryResult": {
        "type": "object",
        "properties": {
          "engine": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rows": {
            "type": "array",
            "description": "One array per row, cells in column order; null is SQL NULL.",
            "items": {
              "type": "array",
              "items": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "rowCount": {
            "type": "number"
          },
          "truncated": {
            "type": "boolean",
            "description": "More rows matched than were returned."
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "notices": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "executionMs": {
            "type": "number"
          }
        },
        "required": [
          "engine",
          "columns",
          "rows",
          "rowCount",
          "truncated",
          "message",
          "notices",
          "executionMs"
        ]
      },
      "V1RedeployStaticSiteBody": {
        "type": "object",
        "properties": {
          "indexPath": {
            "type": "string",
            "description": "The page to serve at \"/\" when it is not index.html."
          },
          "spaFallback": {
            "type": "boolean",
            "description": "Serve the index page for unknown paths (single-page apps)."
          },
          "uploadId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "uploadId"
        ]
      },
      "V1Region": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "eu-west"
          },
          "label": {
            "type": "string",
            "example": "Europe"
          }
        },
        "required": [
          "key",
          "label"
        ]
      },
      "V1RegionPriceMultiplier": {
        "type": "object",
        "properties": {
          "multiplier": {
            "type": "number",
            "description": "Applied to app and database prices for services created in this region today. eu-west is the base, 1.0."
          },
          "region": {
            "type": "string",
            "description": "Region id, e.g. af-west."
          }
        },
        "required": [
          "multiplier",
          "region"
        ]
      },
      "V1RegisteredDomain": {
        "type": "object",
        "properties": {
          "autoRenew": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "customNameservers": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "domain": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "id": {
            "type": "string"
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "nameserverMode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NameserverMode"
              }
            ]
          },
          "registeredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "registrantVerifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RegisteredDomainStatus"
              }
            ]
          },
          "teamId": {
            "type": "string"
          },
          "tld": {
            "type": "string"
          },
          "transferLockUntil": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "autoRenew",
          "createdAt",
          "customNameservers",
          "domain",
          "expiresAt",
          "id",
          "lastError",
          "nameserverMode",
          "registeredAt",
          "registrantVerifiedAt",
          "status",
          "teamId",
          "tld",
          "transferLockUntil",
          "updatedAt"
        ]
      },
      "V1RegisteredDomainList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1RegisteredDomain"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1RenewDomainBody": {
        "type": "object",
        "properties": {
          "years": {
            "type": "number",
            "minimum": 1,
            "maximum": 10,
            "default": 1
          }
        }
      },
      "V1Repository": {
        "type": "object",
        "properties": {
          "fullName": {
            "type": "string",
            "description": "owner/name"
          },
          "private": {
            "type": "boolean"
          },
          "defaultBranch": {
            "type": "string"
          },
          "installationId": {
            "type": "string",
            "description": "Pass with repoFullName when creating a service."
          }
        },
        "required": [
          "fullName",
          "private",
          "defaultBranch",
          "installationId"
        ]
      },
      "V1RepositoryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Repository"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1Restore": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid"
          },
          "backupId": {
            "type": "string",
            "format": "uuid"
          },
          "safetyBackupId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The backup taken of the database just before restoring, to undo with."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RestoreStatus"
              }
            ]
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BackupFailureReason"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "serviceId",
          "backupId",
          "safetyBackupId",
          "status",
          "error",
          "errorCode",
          "createdAt",
          "startedAt",
          "completedAt"
        ]
      },
      "V1SecretFile": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "example": "config/credentials.json"
          },
          "content": {
            "type": "string",
            "description": "Blanked for read-only roles."
          }
        },
        "required": [
          "path",
          "content"
        ]
      },
      "V1SecretFileChange": {
        "type": "object",
        "properties": {
          "secretFiles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1SecretFile"
            }
          },
          "needsRedeploy": {
            "type": "boolean"
          }
        },
        "required": [
          "secretFiles",
          "needsRedeploy"
        ]
      },
      "V1SecretFileInput": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "example": "config/credentials.json"
          },
          "content": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "content"
        ]
      },
      "V1SecretFileList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1SecretFile"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1Service": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "environmentId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "api"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceStatus"
              }
            ]
          },
          "tier": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceTier"
              }
            ]
          },
          "url": {
            "type": "string",
            "nullable": true,
            "example": "https://api-shop.naijacloud.app",
            "description": "The platform URL. Null for databases and before placement."
          },
          "region": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1Region"
              }
            ]
          },
          "runtime": {
            "type": "string",
            "nullable": true,
            "example": "node"
          },
          "framework": {
            "type": "string",
            "nullable": true,
            "example": "nextjs"
          },
          "isStatic": {
            "type": "boolean"
          },
          "functionsRuntime": {
            "type": "boolean",
            "description": "True for a project environment's hidden functions runtime. Lists of services usually leave it out and show its functions instead."
          },
          "port": {
            "type": "number",
            "nullable": true
          },
          "healthCheckPath": {
            "type": "string",
            "nullable": true
          },
          "memoryMb": {
            "type": "number"
          },
          "cpuMillicores": {
            "type": "number"
          },
          "storageLimitMb": {
            "type": "number",
            "nullable": true
          },
          "source": {
            "$ref": "#/components/schemas/V1ServiceSource"
          },
          "build": {
            "$ref": "#/components/schemas/V1ServiceBuild"
          },
          "cron": {
            "nullable": true,
            "description": "Set for CRON services only.",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1ServiceCron"
              }
            ]
          },
          "suspension": {
            "description": "Why nothing is running, if anything: NONE, USER (suspended by a person), BILLING or ABUSE.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceSuspension"
              }
            ]
          },
          "health": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceHealth"
              }
            ]
          },
          "lastDeployedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "environmentId",
          "name",
          "type",
          "status",
          "tier",
          "url",
          "region",
          "runtime",
          "framework",
          "isStatic",
          "functionsRuntime",
          "port",
          "healthCheckPath",
          "memoryMb",
          "cpuMillicores",
          "storageLimitMb",
          "source",
          "build",
          "cron",
          "suspension",
          "health",
          "lastDeployedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "V1ServiceBuild": {
        "type": "object",
        "properties": {
          "buildCommand": {
            "type": "string",
            "nullable": true
          },
          "startCommand": {
            "type": "string",
            "nullable": true
          },
          "runtimeVersion": {
            "type": "string",
            "nullable": true,
            "example": "22"
          },
          "staticOutputDir": {
            "type": "string",
            "nullable": true
          },
          "staticSpa": {
            "type": "boolean"
          },
          "monorepoStrategy": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/MonorepoStrategy"
              }
            ]
          },
          "watchPaths": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "buildCommand",
          "startCommand",
          "runtimeVersion",
          "staticOutputDir",
          "staticSpa",
          "monorepoStrategy",
          "watchPaths"
        ]
      },
      "V1ServiceCron": {
        "type": "object",
        "properties": {
          "schedule": {
            "type": "string",
            "nullable": true,
            "example": "*/15 * * * *"
          },
          "command": {
            "type": "string",
            "nullable": true
          },
          "suspended": {
            "type": "boolean",
            "description": "Scheduled runs are paused."
          }
        },
        "required": [
          "schedule",
          "command",
          "suspended"
        ]
      },
      "V1ServiceList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Service"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1ServiceSource": {
        "type": "object",
        "properties": {
          "type": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/SourceType"
              }
            ]
          },
          "repoFullName": {
            "type": "string",
            "nullable": true,
            "example": "acme/shop"
          },
          "gitUrl": {
            "type": "string",
            "nullable": true
          },
          "branch": {
            "type": "string",
            "nullable": true
          },
          "rootDir": {
            "type": "string",
            "nullable": true
          },
          "image": {
            "type": "string",
            "nullable": true,
            "description": "The public image a DOCKER_IMAGE service runs."
          },
          "imageCommand": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "type",
          "repoFullName",
          "gitUrl",
          "branch",
          "rootDir",
          "image",
          "imageCommand"
        ]
      },
      "V1ServiceSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "projectName": {
            "type": "string"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "projectName",
          "type"
        ]
      },
      "V1ServiceSummaryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1ServiceSummary"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1ServiceTierPrice": {
        "type": "object",
        "properties": {
          "cpuMillicores": {
            "type": "integer"
          },
          "currency": {
            "type": "string"
          },
          "family": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "memoryMb": {
            "type": "integer"
          },
          "priceKobo": {
            "type": "number"
          },
          "storageMb": {
            "type": "integer",
            "nullable": true
          },
          "tier": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceTier"
              }
            ]
          }
        },
        "required": [
          "cpuMillicores",
          "currency",
          "family",
          "label",
          "memoryMb",
          "priceKobo",
          "storageMb",
          "tier"
        ]
      },
      "V1ServiceUsage": {
        "type": "object",
        "properties": {
          "cpuPercent": {
            "type": "number"
          },
          "database": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1DatabaseStats"
              }
            ]
          },
          "hasData": {
            "type": "boolean"
          },
          "memoryBytes": {
            "type": "number"
          },
          "memoryLimitBytes": {
            "type": "number"
          },
          "memoryPercent": {
            "type": "number"
          },
          "networkRxBytesPerSec": {
            "type": "number"
          },
          "networkTxBytesPerSec": {
            "type": "number"
          },
          "sampledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "serviceId": {
            "type": "string"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceType"
              }
            ]
          }
        },
        "required": [
          "cpuPercent",
          "database",
          "hasData",
          "memoryBytes",
          "memoryLimitBytes",
          "memoryPercent",
          "networkRxBytesPerSec",
          "networkTxBytesPerSec",
          "sampledAt",
          "serviceId",
          "type"
        ]
      },
      "V1Session": {
        "type": "object",
        "properties": {
          "accessToken": {
            "type": "string",
            "nullable": true
          },
          "user": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1Me"
              }
            ]
          },
          "twoFactor": {
            "nullable": true,
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/V1TwoFactorChallenge"
              }
            ]
          }
        },
        "required": [
          "accessToken",
          "user",
          "twoFactor"
        ]
      },
      "V1SetEnvVarsBody": {
        "type": "object",
        "properties": {
          "envVars": {
            "description": "Created or replaced by key. Keys not listed are kept.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1EnvVarInput"
            }
          }
        },
        "required": [
          "envVars"
        ]
      },
      "V1StaticSite": {
        "type": "object",
        "properties": {
          "site": {
            "$ref": "#/components/schemas/V1Service"
          },
          "deploy": {
            "$ref": "#/components/schemas/V1Deploy"
          }
        },
        "required": [
          "site",
          "deploy"
        ]
      },
      "V1StaticUpload": {
        "type": "object",
        "properties": {
          "uploadId": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "A presigned URL; it expires."
          },
          "method": {
            "type": "string",
            "example": "PUT"
          },
          "headers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1UploadHeader"
            }
          },
          "maxBytes": {
            "type": "number"
          },
          "expiresInSeconds": {
            "type": "number"
          }
        },
        "required": [
          "uploadId",
          "url",
          "method",
          "headers",
          "maxBytes",
          "expiresInSeconds"
        ]
      },
      "V1StaticUploadBody": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string",
            "description": "e.g. \"site.zip\" or \"index.html\"."
          },
          "contentType": {
            "type": "string",
            "description": "e.g. \"application/zip\" or \"text/html\"."
          },
          "sizeBytes": {
            "type": "number",
            "minimum": 1
          }
        },
        "required": [
          "filename",
          "contentType",
          "sizeBytes"
        ]
      },
      "V1StorageAccessKey": {
        "type": "object",
        "properties": {
          "accessKeyId": {
            "type": "string",
            "description": "The S3 access key ID. Safe to show."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "What the key is for, e.g. \"storefront uploads\"."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "accessKeyId",
          "createdAt",
          "id",
          "name",
          "updatedAt"
        ]
      },
      "V1StorageAccessKeyList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1StorageAccessKey"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1StorageBucket": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "nullable": true
          },
          "endpoint": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "publicBaseUrl": {
            "type": "string",
            "nullable": true
          },
          "region": {
            "type": "string"
          },
          "visibility": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BucketVisibility"
              }
            ]
          }
        },
        "required": [
          "createdAt",
          "endpoint",
          "name",
          "publicBaseUrl",
          "region",
          "visibility"
        ]
      },
      "V1StorageBucketList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1StorageBucket"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1TableExportBody": {
        "type": "object",
        "properties": {
          "format": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TableExportFormat"
              }
            ]
          },
          "schema": {
            "type": "string",
            "description": "Postgres schema, if not public."
          }
        }
      },
      "V1TableSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "schema": {
            "type": "string",
            "nullable": true
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Column"
            }
          },
          "primaryKey": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "schema",
          "columns",
          "primaryKey"
        ]
      },
      "V1TableStat": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "schema": {
            "type": "string",
            "nullable": true
          },
          "estimatedRows": {
            "type": "number",
            "nullable": true,
            "description": "The planner's estimate, never a live count."
          }
        },
        "required": [
          "name",
          "schema",
          "estimatedRows"
        ]
      },
      "V1TableStatList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1TableStat"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1TeamRole": {
        "type": "object",
        "properties": {
          "allProjects": {
            "type": "boolean"
          },
          "builtin": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "description": {
            "type": "string"
          },
          "editable": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "permissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamPermission"
            }
          },
          "projectIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "readOnly": {
            "type": "boolean"
          },
          "teamId": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "allProjects",
          "builtin",
          "createdAt",
          "description",
          "editable",
          "id",
          "name",
          "permissions",
          "projectIds",
          "readOnly",
          "teamId",
          "updatedAt"
        ]
      },
      "V1TeamRoleList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1TeamRoleRow"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1TeamRoleRow": {
        "type": "object",
        "properties": {
          "memberCount": {
            "type": "integer"
          },
          "role": {
            "$ref": "#/components/schemas/V1TeamRole"
          },
          "scopedProjectIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "memberCount",
          "role",
          "scopedProjectIds"
        ]
      },
      "V1TopUpBonusTier": {
        "type": "object",
        "properties": {
          "minTopUpKobo": {
            "type": "number",
            "description": "The smallest single top-up that earns this tier, in kobo."
          },
          "percent": {
            "type": "number",
            "description": "Extra credit, as a percent of what the top-up paid in."
          }
        },
        "required": [
          "minTopUpKobo",
          "percent"
        ]
      },
      "V1TwoFactorBody": {
        "type": "object",
        "properties": {
          "pendingToken": {
            "type": "string",
            "description": "The `pendingToken` the sign-in returned."
          },
          "code": {
            "type": "string",
            "description": "A 6-digit authenticator code, or a one-time recovery code."
          }
        },
        "required": [
          "pendingToken",
          "code"
        ]
      },
      "V1TwoFactorChallenge": {
        "type": "object",
        "properties": {
          "pendingToken": {
            "type": "string",
            "description": "Send to POST /v1/auth/two-factor with a code."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "pendingToken",
          "expiresAt"
        ]
      },
      "V1UnitRateCard": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string"
          },
          "dbDiskKoboPerGbMonth": {
            "type": "number"
          },
          "egressKoboPerGb": {
            "type": "number"
          },
          "emailKoboPerMessage": {
            "type": "number"
          },
          "memoryKoboPerGbMonth": {
            "type": "number"
          },
          "objectStorageKoboPerGbMonth": {
            "type": "number"
          },
          "vcpuKoboPerVcpuMonth": {
            "type": "number"
          }
        },
        "required": [
          "currency",
          "dbDiskKoboPerGbMonth",
          "egressKoboPerGb",
          "emailKoboPerMessage",
          "memoryKoboPerGbMonth",
          "objectStorageKoboPerGbMonth",
          "vcpuKoboPerVcpuMonth"
        ]
      },
      "V1UpdateCronBody": {
        "type": "object",
        "properties": {
          "schedule": {
            "type": "string",
            "example": "0 3 * * *",
            "description": "Five-field cron expression, in UTC."
          },
          "command": {
            "type": "string",
            "description": "The command each run executes."
          }
        }
      },
      "V1UpdateDomainBody": {
        "type": "object",
        "properties": {
          "autoRenew": {
            "type": "boolean"
          },
          "nameserverMode": {
            "description": "Use our nameservers, or your own (then `nameservers`).",
            "allOf": [
              {
                "$ref": "#/components/schemas/NameserverMode"
              }
            ]
          },
          "nameservers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "V1UpdateProjectBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "V1UpdateServiceBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "A label only."
          },
          "build": {
            "$ref": "#/components/schemas/V1UpdateServiceBuild"
          },
          "source": {
            "$ref": "#/components/schemas/V1UpdateServiceSource"
          }
        }
      },
      "V1UpdateServiceBuild": {
        "type": "object",
        "properties": {
          "buildCommand": {
            "type": "string"
          },
          "startCommand": {
            "type": "string"
          },
          "runtimeVersion": {
            "type": "string"
          },
          "rootDir": {
            "type": "string"
          },
          "port": {
            "type": "number"
          },
          "healthCheckPath": {
            "type": "string"
          },
          "monorepoStrategy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MonorepoStrategy"
              }
            ]
          },
          "staticOutputDir": {
            "type": "string"
          },
          "staticSpa": {
            "type": "boolean"
          },
          "watchPaths": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "V1UpdateServiceSource": {
        "type": "object",
        "properties": {
          "sourceType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SourceType"
              }
            ]
          },
          "repoFullName": {
            "type": "string"
          },
          "installationId": {
            "type": "string"
          },
          "gitUrl": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "image": {
            "type": "string"
          },
          "imageCommand": {
            "type": "string"
          },
          "redeploy": {
            "type": "boolean",
            "description": "Deploy from the new source straight away."
          }
        }
      },
      "V1UploadHeader": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ]
      },
      "V1WalletBalance": {
        "type": "object",
        "properties": {
          "balanceMinor": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "low": {
            "type": "boolean"
          },
          "lowBalanceThresholdMinor": {
            "type": "number"
          }
        },
        "required": [
          "balanceMinor",
          "currency",
          "low",
          "lowBalanceThresholdMinor"
        ]
      },
      "V1Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "defaultRegion": {
            "type": "string",
            "nullable": true,
            "description": "Region new projects are placed in, e.g. \"eu-west\"."
          },
          "role": {
            "nullable": true,
            "description": "The caller's role in this workspace.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkspaceRole"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "defaultRegion",
          "role",
          "createdAt",
          "updatedAt"
        ]
      },
      "V1WorkspaceList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1Workspace"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "description": "Pass as `cursor` to get the next page; null on the last."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ]
      },
      "V1WorkspaceUsageMeters": {
        "type": "object",
        "properties": {
          "bandwidthAllowanceBytes": {
            "type": "number",
            "nullable": true
          },
          "bandwidthBytes": {
            "type": "number",
            "nullable": true
          },
          "computeAllowanceHours": {
            "type": "number",
            "nullable": true
          },
          "computeHours": {
            "type": "number"
          },
          "databaseAllowanceBytes": {
            "type": "number",
            "nullable": true
          },
          "databaseBytes": {
            "type": "number"
          },
          "storageAllowanceBytes": {
            "type": "number",
            "nullable": true
          },
          "storageBytes": {
            "type": "number"
          }
        },
        "required": [
          "bandwidthAllowanceBytes",
          "bandwidthBytes",
          "computeAllowanceHours",
          "computeHours",
          "databaseAllowanceBytes",
          "databaseBytes",
          "storageAllowanceBytes",
          "storageBytes"
        ]
      },
      "WorkspaceRole": {
        "type": "string",
        "enum": [
          "OWNER",
          "ADMIN",
          "MEMBER"
        ]
      }
    }
  }
}
