{"openapi": "3.1.0", "info": {"title": "JetDeploy API", "version": "1", "description": "The JetDeploy JSON API. Authenticate every request with the header `Authorization: Bearer <API token>`, where the token is the API token of your user, shown in the console under Integrations > API Access Token; requests without a valid token are refused with 401, and every token is rate limited per minute."}, "paths": {"/api/v1/me": {"get": {"operationId": "get_me", "summary": "The user the token belongs to", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["organizations"], "security": [{"BearerAuth": []}]}}, "/api/v1/organizations": {"get": {"operationId": "list_organizations", "summary": "The organizations the user belongs to", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/OrganizationSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["organizations"], "security": [{"BearerAuth": []}]}}, "/api/v1/organizations/{organization_id}": {"get": {"operationId": "get_organization", "summary": "One organization the user belongs to", "parameters": [{"in": "path", "name": "organization_id", "schema": {"title": "Organization Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OrganizationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["organizations"], "security": [{"BearerAuth": []}]}}, "/api/v1/organizations/{organization_id}/select": {"post": {"operationId": "select_organization", "summary": "Make an organization the current one of the user", "parameters": [{"in": "path", "name": "organization_id", "schema": {"title": "Organization Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OrganizationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Sets the organization every request without an explicit organization works on, exactly as the organization switcher of the console does. Only an organization the user belongs to can be selected.", "tags": ["organizations"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps": {"get": {"operationId": "list_apps", "summary": "The apps of an organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AppSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["apps"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_app", "summary": "Create an app", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AppDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Creates the app and its git repository. The app is not running yet: add a pod, set envs and the pre-deploy script if needed, then push to git_remote_url; the push deploys once the app has a pod; next_step says what is left.", "tags": ["apps"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AppCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}": {"get": {"operationId": "get_app", "summary": "One app with its pods, environment variables and domains", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AppDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["apps"], "security": [{"BearerAuth": []}]}, "patch": {"operationId": "update_app", "summary": "Change the pre-deploy script of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AppDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Only predeploy_script can change. The deploy branch is fixed when the app is created, so sending branch is refused with 400.", "tags": ["apps"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AppUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "delete": {"operationId": "destroy_app", "summary": "Destroy an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Queues the destroy of the app, its pods and its git repository.", "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/deploy": {"post": {"operationId": "deploy_app", "summary": "Deploy the latest push of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "A push to an app that already has a pod deploys by itself: call this only when the pod was added after the push, or to redeploy the same push again. A deploy already running is refused with 409 and code operation_pending.", "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/apply": {"post": {"operationId": "apply_app", "summary": "Apply the stored changes of an app to what is running", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Only an app that was already deployed can be applied: on a never deployed one this is refused with 409 and the app has to be deployed instead.", "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/restart": {"post": {"operationId": "restart_app", "summary": "Restart every pod of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/start": {"post": {"operationId": "start_app", "summary": "Start a stopped app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/stop": {"post": {"operationId": "stop_app", "summary": "Stop a running app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["apps"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods": {"get": {"operationId": "list_pods", "summary": "The pods of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PodSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_pod", "summary": "Add a pod to an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PodSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Every pod of an app runs the same code, from the same git repository, with a command of its own. The pod starts with the next deploy: on an app with no push yet the push itself starts it; otherwise call POST /apps/<id>/deploy, or POST /apps/<id>/apply on an app already deployed, or POST /apps/<id>/start on a stopped one.", "tags": ["pods"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PodCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods/{pod_id}": {"get": {"operationId": "get_pod", "summary": "One pod of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PodSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}, "patch": {"operationId": "update_pod", "summary": "Change a pod", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PodSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The name of a pod cannot change, exactly as in the console.", "tags": ["pods"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PodUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "delete": {"operationId": "destroy_pod", "summary": "Destroy a pod", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods/{pod_id}/restart": {"post": {"operationId": "restart_pod", "summary": "Restart one pod", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods/{pod_id}/start": {"post": {"operationId": "start_pod", "summary": "Start one stopped pod", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods/{pod_id}/stop": {"post": {"operationId": "stop_pod", "summary": "Stop one running pod", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["pods"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/envs": {"get": {"operationId": "list_envs", "summary": "The environment variables of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": {"type": "string"}, "title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Environment variables of the app as a key to value mapping. They reach the pods on the next apply, not before.", "tags": ["envs"], "security": [{"BearerAuth": []}]}, "put": {"operationId": "set_envs", "summary": "Replace every environment variable of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": {"type": "string"}, "title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The app ends up with exactly the variables you send: the ones you leave out are deleted. The new set reaches the pods on the next apply of the app.", "tags": ["envs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvsSetSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_env", "summary": "Add one environment variable to an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["envs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/envs/{key}": {"get": {"operationId": "get_env", "summary": "One environment variable of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "key", "schema": {"title": "Key", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["envs"], "security": [{"BearerAuth": []}]}, "patch": {"operationId": "update_env", "summary": "Change the value of one environment variable", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "key", "schema": {"title": "Key", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["envs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "delete": {"operationId": "delete_env", "summary": "Delete one environment variable", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "key", "schema": {"title": "Key", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The variable stays in the running pods until the next apply of the app.", "tags": ["envs"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/redirect-rules": {"get": {"operationId": "list_redirect_rules", "summary": "The redirect rules of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RedirectRuleSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["redirect-rules"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_redirect_rule", "summary": "Add a redirect rule to an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RedirectRuleSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["redirect-rules"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RedirectRuleCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/redirect-rules/{rule_id}": {"get": {"operationId": "get_redirect_rule", "summary": "One redirect rule of an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "rule_id", "schema": {"title": "Rule Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RedirectRuleSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["redirect-rules"], "security": [{"BearerAuth": []}]}, "patch": {"operationId": "update_redirect_rule", "summary": "Change a redirect rule", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "rule_id", "schema": {"title": "Rule Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RedirectRuleSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["redirect-rules"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RedirectRuleUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "delete": {"operationId": "delete_redirect_rule", "summary": "Delete a redirect rule", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "rule_id", "schema": {"title": "Rule Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The rule keeps redirecting until the next apply of the app.", "tags": ["redirect-rules"], "security": [{"BearerAuth": []}]}}, "/api/v1/domains": {"get": {"operationId": "list_domains", "summary": "The custom domains of an organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DomainSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["domains"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_domain", "summary": "Claim a custom domain", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The domain is not routed until it is validated: create the records in dns_target and verification_record, then call POST /api/v1/domains/<id>/validate.", "tags": ["domains"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/domains/{domain_id}": {"get": {"operationId": "get_domain", "summary": "One custom domain", "parameters": [{"in": "path", "name": "domain_id", "schema": {"title": "Domain Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["domains"], "security": [{"BearerAuth": []}]}, "patch": {"operationId": "update_domain", "summary": "Switch the routing mode of a domain", "parameters": [{"in": "path", "name": "domain_id", "schema": {"title": "Domain Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Only routing_mode can change, and the records the domain needs change with it: read dns_target and verification_record of the answer, then validate the domain again. Switching the mode of a validated domain makes it unvalidated: it is no longer served by the app from the next apply on, and it is removed after 7 days unless validated again (see expires_at). Its TLS certificate is kept, so validating again does not issue a new one.", "tags": ["domains"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "delete": {"operationId": "delete_domain", "summary": "Delete a custom domain", "parameters": [{"in": "path", "name": "domain_id", "schema": {"title": "Domain Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Deletes the domain and releases its TLS certificate. When it was attached to an app, apply the app for the change to take effect.", "tags": ["domains"], "security": [{"BearerAuth": []}]}}, "/api/v1/domains/{domain_id}/validate": {"post": {"operationId": "validate_domain", "summary": "Check the DNS records of a domain and validate it", "parameters": [{"in": "path", "name": "domain_id", "schema": {"title": "Domain Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "JetDeploy queries the authoritative nameservers of the domain. When the records are in place the domain becomes validated; otherwise the answer is 409 with the records to create in the hint. Apply the app the domain is attached to once it is validated.", "tags": ["domains"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/domains": {"post": {"operationId": "attach_domain", "summary": "Attach a domain to an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The app serves the domain once it is applied. Run POST /api/v1/apps/<id>/apply, or POST /api/v1/apps/<id>/start when the app is stopped, for the change to take effect", "tags": ["domains"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DomainAttachSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/domains/{domain_id}": {"delete": {"operationId": "detach_domain", "summary": "Detach a domain from an app", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "domain_id", "schema": {"title": "Domain Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The app stops serving the domain once it is applied. Run POST /api/v1/apps/<id>/apply, or POST /api/v1/apps/<id>/start when the app is stopped, for the change to take effect", "tags": ["domains"], "security": [{"BearerAuth": []}]}}, "/api/v1/services": {"get": {"operationId": "list_services", "summary": "The data services of an organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}, {"in": "query", "name": "kind", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Kind"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "create_service", "summary": "Create a data service and deploy it", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Creates the service on the newest catalog chart of the kind, stores its settings and queues the deploy in one call. It answers at once, in created status, with the credentials and the pending_operation of that deploy. The service accepts connections once GET /api/v1/services/<id> shows status ready; if pending_operation turns null while status is not ready, the deploy failed (deploy_failed is true): retry it with POST /api/v1/services/<id>/deploy.", "tags": ["services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceCreateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}": {"get": {"operationId": "get_service", "summary": "One data service with its endpoints and credentials", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceDetailSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}, "delete": {"operationId": "destroy_service", "summary": "Destroy a data service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Queues the destroy of the service and of its volume: the data is not recoverable.", "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/deploy": {"post": {"operationId": "deploy_service", "summary": "Retry the deploy of a service whose deploy failed", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/restart": {"post": {"operationId": "restart_service", "summary": "Restart a data service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/start": {"post": {"operationId": "start_service", "summary": "Start a stopped data service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/stop": {"post": {"operationId": "stop_service", "summary": "Stop a running data service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/expose": {"post": {"operationId": "expose_service", "summary": "Publish a data service outside the platform", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Only the listed addresses reach the exposed service. Read exposed_endpoint of GET /api/v1/services/<id> once the operation is finished.", "tags": ["services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceExposeSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/unexpose": {"post": {"operationId": "unexpose_service", "summary": "Withdraw a data service from outside the platform", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/apply": {"post": {"operationId": "apply_service", "summary": "Apply the stored changes of a service to what is running", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Reserved to the JetDeploy staff, as in the console.", "tags": ["services"], "security": [{"BearerAuth": []}]}}, "/api/v1/catalog/services": {"get": {"operationId": "list_catalog_services", "summary": "The data services that can be created, with the settings each one takes", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CatalogServiceSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "One row per engine, on the newest chart of the catalog. storage_size can also be sent at the top level of POST /api/v1/services; when this engine does not list it, its volume is sized from the other attributes.", "tags": ["catalog"], "security": [{"BearerAuth": []}]}}, "/api/v1/operations": {"get": {"operationId": "list_operations", "summary": "The operations of an organization, newest first", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Organization"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "description": "How many operations to return, newest first", "maximum": 200, "minimum": 1, "title": "Limit", "type": "integer"}, "required": false, "description": "How many operations to return, newest first"}, {"in": "query", "name": "app", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Keep only the operations acting on this app", "title": "App"}, "required": false, "description": "Keep only the operations acting on this app"}, {"in": "query", "name": "service", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Keep only the operations acting on this service", "title": "Service"}, "required": false, "description": "Keep only the operations acting on this service"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"enum": ["PENDING", "STARTED", "RETRY", "REVOKING", "SUCCESS", "FAILURE", "REVOKED"], "type": "string"}, {"type": "null"}], "description": "Keep only the operations in this status: PENDING, STARTED, RETRY, REVOKING, SUCCESS, FAILURE or REVOKED", "title": "Status"}, "required": false, "description": "Keep only the operations in this status: PENDING, STARTED, RETRY, REVOKING, SUCCESS, FAILURE or REVOKED"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/OperationSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Every deploy, apply, restart, start, stop, expose, unexpose and destroy the organization ran, including the ones still in progress. Poll one of them at GET /api/v1/operations/<id> to follow it.", "tags": ["operations"], "security": [{"BearerAuth": []}]}}, "/api/v1/operations/{operation_id}": {"get": {"operationId": "get_operation", "summary": "One operation", "parameters": [{"in": "path", "name": "operation_id", "schema": {"title": "Operation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["operations"], "security": [{"BearerAuth": []}]}}, "/api/v1/operations/{operation_id}/cancel": {"post": {"operationId": "cancel_operation", "summary": "Cancel an operation that has not finished yet", "parameters": [{"in": "path", "name": "operation_id", "schema": {"title": "Operation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OperationSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "An operation that never started is revoked at once; a running one is asked to stop, so its status becomes revoking until the worker gives up. Before the pre-deploy script starts, Cancel stops the deploy cleanly. While the script runs, Cancel stops it within seconds, wherever it got to (on a database without transactional DDL, such as MariaDB or MySQL, a migration can be left half done), and the new version is never rolled out. Once the script has finished, the new version is already rolling out and Cancel cannot undo it: it only ends the operation, so that another deploy can start, and a deploy whose rollout is already complete is reported as succeeded.", "tags": ["operations"], "security": [{"BearerAuth": []}]}}, "/api/v1/profile": {"get": {"operationId": "get_profile", "summary": "The user the token belongs to, with the hints of its tokens", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProfileSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["profile"], "security": [{"BearerAuth": []}]}}, "/api/v1/profile/git-token/regenerate": {"post": {"operationId": "regenerate_git_token", "summary": "Issue a new Git Access Token and revoke the old one", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegeneratedTokenSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Revokes the Git Access Token of the user and issues a new one. The secret is returned only here, so store it now and update every git remote that carried the old one.", "tags": ["profile"], "security": [{"BearerAuth": []}]}}, "/api/v1/profile/api-token/regenerate": {"post": {"operationId": "regenerate_api_token", "summary": "Issue a new API token and revoke the old one", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegeneratedApiTokenSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Revokes the API token of the user and issues a new one. The token used for this request stops working immediately, so the secret in the response must be stored now: it is returned only here, later requests can read its hint but never the secret again.", "tags": ["profile"], "security": [{"BearerAuth": []}]}}, "/api/v1/profile/connections": {"get": {"operationId": "list_connections", "summary": "The agents connected to the user through OAuth", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ConnectionSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The agents and applications that hold a live OAuth token of this user, one entry per connection. They were authorized from a browser and act as the user on every organization it belongs to.", "tags": ["profile"], "security": [{"BearerAuth": []}]}}, "/api/v1/profile/connections/{connection_id}": {"delete": {"operationId": "revoke_connection", "summary": "Revoke a connected agent", "parameters": [{"in": "path", "name": "connection_id", "schema": {"format": "uuid", "title": "Connection Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Revokes a connection: the access token of the agent and the refresh token that renews it stop working immediately and the agent has to be authorized again from a browser.", "tags": ["profile"], "security": [{"BearerAuth": []}]}}, "/api/v1/pricing": {"get": {"operationId": "get_pricing", "summary": "The sizes you can choose and the plan of the organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user", "title": "Organization"}, "required": false, "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PricingSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["billing"], "security": [{"BearerAuth": []}]}}, "/api/v1/billing": {"get": {"operationId": "get_billing", "summary": "Billing details and cards of the organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user", "title": "Organization"}, "required": false, "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["billing"], "security": [{"BearerAuth": []}]}}, "/api/v1/billing/details": {"patch": {"operationId": "update_billing_details", "summary": "Change the details the invoices are issued to", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user", "title": "Organization"}, "required": false, "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingDetailsSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingDetailsUpdateSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/billing/payment-methods": {"post": {"operationId": "add_payment_method", "summary": "Add a card to the organization", "parameters": [{"in": "query", "name": "organization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user", "title": "Organization"}, "required": false, "description": "Identifier of the organization to work on, as returned by GET /api/v1/organizations; defaults to the current organization of the user"}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaymentMethodSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "Adds a card to the organization. The id comes from Stripe.js on the client, from a Stripe SetupIntent or a PaymentMethod created there, exactly as the console does: this API never sees the card details. The card is attached to the Stripe customer of the organization and kept only when Stripe reports it as a card that belongs to nobody else.", "tags": ["billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddPaymentMethodSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/billing/payment-methods/{payment_method_id}/set-preferred": {"post": {"operationId": "set_preferred_payment_method", "summary": "Make a card the one charged first", "parameters": [{"in": "path", "name": "payment_method_id", "schema": {"description": "Identifier of the payment method, as returned by GET /api/v1/billing", "title": "Payment Method Id", "type": "integer"}, "required": true, "description": "Identifier of the payment method, as returned by GET /api/v1/billing"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaymentMethodSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["billing"], "security": [{"BearerAuth": []}]}}, "/api/v1/billing/payment-methods/{payment_method_id}": {"delete": {"operationId": "delete_payment_method", "summary": "Remove a card from the organization", "parameters": [{"in": "path", "name": "payment_method_id", "schema": {"description": "Identifier of the payment method, as returned by GET /api/v1/billing", "title": "Payment Method Id", "type": "integer"}, "required": true, "description": "Identifier of the payment method, as returned by GET /api/v1/billing"}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "tags": ["billing"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/runtime-logs": {"get": {"operationId": "get_app_runtime_logs", "summary": "A page of the runtime logs of an app", "parameters": [{"in": "query", "name": "from", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "required": false, "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs"}, {"in": "query", "name": "to", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "required": false, "description": "End of the window, an ISO 8601 datetime; defaults to now"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "required": false, "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude"}, {"in": "query", "name": "level", "schema": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level"}, {"in": "query", "name": "pod", "schema": {"description": "Read only these pods of the app, repeatable; empty means every pod", "items": {"type": "integer"}, "title": "Pod", "type": "array"}, "required": false, "description": "Read only these pods of the app, repeatable; empty means every pod"}, {"in": "query", "name": "cursor", "schema": {"anyOf": [{"pattern": "^[0-9]{1,20}(:[A-Za-z0-9_-]{1,64})?$", "type": "string"}, {"type": "null"}], "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond", "title": "Cursor"}, "required": false, "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond"}, {"in": "query", "name": "direction", "schema": {"default": "backward", "description": "backward reads from the newest line down, forward from the oldest line up", "title": "Direction", "type": "string"}, "required": false, "description": "backward reads from the newest line down, forward from the oldest line up"}, {"in": "query", "name": "limit", "schema": {"anyOf": [{"maximum": 1000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "How many lines to return, at most 1000; defaults to the console page size", "title": "Limit"}, "required": false, "description": "How many lines to return, at most 1000; defaults to the console page size"}, {"in": "path", "name": "app_id", "schema": {"description": "Identifier of the app, as returned by GET /api/v1/apps", "title": "App Id", "type": "integer"}, "required": true, "description": "Identifier of the app, as returned by GET /api/v1/apps"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LogPageSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The runtime log lines of the app, read from the log store exactly as the console logs page reads them: the same default window, the same search and level filters, the same masking of any value that would reveal a secret of the app (a search touching one returns no lines at all).", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/runtime-logs/histogram": {"get": {"operationId": "get_app_runtime_logs_histogram", "summary": "How many runtime lines per level over the window", "parameters": [{"in": "query", "name": "from", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "required": false, "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs"}, {"in": "query", "name": "to", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "required": false, "description": "End of the window, an ISO 8601 datetime; defaults to now"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "required": false, "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude"}, {"in": "query", "name": "level", "schema": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level"}, {"in": "query", "name": "pod", "schema": {"description": "Read only these pods of the app, repeatable; empty means every pod", "items": {"type": "integer"}, "title": "Pod", "type": "array"}, "required": false, "description": "Read only these pods of the app, repeatable; empty means every pod"}, {"in": "query", "name": "counted", "schema": {"default": false, "description": "Count the filtered lines per level instead of measuring ingested bytes", "title": "Counted", "type": "boolean"}, "required": false, "description": "Count the filtered lines per level instead of measuring ingested bytes"}, {"in": "path", "name": "app_id", "schema": {"description": "Identifier of the app, as returned by GET /api/v1/apps", "title": "App Id", "type": "integer"}, "required": true, "description": "Identifier of the app, as returned by GET /api/v1/apps"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HistogramSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The histogram the console draws above the runtime logs: the window split in buckets, with the lines per level in each of them.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/runtime-logs/context": {"get": {"operationId": "get_app_runtime_logs_context", "summary": "The runtime lines around one line", "parameters": [{"in": "path", "name": "app_id", "schema": {"description": "Identifier of the app, as returned by GET /api/v1/apps", "title": "App Id", "type": "integer"}, "required": true, "description": "Identifier of the app, as returned by GET /api/v1/apps"}, {"in": "query", "name": "ns", "schema": {"description": "The ns of the line to expand", "pattern": "^[0-9]{1,20}$", "title": "Ns", "type": "string"}, "required": true, "description": "The ns of the line to expand"}, {"in": "query", "name": "pod", "schema": {"description": "The pod field of that line", "pattern": "^[A-Za-z0-9._-]{1,253}$", "title": "Pod", "type": "string"}, "required": true, "description": "The pod field of that line"}, {"in": "query", "name": "container", "schema": {"default": "", "description": "The container field of that line, empty to read every container of the pod", "pattern": "^([A-Za-z0-9._-]{1,253})?$", "title": "Container", "type": "string"}, "required": false, "description": "The container field of that line, empty to read every container of the pod"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LogContextSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The lines logged just before and just after one line of one pod, the way the console expands a line in place. The whole retention is searched, whatever window the page endpoint used, and no search or level filter is applied.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/deploy-logs": {"get": {"operationId": "get_app_deploy_logs", "summary": "A page of the deploy logs of an app", "parameters": [{"in": "query", "name": "cursor", "schema": {"anyOf": [{"pattern": "^[0-9]{1,20}(:[A-Za-z0-9_-]{1,64})?$", "type": "string"}, {"type": "null"}], "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond", "title": "Cursor"}, "required": false, "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond"}, {"in": "query", "name": "direction", "schema": {"default": "backward", "description": "backward reads from the newest line down, forward from the oldest line up", "title": "Direction", "type": "string"}, "required": false, "description": "backward reads from the newest line down, forward from the oldest line up"}, {"in": "query", "name": "limit", "schema": {"anyOf": [{"maximum": 1000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "How many lines to return, at most 1000; defaults to the console page size", "title": "Limit"}, "required": false, "description": "How many lines to return, at most 1000; defaults to the console page size"}, {"in": "query", "name": "operation", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the deploy or apply operation to read the logs of", "title": "Operation"}, "required": false, "description": "Identifier of the deploy or apply operation to read the logs of"}, {"in": "path", "name": "app_id", "schema": {"description": "Identifier of the app, as returned by GET /api/v1/apps", "title": "App Id", "type": "integer"}, "required": true, "description": "Identifier of the app, as returned by GET /api/v1/apps"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeployLogPageSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The logs of one deploy or apply run of the app, in time order, plus the outcome line once the run is over: a deploy run also has the image build and the predeploy script, an apply run neither. Without an operation the latest run still within the log retention is served, the one the console opens.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/logs": {"get": {"operationId": "get_service_logs", "summary": "A page of the logs of a service", "parameters": [{"in": "query", "name": "from", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "required": false, "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs"}, {"in": "query", "name": "to", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "required": false, "description": "End of the window, an ISO 8601 datetime; defaults to now"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "required": false, "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude"}, {"in": "query", "name": "level", "schema": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level"}, {"in": "query", "name": "cursor", "schema": {"anyOf": [{"pattern": "^[0-9]{1,20}(:[A-Za-z0-9_-]{1,64})?$", "type": "string"}, {"type": "null"}], "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond", "title": "Cursor"}, "required": false, "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond"}, {"in": "query", "name": "direction", "schema": {"default": "backward", "description": "backward reads from the newest line down, forward from the oldest line up", "title": "Direction", "type": "string"}, "required": false, "description": "backward reads from the newest line down, forward from the oldest line up"}, {"in": "query", "name": "limit", "schema": {"anyOf": [{"maximum": 1000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "How many lines to return, at most 1000; defaults to the console page size", "title": "Limit"}, "required": false, "description": "How many lines to return, at most 1000; defaults to the console page size"}, {"in": "path", "name": "service_id", "schema": {"description": "Identifier of the service, as returned by GET /api/v1/services", "title": "Service Id", "type": "integer"}, "required": true, "description": "Identifier of the service, as returned by GET /api/v1/services"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LogPageSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The log lines of the service, read exactly as the console logs page reads them: the same default window, the same search and level filters, the same masking of any value that would reveal a credential of the organization.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/logs/histogram": {"get": {"operationId": "get_service_logs_histogram", "summary": "How many service lines per level over the window", "parameters": [{"in": "query", "name": "from", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "required": false, "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs"}, {"in": "query", "name": "to", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "required": false, "description": "End of the window, an ISO 8601 datetime; defaults to now"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "required": false, "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude"}, {"in": "query", "name": "level", "schema": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level"}, {"in": "query", "name": "counted", "schema": {"default": false, "description": "Count the filtered lines per level instead of measuring ingested bytes", "title": "Counted", "type": "boolean"}, "required": false, "description": "Count the filtered lines per level instead of measuring ingested bytes"}, {"in": "path", "name": "service_id", "schema": {"description": "Identifier of the service, as returned by GET /api/v1/services", "title": "Service Id", "type": "integer"}, "required": true, "description": "Identifier of the service, as returned by GET /api/v1/services"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HistogramSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The histogram the console draws above the logs of the service.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/logs/context": {"get": {"operationId": "get_service_logs_context", "summary": "The service lines around one line", "parameters": [{"in": "path", "name": "service_id", "schema": {"description": "Identifier of the service, as returned by GET /api/v1/services", "title": "Service Id", "type": "integer"}, "required": true, "description": "Identifier of the service, as returned by GET /api/v1/services"}, {"in": "query", "name": "ns", "schema": {"description": "The ns of the line to expand", "pattern": "^[0-9]{1,20}$", "title": "Ns", "type": "string"}, "required": true, "description": "The ns of the line to expand"}, {"in": "query", "name": "pod", "schema": {"description": "The pod field of that line", "pattern": "^[A-Za-z0-9._-]{1,253}$", "title": "Pod", "type": "string"}, "required": true, "description": "The pod field of that line"}, {"in": "query", "name": "container", "schema": {"default": "", "description": "The container field of that line, empty to read every container of the pod", "pattern": "^([A-Za-z0-9._-]{1,253})?$", "title": "Container", "type": "string"}, "required": false, "description": "The container field of that line, empty to read every container of the pod"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LogContextSchema"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The lines logged just before and just after one line of the service. The whole retention is searched and no search or level filter is applied.", "tags": ["logs"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/metrics": {"get": {"operationId": "get_app_metrics", "summary": "CPU and memory used by the pods of an app over a window", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "query", "name": "range", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h", "title": "Range"}, "required": false, "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkloadSeriesSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The series the console draws on the app page, one per pod: the share of what the nodes of the organization can give to workloads that the pod is using.", "tags": ["metrics"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/metrics": {"get": {"operationId": "get_service_metrics", "summary": "CPU and memory used by a service over a window", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "range", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h", "title": "Range"}, "required": false, "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkloadSeriesSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The series the console draws on the service page: the share of what the nodes of the organization can give to workloads that the service is using.", "tags": ["metrics"], "security": [{"BearerAuth": []}]}}, "/api/v1/organizations/{organization_id}/resources": {"get": {"operationId": "get_organization_resources", "summary": "What the plan of an organization provides and how much of it is in use", "parameters": [{"in": "path", "name": "organization_id", "schema": {"title": "Organization Id", "type": "integer"}, "required": true}, {"in": "query", "name": "range", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h", "title": "Range"}, "required": false, "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OrganizationResourcesSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The resources page of the console: the active node plan, what it provides and, per resource, the share of what the nodes can give to workloads that is in use right now. The percentage is measured against what the nodes can actually give, so at 100% memory the nodes are full and workloads get killed.", "tags": ["resources"], "security": [{"BearerAuth": []}]}}, "/api/v1/organizations/{organization_id}/resources/series": {"get": {"operationId": "get_organization_resources_series", "summary": "CPU and memory used by an organization over a window", "parameters": [{"in": "path", "name": "organization_id", "schema": {"title": "Organization Id", "type": "integer"}, "required": true}, {"in": "query", "name": "range", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h", "title": "Range"}, "required": false, "description": "Window of the series, one of: 1h, 6h, 24h, 7d, 30d; defaults to 6h"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OrganizationSeriesSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}}, "description": "The series the console resources chart draws: one point per step over the window, as a percentage of what the nodes of the organization can give to workloads.", "tags": ["resources"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/pods/{pod_id}/exec": {"post": {"operationId": "exec_in_pod", "summary": "Run a command in a running pod and stream its output", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "path", "name": "pod_id", "schema": {"title": "Pod Id", "type": "integer"}, "required": true}], "responses": {"503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "200": {"description": "A chunked stream of newline delimited JSON, one object per line, flushed as it is produced. Read it line by line: every line is one of the objects below, and the last line always says why the stream ended.", "content": {"application/x-ndjson": {"schema": {"anyOf": [{"properties": {"stream": {"description": "The channel the chunk came from: \"stdout\" or \"stderr\"", "title": "Stream", "type": "string"}, "data": {"description": "A chunk of output as the container wrote it; chunks are not line buffered", "title": "Data", "type": "string"}}, "required": ["stream", "data"], "title": "ExecOutputSchema", "type": "object"}, {"properties": {"exit_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Exit status of the command, null when Kubernetes did not report one", "title": "Exit Code"}, "reason": {"description": "Why the stream ended: \"completed\" when the command finished, \"timeout\", \"output_limit\" when the output cap was reached, \"pod_gone\" when the pod went away, \"access_revoked\" when the caller lost access to the organization, or \"error\"", "title": "Reason", "type": "string"}, "message": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "What went wrong, null when nothing did", "title": "Message"}}, "required": ["exit_code", "reason", "message"], "title": "ExecEndSchema", "type": "object"}]}}}}}, "description": "At most 8 commands and log tails may be open at once per token, counted together: beyond that the answer is 429 with code too_many_streams until one of them ends.", "tags": ["streams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExecRequestSchema"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/runtime-logs/tail": {"get": {"operationId": "tail_runtime_logs", "summary": "Stream the runtime logs of an app as they arrive", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "query", "name": "pod", "schema": {"default": [], "description": "Identifiers of the pods to read, all of them when empty", "items": {"type": "integer"}, "title": "Pod", "type": "array"}, "required": false, "description": "Identifiers of the pods to read, all of them when empty"}, {"in": "query", "name": "level", "schema": {"default": [], "description": "Keep only these levels; one of error, warn, info, debug, other", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels; one of error, warn, info, debug, other"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same one the console log search accepts", "title": "Contains"}, "required": false, "description": "Search expression, the same one the console log search accepts"}, {"in": "query", "name": "cursor", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 15 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 15 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 15 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines", "title": "Cursor"}, "required": false, "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 15 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 15 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 15 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines"}, {"in": "query", "name": "timeout", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600", "title": "Timeout"}, "required": false, "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600"}], "responses": {"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "200": {"description": "A chunked stream of newline delimited JSON, one object per line, flushed as it is produced. Read it line by line: every line is one of the objects below, and the last line always says why the stream ended.", "content": {"application/x-ndjson": {"schema": {"anyOf": [{"properties": {"timestamp": {"description": "When the line was written", "format": "date-time", "title": "Timestamp", "type": "string"}, "level": {"description": "Level detected on the line, \"unknown\" when there is none", "title": "Level", "type": "string"}, "message": {"description": "The line itself, with the secrets of the app masked", "title": "Message", "type": "string"}, "pod": {"description": "Pod the line comes from, empty for lines with no pod", "title": "Pod", "type": "string"}, "container": {"description": "Container the line comes from, empty when unknown", "title": "Container", "type": "string"}, "ns": {"description": "Timestamp of the line in nanoseconds", "title": "Ns", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail when you stop after this line: nothing after it is lost within the lateness bound the cursor parameter describes. It can be ahead of the ns of the line, and lines sharing one ns can carry the same cursor: a client that stops after a number of lines has to count only the lines whose key is new to it", "title": "Cursor", "type": "string"}, "key": {"description": "Identifier of the line, the same on the log pages and tails read with the same filters (a field:value search changes it). The first lines of a resumed tail can repeat those of the 15 seconds (60 on a deploy-log tail) before its cursor: keep the keys of that stretch and skip the lines whose key you already handled", "title": "Key", "type": "string"}, "stream": {"description": "On a deploy-log tail: build (the image build), predeploy (the predeploy script) or outcome (the final line, sent when the run is over; the tail ends there, and a resumed tail sends it again past the cursor: skip it by key, resume from its cursor, not its ns). Empty on a runtime or service log tail", "title": "Stream", "type": "string"}}, "required": ["timestamp", "level", "message", "pod", "container", "ns", "cursor", "key", "stream"], "title": "LogLineSchema", "type": "object"}, {"properties": {"ping": {"description": "Always true; sent while idle so proxies see traffic", "title": "Ping", "type": "boolean"}}, "required": ["ping"], "title": "PingSchema", "type": "object"}, {"properties": {"end": {"description": "Why the stream ended: \"timeout\" when the requested duration elapsed, \"source_gone\" when the app, service or deploy has nothing more to send, \"access_revoked\" when the caller lost access to the organization, or \"error\"", "title": "End", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail to resume where this stream stopped. It can be ahead of the last line sent", "title": "Cursor", "type": "string"}}, "required": ["end", "cursor"], "title": "TailEndSchema", "type": "object"}]}}}}}, "description": "At most 8 commands and log tails may be open at once per token, counted together: beyond that the answer is 429 with code too_many_streams until one of them ends.", "tags": ["streams"], "security": [{"BearerAuth": []}]}}, "/api/v1/apps/{app_id}/deploy-logs/tail": {"get": {"operationId": "tail_deploy_logs", "summary": "Stream the build and pre-deploy logs of a deploy as they arrive", "parameters": [{"in": "path", "name": "app_id", "schema": {"title": "App Id", "type": "integer"}, "required": true}, {"in": "query", "name": "operation", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the deploy or apply operation, the most recent one when empty", "title": "Operation"}, "required": false, "description": "Identifier of the deploy or apply operation, the most recent one when empty"}, {"in": "query", "name": "cursor", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 60 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 60 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 60 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines", "title": "Cursor"}, "required": false, "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 60 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 60 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 60 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines"}, {"in": "query", "name": "timeout", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600", "title": "Timeout"}, "required": false, "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600"}], "responses": {"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "200": {"description": "A chunked stream of newline delimited JSON, one object per line, flushed as it is produced. Read it line by line: every line is one of the objects below, and the last line always says why the stream ended.", "content": {"application/x-ndjson": {"schema": {"anyOf": [{"properties": {"timestamp": {"description": "When the line was written", "format": "date-time", "title": "Timestamp", "type": "string"}, "level": {"description": "Level detected on the line, \"unknown\" when there is none", "title": "Level", "type": "string"}, "message": {"description": "The line itself, with the secrets of the app masked", "title": "Message", "type": "string"}, "pod": {"description": "Pod the line comes from, empty for lines with no pod", "title": "Pod", "type": "string"}, "container": {"description": "Container the line comes from, empty when unknown", "title": "Container", "type": "string"}, "ns": {"description": "Timestamp of the line in nanoseconds", "title": "Ns", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail when you stop after this line: nothing after it is lost within the lateness bound the cursor parameter describes. It can be ahead of the ns of the line, and lines sharing one ns can carry the same cursor: a client that stops after a number of lines has to count only the lines whose key is new to it", "title": "Cursor", "type": "string"}, "key": {"description": "Identifier of the line, the same on the log pages and tails read with the same filters (a field:value search changes it). The first lines of a resumed tail can repeat those of the 15 seconds (60 on a deploy-log tail) before its cursor: keep the keys of that stretch and skip the lines whose key you already handled", "title": "Key", "type": "string"}, "stream": {"description": "On a deploy-log tail: build (the image build), predeploy (the predeploy script) or outcome (the final line, sent when the run is over; the tail ends there, and a resumed tail sends it again past the cursor: skip it by key, resume from its cursor, not its ns). Empty on a runtime or service log tail", "title": "Stream", "type": "string"}}, "required": ["timestamp", "level", "message", "pod", "container", "ns", "cursor", "key", "stream"], "title": "LogLineSchema", "type": "object"}, {"properties": {"ping": {"description": "Always true; sent while idle so proxies see traffic", "title": "Ping", "type": "boolean"}}, "required": ["ping"], "title": "PingSchema", "type": "object"}, {"properties": {"end": {"description": "Why the stream ended: \"timeout\" when the requested duration elapsed, \"source_gone\" when the app, service or deploy has nothing more to send, \"access_revoked\" when the caller lost access to the organization, or \"error\"", "title": "End", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail to resume where this stream stopped. It can be ahead of the last line sent", "title": "Cursor", "type": "string"}}, "required": ["end", "cursor"], "title": "TailEndSchema", "type": "object"}]}}}}}, "description": "At most 8 commands and log tails may be open at once per token, counted together: beyond that the answer is 429 with code too_many_streams until one of them ends.", "tags": ["streams"], "security": [{"BearerAuth": []}]}}, "/api/v1/services/{service_id}/logs/tail": {"get": {"operationId": "tail_service_logs", "summary": "Stream the logs of a service as they arrive", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "level", "schema": {"default": [], "description": "Keep only these levels; one of error, warn, info, debug, other", "items": {"type": "string"}, "title": "Level", "type": "array"}, "required": false, "description": "Keep only these levels; one of error, warn, info, debug, other"}, {"in": "query", "name": "contains", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same one the console log search accepts", "title": "Contains"}, "required": false, "description": "Search expression, the same one the console log search accepts"}, {"in": "query", "name": "cursor", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 15 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 15 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 15 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines", "title": "Cursor"}, "required": false, "description": "Where to resume: the cursor of the end line of the previous tail, or of the last line you handled, passed back as it is. A line that reaches the log store up to 15 seconds late is still delivered while the tail keeps up with the logs; a later one, or one late by more than a few seconds while the tail catches up on a dense stretch (several hundred lines per second), may be missed, and a page read afterwards has it. The first lines can repeat those of the 15 seconds before the cursor: keep the keys of that stretch and skip the lines whose key you already handled. The ns of a line is accepted too, but repeats those 15 seconds in full. Bound a tail with timeout, not with a number of lines. Leave it out to start from now, with no earlier lines"}, {"in": "query", "name": "timeout", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600", "title": "Timeout"}, "required": false, "description": "Seconds to keep the stream open. Defaults to 300; a larger value is clamped to 3600"}], "responses": {"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorSchema"}}}}, "200": {"description": "A chunked stream of newline delimited JSON, one object per line, flushed as it is produced. Read it line by line: every line is one of the objects below, and the last line always says why the stream ended.", "content": {"application/x-ndjson": {"schema": {"anyOf": [{"properties": {"timestamp": {"description": "When the line was written", "format": "date-time", "title": "Timestamp", "type": "string"}, "level": {"description": "Level detected on the line, \"unknown\" when there is none", "title": "Level", "type": "string"}, "message": {"description": "The line itself, with the secrets of the app masked", "title": "Message", "type": "string"}, "pod": {"description": "Pod the line comes from, empty for lines with no pod", "title": "Pod", "type": "string"}, "container": {"description": "Container the line comes from, empty when unknown", "title": "Container", "type": "string"}, "ns": {"description": "Timestamp of the line in nanoseconds", "title": "Ns", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail when you stop after this line: nothing after it is lost within the lateness bound the cursor parameter describes. It can be ahead of the ns of the line, and lines sharing one ns can carry the same cursor: a client that stops after a number of lines has to count only the lines whose key is new to it", "title": "Cursor", "type": "string"}, "key": {"description": "Identifier of the line, the same on the log pages and tails read with the same filters (a field:value search changes it). The first lines of a resumed tail can repeat those of the 15 seconds (60 on a deploy-log tail) before its cursor: keep the keys of that stretch and skip the lines whose key you already handled", "title": "Key", "type": "string"}, "stream": {"description": "On a deploy-log tail: build (the image build), predeploy (the predeploy script) or outcome (the final line, sent when the run is over; the tail ends there, and a resumed tail sends it again past the cursor: skip it by key, resume from its cursor, not its ns). Empty on a runtime or service log tail", "title": "Stream", "type": "string"}}, "required": ["timestamp", "level", "message", "pod", "container", "ns", "cursor", "key", "stream"], "title": "LogLineSchema", "type": "object"}, {"properties": {"ping": {"description": "Always true; sent while idle so proxies see traffic", "title": "Ping", "type": "boolean"}}, "required": ["ping"], "title": "PingSchema", "type": "object"}, {"properties": {"end": {"description": "Why the stream ended: \"timeout\" when the requested duration elapsed, \"source_gone\" when the app, service or deploy has nothing more to send, \"access_revoked\" when the caller lost access to the organization, or \"error\"", "title": "End", "type": "string"}, "cursor": {"description": "Nanosecond timestamp to pass back, as it is, as the cursor of the next tail to resume where this stream stopped. It can be ahead of the last line sent", "title": "Cursor", "type": "string"}}, "required": ["end", "cursor"], "title": "TailEndSchema", "type": "object"}]}}}}}, "description": "At most 8 commands and log tails may be open at once per token, counted together: beyond that the answer is 429 with code too_many_streams until one of them ends.", "tags": ["streams"], "security": [{"BearerAuth": []}]}}}, "components": {"schemas": {"OrganizationRefSchema": {"properties": {"id": {"description": "Identifier of the organization", "title": "Id", "type": "integer"}, "name": {"description": "Display name of the organization", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "OrganizationRefSchema", "type": "object"}, "UserSchema": {"properties": {"id": {"description": "Identifier of the user the token belongs to", "title": "Id", "type": "integer"}, "email": {"description": "Email address of the user", "title": "Email", "type": "string"}, "username": {"description": "Unique handle of the user", "title": "Username", "type": "string"}, "fullname": {"description": "Full name of the user, empty when never set", "title": "Fullname", "type": "string"}, "organization": {"anyOf": [{"$ref": "#/components/schemas/OrganizationRefSchema"}, {"type": "null"}], "description": "Organization the user is currently working on, null when none is selected"}}, "required": ["id", "email", "username", "fullname", "organization"], "title": "UserSchema", "type": "object"}, "ErrorSchema": {"properties": {"code": {"description": "Machine readable identifier of the error", "title": "Code", "type": "string"}, "message": {"description": "Human readable description of what went wrong", "title": "Message", "type": "string"}, "hint": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Suggested way to fix the request, when there is one", "title": "Hint"}, "errors": {"anyOf": [{"additionalProperties": {"items": {"type": "string"}, "type": "array"}, "type": "object"}, {"type": "null"}], "description": "Messages per field, only on validation errors; non-field messages are under \"__all__\"", "title": "Errors"}}, "required": ["code", "message"], "title": "ErrorSchema", "type": "object"}, "OrganizationSchema": {"properties": {"id": {"description": "Identifier of the organization", "title": "Id", "type": "integer"}, "name": {"description": "Display name of the organization", "title": "Name", "type": "string"}, "namespace": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Kubernetes namespace the organization workloads run in", "title": "Namespace"}, "is_current": {"description": "Whether this is the organization the token works on by default", "title": "Is Current", "type": "boolean"}}, "required": ["id", "name", "namespace", "is_current"], "title": "OrganizationSchema", "type": "object"}, "AppSchema": {"properties": {"id": {"description": "Identifier of the app", "title": "Id", "type": "integer"}, "name": {"description": "Name of the app, unique across JetDeploy", "title": "Name", "type": "string"}, "status": {"description": "Current status of the app: created (never deployed), ready, ready_partial, starting, stopping, stopped, unknown", "title": "Status", "type": "string"}, "wizard_step": {"description": "How far the app got in the creation wizard: console:app:wizard_push while it waits for the first push, console:app:wizard_pod while it has no pod, console:app:detail once it is complete", "title": "Wizard Step", "type": "string"}, "branch": {"description": "Git branch a push has to carry to be deployed", "title": "Branch", "type": "string"}, "url": {"description": "Public HTTPS URL of the app on its platform host, live once the app is deployed with an external pod; attached validated domains answer too", "title": "Url", "type": "string"}, "created_at": {"description": "When the app was created", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "When the app was last changed", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "wizard_step", "branch", "url", "created_at", "updated_at"], "title": "AppSchema", "type": "object"}, "AppDetailSchema": {"properties": {"id": {"description": "Identifier of the app", "title": "Id", "type": "integer"}, "name": {"description": "Name of the app, unique across JetDeploy", "title": "Name", "type": "string"}, "status": {"description": "Current status of the app: created (never deployed), ready, ready_partial, starting, stopping, stopped, unknown", "title": "Status", "type": "string"}, "wizard_step": {"description": "How far the app got in the creation wizard: console:app:wizard_push while it waits for the first push, console:app:wizard_pod while it has no pod, console:app:detail once it is complete", "title": "Wizard Step", "type": "string"}, "branch": {"description": "Git branch a push has to carry to be deployed", "title": "Branch", "type": "string"}, "url": {"description": "Public HTTPS URL of the app on its platform host, live once the app is deployed with an external pod; attached validated domains answer too", "title": "Url", "type": "string"}, "created_at": {"description": "When the app was created", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "When the app was last changed", "format": "date-time", "title": "Updated At", "type": "string"}, "namespace": {"description": "Kubernetes namespace the app runs in", "title": "Namespace", "type": "string"}, "repo_path": {"description": "Path of the bare git repository on the git server", "title": "Repo Path", "type": "string"}, "git_remote_url": {"description": "HTTPS URL of the git remote of this app, without credentials. Push to it with the username \"git\" and the Git Access Token of the user as the password, on the branch of the app", "title": "Git Remote Url", "type": "string"}, "predeploy_script": {"description": "Script run on every deploy after the build and before the new version gets traffic, empty when there is none. It may take at most 510 seconds, both attempts included; past the limit it is stopped wherever it got to", "title": "Predeploy Script", "type": "string"}, "pods": {"description": "Pods of the app", "items": {"$ref": "#/components/schemas/PodSchema"}, "title": "Pods", "type": "array"}, "envs": {"additionalProperties": {"type": "string"}, "description": "Environment variables of the app, as key to value", "title": "Envs", "type": "object"}, "redirect_rules": {"description": "Redirect rules of the app", "items": {"$ref": "#/components/schemas/RedirectRuleSchema"}, "title": "Redirect Rules", "type": "array"}, "domains": {"description": "Domains attached to the app", "items": {"$ref": "#/components/schemas/DomainRefSchema"}, "title": "Domains", "type": "array"}, "latest_push": {"anyOf": [{"$ref": "#/components/schemas/PushSchema"}, {"type": "null"}], "description": "Last push JetDeploy received for this app, null when it was never pushed to"}, "pending_operation": {"anyOf": [{"$ref": "#/components/schemas/OperationSchema"}, {"type": "null"}], "description": "Operation still running on the app or one of its pods, null when there is none"}, "next_step": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "What to do next to get this app running, null when it is deployed", "title": "Next Step"}, "apply_required": {"default": false, "description": "True when the change is stored but not live yet, exactly where the console asks for an Apply; next_step of the app says which call brings it live", "title": "Apply Required", "type": "boolean"}}, "required": ["id", "name", "status", "wizard_step", "branch", "url", "created_at", "updated_at", "namespace", "repo_path", "git_remote_url", "predeploy_script", "pods", "envs", "redirect_rules", "domains", "latest_push", "pending_operation", "next_step"], "title": "AppDetailSchema", "type": "object"}, "DomainRefSchema": {"properties": {"id": {"description": "Identifier of the domain", "title": "Id", "type": "integer"}, "name": {"description": "Domain name", "title": "Name", "type": "string"}, "status": {"description": "Whether the domain is validated or unvalidated", "title": "Status", "type": "string"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "HTTPS URL of the app on this domain, null while the domain is unvalidated since only validated domains are routed", "title": "Url"}}, "required": ["id", "name", "status", "url"], "title": "DomainRefSchema", "type": "object"}, "OperationSchema": {"properties": {"id": {"description": "Identifier of the operation", "title": "Id", "type": "integer"}, "kind": {"description": "What the operation does: deploy, apply, restart, start, stop, expose, unexpose, destroy", "title": "Kind", "type": "string"}, "target": {"description": "Kind of resource the operation acts on: app, service, pod", "title": "Target", "type": "string"}, "target_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the app, service or pod the operation acts on", "title": "Target Id"}, "target_name": {"description": "Name of the resource the operation acts on", "title": "Target Name", "type": "string"}, "status": {"description": "Current status of the operation", "title": "Status", "type": "string"}, "is_finished": {"description": "Whether the operation reached a final status", "title": "Is Finished", "type": "boolean"}, "error_message": {"description": "Why the operation failed, empty otherwise", "title": "Error Message", "type": "string"}, "created_at": {"description": "When the operation was requested", "format": "date-time", "title": "Created At", "type": "string"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the operation started running, null until then", "title": "Started At"}}, "required": ["id", "kind", "target", "target_id", "target_name", "status", "is_finished", "error_message", "created_at", "started_at"], "title": "OperationSchema", "type": "object"}, "PodSchema": {"properties": {"id": {"description": "Identifier of the pod", "title": "Id", "type": "integer"}, "name": {"description": "Name of the pod, unique within the app", "title": "Name", "type": "string"}, "status": {"description": "Current status of the pod: created, ready, ready_partial, starting, stopping, stopped, unknown", "title": "Status", "type": "string"}, "command": {"description": "Command the container runs, empty when the image decides", "title": "Command", "type": "string"}, "port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the container listens on, null when it serves none", "title": "Port"}, "external": {"description": "Whether this pod is the one reachable from the internet", "title": "External", "type": "boolean"}, "replicas": {"description": "How many copies of the pod run", "title": "Replicas", "type": "integer"}, "limits_cpu": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "CPU limit in millicores, null when unset", "title": "Limits Cpu"}, "limits_mem": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Memory limit in MiB, null when unset", "title": "Limits Mem"}, "warmup_delay": {"description": "Extra seconds waited before the pod counts as ready, on top of the port check", "title": "Warmup Delay", "type": "integer"}, "termination_grace_period": {"description": "Seconds the process gets after SIGTERM before it is killed", "title": "Termination Grace Period", "type": "integer"}, "internal_endpoint": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "URL other pods of the organization reach this pod at, null when it has no port", "title": "Internal Endpoint"}, "created_at": {"description": "When the pod was created", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "When the pod was last changed", "format": "date-time", "title": "Updated At", "type": "string"}, "apply_required": {"default": false, "description": "True when the change is stored but not live yet, exactly where the console asks for an Apply; next_step of the app says which call brings it live", "title": "Apply Required", "type": "boolean"}}, "required": ["id", "name", "status", "command", "port", "external", "replicas", "limits_cpu", "limits_mem", "warmup_delay", "termination_grace_period", "internal_endpoint", "created_at", "updated_at"], "title": "PodSchema", "type": "object"}, "PushSchema": {"properties": {"sha": {"description": "Full sha of the pushed commit", "title": "Sha", "type": "string"}, "message": {"description": "Message of the pushed commit", "title": "Message", "type": "string"}, "author_name": {"description": "Name of the author of the pushed commit", "title": "Author Name", "type": "string"}, "author_email": {"description": "Email of the author of the pushed commit", "title": "Author Email", "type": "string"}, "timestamp": {"description": "When the pushed commit was authored", "format": "date-time", "title": "Timestamp", "type": "string"}, "branch": {"description": "Branch the push landed on", "title": "Branch", "type": "string"}, "created_at": {"description": "When JetDeploy received the push", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["sha", "message", "author_name", "author_email", "timestamp", "branch", "created_at"], "title": "PushSchema", "type": "object"}, "RedirectRuleSchema": {"properties": {"id": {"description": "Identifier of the redirect rule", "title": "Id", "type": "integer"}, "from_host": {"description": "Host the request arrives on", "title": "From Host", "type": "string"}, "to_host": {"description": "Host the request is redirected to", "title": "To Host", "type": "string"}, "apply_required": {"default": false, "description": "True when the change is stored but not live yet, exactly where the console asks for an Apply; next_step of the app says which call brings it live", "title": "Apply Required", "type": "boolean"}}, "required": ["id", "from_host", "to_host"], "title": "RedirectRuleSchema", "type": "object"}, "AppCreateSchema": {"additionalProperties": false, "properties": {"name": {"description": "Name of the app: lowercase letters, digits and hyphens, unique across JetDeploy", "title": "Name", "type": "string"}, "branch": {"default": "main", "description": "Git branch to deploy from", "title": "Branch", "type": "string"}}, "required": ["name"], "title": "AppCreateSchema", "type": "object"}, "AppUpdateSchema": {"additionalProperties": false, "properties": {"branch": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Refused: the deploy branch is fixed when the app is created", "title": "Branch"}, "predeploy_script": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Script run on every deploy after the build and before the new version gets traffic, empty string to remove it; used by the next deploy, not by Apply. It may take at most 510 seconds, both attempts included; past the limit it is stopped wherever it got to", "title": "Predeploy Script"}}, "title": "AppUpdateSchema", "type": "object"}, "PodCreateSchema": {"additionalProperties": false, "properties": {"name": {"description": "Name of the pod, unique within the app", "title": "Name", "type": "string"}, "command": {"default": "", "description": "Command the container runs, empty to keep the one of the image. A single command receives the shutdown signal directly; end a script with exec <process> so that it does too", "title": "Command", "type": "string"}, "port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the container listens on, required when the pod is external", "title": "Port"}, "external": {"default": true, "description": "Whether this pod is the one reachable from the internet; at most one pod of the app can be", "title": "External", "type": "boolean"}, "warmup_delay": {"default": 0, "description": "Extra seconds waited before the pod counts as ready, on top of waiting for the port", "title": "Warmup Delay", "type": "integer"}, "termination_grace_period": {"default": 30, "description": "Seconds the process gets to finish after the shutdown signal (SIGTERM) before it is killed, 1 to 900", "title": "Termination Grace Period", "type": "integer"}}, "required": ["name"], "title": "PodCreateSchema", "type": "object"}, "PodUpdateSchema": {"additionalProperties": false, "properties": {"command": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Command the container runs, empty to keep the one of the image. A single command receives the shutdown signal directly; end a script with exec <process> so that it does too", "title": "Command"}, "port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the container listens on, required when the pod is external", "title": "Port"}, "external": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether this pod is the one reachable from the internet; at most one pod of the app can be", "title": "External"}, "warmup_delay": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Extra seconds waited before the pod counts as ready, on top of waiting for the port", "title": "Warmup Delay"}, "termination_grace_period": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Seconds the process gets to finish after the shutdown signal (SIGTERM) before it is killed, 1 to 900", "title": "Termination Grace Period"}}, "title": "PodUpdateSchema", "type": "object"}, "EnvsSetSchema": {"additionalProperties": false, "properties": {"envs": {"additionalProperties": {"type": "string"}, "description": "The complete set of environment variables the app must end up with: keys missing from the mapping are deleted", "title": "Envs", "type": "object"}}, "required": ["envs"], "title": "EnvsSetSchema", "type": "object"}, "EnvSchema": {"properties": {"key": {"description": "Name of the environment variable", "title": "Key", "type": "string"}, "value": {"description": "Value of the environment variable", "title": "Value", "type": "string"}, "apply_required": {"default": false, "description": "True when the change is stored but not live yet, exactly where the console asks for an Apply; next_step of the app says which call brings it live", "title": "Apply Required", "type": "boolean"}}, "required": ["key", "value"], "title": "EnvSchema", "type": "object"}, "EnvCreateSchema": {"additionalProperties": false, "properties": {"key": {"description": "Name of the environment variable", "title": "Key", "type": "string"}, "value": {"default": "", "description": "Value of the environment variable", "title": "Value", "type": "string"}}, "required": ["key"], "title": "EnvCreateSchema", "type": "object"}, "EnvUpdateSchema": {"additionalProperties": false, "properties": {"value": {"description": "New value of the environment variable", "title": "Value", "type": "string"}}, "required": ["value"], "title": "EnvUpdateSchema", "type": "object"}, "RedirectRuleCreateSchema": {"additionalProperties": false, "properties": {"from_host": {"description": "Host the request arrives on, e.g. foobar.com", "title": "From Host", "type": "string"}, "to_host": {"description": "Host the request is redirected to, e.g. www.foobar.com", "title": "To Host", "type": "string"}}, "required": ["from_host", "to_host"], "title": "RedirectRuleCreateSchema", "type": "object"}, "RedirectRuleUpdateSchema": {"additionalProperties": false, "properties": {"from_host": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New host the request arrives on", "title": "From Host"}, "to_host": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New host the request is redirected to", "title": "To Host"}}, "title": "RedirectRuleUpdateSchema", "type": "object"}, "DomainSchema": {"properties": {"id": {"description": "Identifier of the domain", "title": "Id", "type": "integer"}, "name": {"description": "Domain name, lowercase", "title": "Name", "type": "string"}, "status": {"description": "Whether the domain is validated or unvalidated", "title": "Status", "type": "string"}, "record_type": {"description": "DNS record JetDeploy expects on this name in direct mode: A or CNAME", "title": "Record Type", "type": "string"}, "routing_mode": {"description": "How traffic reaches JetDeploy: direct (the DNS record points at JetDeploy) or proxy (an external proxy, CDN or WAF sits in front and forwards to the JetDeploy origin)", "title": "Routing Mode", "type": "string"}, "app_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the app the domain is attached to, null when none", "title": "App Id"}, "is_validated": {"description": "Whether JetDeploy routes this domain already", "title": "Is Validated", "type": "boolean"}, "validation_failures": {"description": "How many times the daily re-check of the records failed in a row", "title": "Validation Failures", "type": "integer"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When an unvalidated domain is removed, null once it is validated", "title": "Expires At"}, "created_at": {"description": "When the domain was created", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "name", "status", "record_type", "routing_mode", "app_id", "is_validated", "validation_failures", "expires_at", "created_at"], "title": "DomainSchema", "type": "object"}, "DomainDetailSchema": {"properties": {"id": {"description": "Identifier of the domain", "title": "Id", "type": "integer"}, "name": {"description": "Domain name, lowercase", "title": "Name", "type": "string"}, "status": {"description": "Whether the domain is validated or unvalidated", "title": "Status", "type": "string"}, "record_type": {"description": "DNS record JetDeploy expects on this name in direct mode: A or CNAME", "title": "Record Type", "type": "string"}, "routing_mode": {"description": "How traffic reaches JetDeploy: direct (the DNS record points at JetDeploy) or proxy (an external proxy, CDN or WAF sits in front and forwards to the JetDeploy origin)", "title": "Routing Mode", "type": "string"}, "app_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the app the domain is attached to, null when none", "title": "App Id"}, "is_validated": {"description": "Whether JetDeploy routes this domain already", "title": "Is Validated", "type": "boolean"}, "validation_failures": {"description": "How many times the daily re-check of the records failed in a row", "title": "Validation Failures", "type": "integer"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When an unvalidated domain is removed, null once it is validated", "title": "Expires At"}, "created_at": {"description": "When the domain was created", "format": "date-time", "title": "Created At", "type": "string"}, "verification_record": {"anyOf": [{"$ref": "#/components/schemas/VerificationRecordSchema"}, {"type": "null"}], "description": "TXT record proving you own the domain, null when none is required: it is always required in proxy mode, and in direct mode only while another organization claims this name or a related one, or held it recently"}, "dns_target": {"description": "Values the DNS record of this domain must point at. In direct mode they are the values of the A or CNAME record, and every one of them belongs in the zone when the record type is A; in proxy mode it is the origin your proxy, CDN or WAF must forward HTTPS traffic to", "items": {"type": "string"}, "title": "Dns Target", "type": "array"}}, "required": ["id", "name", "status", "record_type", "routing_mode", "app_id", "is_validated", "validation_failures", "expires_at", "created_at", "verification_record", "dns_target"], "title": "DomainDetailSchema", "type": "object"}, "VerificationRecordSchema": {"properties": {"name": {"description": "Name of the TXT record to create", "title": "Name", "type": "string"}, "value": {"description": "Value the TXT record must carry", "title": "Value", "type": "string"}}, "required": ["name", "value"], "title": "VerificationRecordSchema", "type": "object"}, "DomainCreateSchema": {"additionalProperties": false, "properties": {"name": {"description": "Domain name to claim, for example www.example.com", "title": "Name", "type": "string"}}, "required": ["name"], "title": "DomainCreateSchema", "type": "object"}, "DomainUpdateSchema": {"additionalProperties": false, "properties": {"routing_mode": {"description": "How traffic reaches JetDeploy: direct (the DNS record points at JetDeploy) or proxy (an external proxy, CDN or WAF sits in front and forwards to the JetDeploy origin)", "enum": ["direct", "proxy"], "title": "Routing Mode", "type": "string"}}, "required": ["routing_mode"], "title": "DomainUpdateSchema", "type": "object"}, "DomainAttachSchema": {"additionalProperties": false, "properties": {"domain_id": {"description": "Identifier of the domain to attach to the app", "title": "Domain Id", "type": "integer"}}, "required": ["domain_id"], "title": "DomainAttachSchema", "type": "object"}, "ServiceSchema": {"properties": {"id": {"description": "Identifier of the service", "title": "Id", "type": "integer"}, "name": {"description": "Name of the service, unique across JetDeploy", "title": "Name", "type": "string"}, "kind": {"description": "Engine of the service: mariadb, opensearch, postgresql, rabbitmq or redis", "title": "Kind", "type": "string"}, "status": {"description": "Current status of the service: created, ready, starting, stopping, stopped, unknown", "title": "Status", "type": "string"}, "wizard_step": {"description": "How far the service got in the creation wizard: console:service:detail once it is complete, an earlier step while it still misses its settings", "title": "Wizard Step", "type": "string"}, "exposed": {"description": "Whether the service is reachable from outside the platform", "title": "Exposed", "type": "boolean"}, "exposed_port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the service answers on from outside, null when it is not exposed", "title": "Exposed Port"}, "chart_version": {"description": "Version of the Helm chart the service runs", "title": "Chart Version", "type": "string"}, "application_version": {"description": "Version of the engine the service runs", "title": "Application Version", "type": "string"}, "created_at": {"description": "When the service was created", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "name", "kind", "status", "wizard_step", "exposed", "exposed_port", "chart_version", "application_version", "created_at"], "title": "ServiceSchema", "type": "object"}, "ServiceDetailSchema": {"properties": {"id": {"description": "Identifier of the service", "title": "Id", "type": "integer"}, "name": {"description": "Name of the service, unique across JetDeploy", "title": "Name", "type": "string"}, "kind": {"description": "Engine of the service: mariadb, opensearch, postgresql, rabbitmq or redis", "title": "Kind", "type": "string"}, "status": {"description": "Current status of the service: created, ready, starting, stopping, stopped, unknown", "title": "Status", "type": "string"}, "wizard_step": {"description": "How far the service got in the creation wizard: console:service:detail once it is complete, an earlier step while it still misses its settings", "title": "Wizard Step", "type": "string"}, "exposed": {"description": "Whether the service is reachable from outside the platform", "title": "Exposed", "type": "boolean"}, "exposed_port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the service answers on from outside, null when it is not exposed", "title": "Exposed Port"}, "chart_version": {"description": "Version of the Helm chart the service runs", "title": "Chart Version", "type": "string"}, "application_version": {"description": "Version of the engine the service runs", "title": "Application Version", "type": "string"}, "created_at": {"description": "When the service was created", "format": "date-time", "title": "Created At", "type": "string"}, "internal_host": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Host the other workloads of the organization reach the service at", "title": "Internal Host"}, "port": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Port the service listens on inside the cluster", "title": "Port"}, "credentials": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "description": "What the console shows to connect to this service, as key to value: the username and password when the engine has them, plus the database name or the management endpoints of the engine. Null until the service has its settings, and the password only works once the service is ready, since the deploy is what sets it on the engine", "title": "Credentials"}, "exposed_endpoint": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Endpoint the service answers on from outside, null when it is not exposed", "title": "Exposed Endpoint"}, "allowed_cidrs_when_exposed": {"description": "Public IPv4 networks allowed to reach the service while it is exposed, as stored: a single address is kept as a /32", "items": {"type": "string"}, "title": "Allowed Cidrs When Exposed", "type": "array"}, "storage_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Size of the volume in GiB. For redis this is the size actually given to the volume, computed from attrs.memory rather than the storage_size sent at creation. Null when the service has no volume", "title": "Storage Size"}, "pending_operation": {"anyOf": [{"$ref": "#/components/schemas/OperationSchema"}, {"type": "null"}], "description": "Operation still running on the service, null when there is none"}, "deploy_failed": {"description": "True when the last deploy failed and nothing is installed: retry it with POST /api/v1/services/<id>/deploy", "title": "Deploy Failed", "type": "boolean"}, "is_on_catalog_chart": {"description": "Whether the installed release is on the chart version the catalog carries today", "title": "Is On Catalog Chart", "type": "boolean"}}, "required": ["id", "name", "kind", "status", "wizard_step", "exposed", "exposed_port", "chart_version", "application_version", "created_at", "internal_host", "port", "credentials", "exposed_endpoint", "allowed_cidrs_when_exposed", "storage_size", "pending_operation", "deploy_failed", "is_on_catalog_chart"], "title": "ServiceDetailSchema", "type": "object"}, "ServiceCreateSchema": {"additionalProperties": false, "properties": {"name": {"description": "Name of the service: lowercase letters, digits and hyphens, unique across JetDeploy", "title": "Name", "type": "string"}, "kind": {"description": "Engine of the service: mariadb, opensearch, postgresql, rabbitmq or redis", "title": "Kind", "type": "string"}, "storage_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Size of the volume in GiB. Left out it takes the default of the engine; redis ignores it and sizes its volume from attrs.memory instead", "title": "Storage Size"}, "attrs": {"additionalProperties": true, "description": "Settings of the engine, as GET /api/v1/catalog/services lists them for this kind. Every key left out takes the default of that kind", "title": "Attrs", "type": "object"}}, "required": ["name", "kind"], "title": "ServiceCreateSchema", "type": "object"}, "ServiceExposeSchema": {"additionalProperties": false, "properties": {"allowed_cidrs": {"description": "Public IPv4 addresses or CIDR ranges allowed to reach the service, at least one. Private and reserved ranges, 0.0.0.0/0 and ranges wider than /8 are refused, and a single address is stored as a /32", "items": {"type": "string"}, "title": "Allowed Cidrs", "type": "array"}}, "required": ["allowed_cidrs"], "title": "ServiceExposeSchema", "type": "object"}, "CatalogAttrSchema": {"properties": {"name": {"description": "Key to send inside attrs", "title": "Name", "type": "string"}, "type": {"description": "Type of the value: string, integer or boolean", "title": "Type", "type": "string"}, "default": {"anyOf": [{"type": "integer"}, {"type": "string"}, {"type": "boolean"}, {"type": "null"}], "description": "Value used when the key is left out", "title": "Default"}, "required": {"description": "Whether the value has to be a non-empty one", "title": "Required", "type": "boolean"}, "minimum": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Smallest value accepted, null when the setting has no lower bound", "title": "Minimum"}, "maximum": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Largest value accepted, null when the setting has no upper bound", "title": "Maximum"}, "description": {"description": "What the setting does, as the console explains it", "title": "Description", "type": "string"}}, "required": ["name", "type", "default", "required", "minimum", "maximum", "description"], "title": "CatalogAttrSchema", "type": "object"}, "CatalogServiceSchema": {"properties": {"kind": {"description": "Engine to send as kind to POST /api/v1/services", "title": "Kind", "type": "string"}, "category": {"description": "Family of the engine: sql-databases, nosql-in-memory or message-broker", "title": "Category", "type": "string"}, "chart": {"description": "Name of the Helm chart the engine is installed from", "title": "Chart", "type": "string"}, "chart_version": {"description": "Version of the Helm chart a new service gets", "title": "Chart Version", "type": "string"}, "application_version": {"description": "Version of the engine a new service gets", "title": "Application Version", "type": "string"}, "expose_method": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "How the service is published when it is exposed: nodeport (a port on the load balancer) or ingress (HTTPS on its own host)", "title": "Expose Method"}, "attrs": {"description": "Settings this engine takes, as the keys of the attrs object of POST /api/v1/services. Every key left out takes its default", "items": {"$ref": "#/components/schemas/CatalogAttrSchema"}, "title": "Attrs", "type": "array"}}, "required": ["kind", "category", "chart", "chart_version", "application_version", "expose_method", "attrs"], "title": "CatalogServiceSchema", "type": "object"}, "GitTokenSchema": {"properties": {"hint": {"description": "First characters of the secret, enough to tell tokens apart; never the secret", "title": "Hint", "type": "string"}, "created_at": {"description": "When the token was issued", "format": "date-time", "title": "Created At", "type": "string"}, "last_used_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the token was last used, null when it never was", "title": "Last Used At"}, "secret": {"description": "The Git Access Token itself, the password of `git push` with username `git`", "title": "Secret", "type": "string"}}, "required": ["hint", "created_at", "last_used_at", "secret"], "title": "GitTokenSchema", "type": "object"}, "ProfileSchema": {"properties": {"id": {"description": "Identifier of the user the token belongs to", "title": "Id", "type": "integer"}, "email": {"description": "Email address of the user", "title": "Email", "type": "string"}, "username": {"description": "Unique handle of the user", "title": "Username", "type": "string"}, "fullname": {"description": "Full name of the user, empty when never set", "title": "Fullname", "type": "string"}, "organization": {"anyOf": [{"$ref": "#/components/schemas/OrganizationRefSchema"}, {"type": "null"}], "description": "Organization the user is currently working on, null when none is selected"}, "git_token": {"anyOf": [{"$ref": "#/components/schemas/GitTokenSchema"}, {"type": "null"}], "description": "Token that authenticates git pushes, secret included since it is never hidden, null when the user has none"}, "api_token": {"anyOf": [{"$ref": "#/components/schemas/TokenSchema"}, {"type": "null"}], "description": "Token that authenticates this API, null when the user has none"}}, "required": ["id", "email", "username", "fullname", "organization", "git_token", "api_token"], "title": "ProfileSchema", "type": "object"}, "TokenSchema": {"properties": {"hint": {"description": "First characters of the secret, enough to tell tokens apart; never the secret", "title": "Hint", "type": "string"}, "created_at": {"description": "When the token was issued", "format": "date-time", "title": "Created At", "type": "string"}, "last_used_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the token was last used, null when it never was", "title": "Last Used At"}}, "required": ["hint", "created_at", "last_used_at"], "title": "TokenSchema", "type": "object"}, "RegeneratedTokenSchema": {"properties": {"secret": {"description": "The new secret, returned only here and never again", "title": "Secret", "type": "string"}, "hint": {"description": "First characters of the new secret, what the profile shows from now on", "title": "Hint", "type": "string"}, "created_at": {"description": "When the new token was issued", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["secret", "hint", "created_at"], "title": "RegeneratedTokenSchema", "type": "object"}, "RegeneratedApiTokenSchema": {"properties": {"secret": {"description": "The new secret, returned only here and never again", "title": "Secret", "type": "string"}, "hint": {"description": "First characters of the new secret, what the profile shows from now on", "title": "Hint", "type": "string"}, "created_at": {"description": "When the new token was issued", "format": "date-time", "title": "Created At", "type": "string"}, "warning": {"description": "What breaks right now and what has to be done with the secret", "title": "Warning", "type": "string"}}, "required": ["secret", "hint", "created_at", "warning"], "title": "RegeneratedApiTokenSchema", "type": "object"}, "ConnectionSchema": {"properties": {"id": {"description": "Identifier of the connection, the one to revoke it with, stable across token renewals", "format": "uuid", "title": "Id", "type": "string"}, "client_id": {"description": "Identifier of the client, its metadata document URL when it has one", "title": "Client Id", "type": "string"}, "client_name": {"description": "Name the client declared, empty when it declared none", "title": "Client Name", "type": "string"}, "scopes": {"description": "What the connection is allowed to do: read, write, offline_access", "items": {"type": "string"}, "title": "Scopes", "type": "array"}, "resource": {"description": "The resource the token was issued for", "title": "Resource", "type": "string"}, "created_at": {"description": "When the connection was authorized", "format": "date-time", "title": "Created At", "type": "string"}, "last_used_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the connection was last used, null when it never was", "title": "Last Used At"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the connection expires unless the agent renews it before", "title": "Expires At"}}, "required": ["id", "client_id", "client_name", "scopes", "resource", "created_at", "last_used_at", "expires_at"], "title": "ConnectionSchema", "type": "object"}, "NodePlanSchema": {"properties": {"node_size": {"$ref": "#/components/schemas/NodeSizeSchema", "description": "Size the organization is on"}, "price_per_month": {"description": "Price the organization pays per month, VAT excluded", "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "title": "Price Per Month", "type": "string"}, "currency": {"description": "Currency of the price", "title": "Currency", "type": "string"}, "effective_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Day the plan started, null when it was never set", "title": "Effective From"}}, "required": ["node_size", "price_per_month", "currency", "effective_from"], "title": "NodePlanSchema", "type": "object"}, "NodeSizeSchema": {"properties": {"name": {"description": "Name of the size, as offered to customers", "title": "Name", "type": "string"}, "instance_type": {"description": "EC2 instance type the nodes of this size run on", "title": "Instance Type", "type": "string"}, "cpu": {"description": "vCPU of this size", "title": "Cpu", "type": "number"}, "memory": {"description": "GiB of memory of this size", "title": "Memory", "type": "number"}, "price_per_month": {"description": "Price of the size per month, VAT excluded", "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "title": "Price Per Month", "type": "string"}, "currency": {"description": "Currency of the price", "title": "Currency", "type": "string"}}, "required": ["name", "instance_type", "cpu", "memory", "price_per_month", "currency"], "title": "NodeSizeSchema", "type": "object"}, "PricingSchema": {"properties": {"sizes": {"description": "Every size you can choose", "items": {"$ref": "#/components/schemas/NodeSizeSchema"}, "title": "Sizes", "type": "array"}, "plan": {"anyOf": [{"$ref": "#/components/schemas/NodePlanSchema"}, {"type": "null"}], "description": "Plan the organization is on, null when it has no active plan"}}, "required": ["sizes", "plan"], "title": "PricingSchema", "type": "object"}, "BillingDetailsSchema": {"properties": {"billing_company": {"description": "Company the invoices are issued to", "title": "Billing Company", "type": "string"}, "billing_first_name": {"description": "First name of the billing contact", "title": "Billing First Name", "type": "string"}, "billing_last_name": {"description": "Last name of the billing contact", "title": "Billing Last Name", "type": "string"}, "billing_address_1": {"description": "Address line 1", "title": "Billing Address 1", "type": "string"}, "billing_address_2": {"description": "Address line 2, empty when unused", "title": "Billing Address 2", "type": "string"}, "billing_city": {"description": "City", "title": "Billing City", "type": "string"}, "billing_province": {"description": "Province", "title": "Billing Province", "type": "string"}, "billing_country": {"description": "Country", "title": "Billing Country", "type": "string"}, "billing_zip": {"description": "Zip or postal code", "title": "Billing Zip", "type": "string"}, "billing_vat": {"description": "VAT or GST number", "title": "Billing Vat", "type": "string"}, "billing_email": {"description": "Address the invoices are sent to", "title": "Billing Email", "type": "string"}, "billing_sdi": {"description": "Italian SDI code (Codice Univoco), empty when unused", "title": "Billing Sdi", "type": "string"}}, "required": ["billing_company", "billing_first_name", "billing_last_name", "billing_address_1", "billing_address_2", "billing_city", "billing_province", "billing_country", "billing_zip", "billing_vat", "billing_email", "billing_sdi"], "title": "BillingDetailsSchema", "type": "object"}, "BillingSchema": {"properties": {"details": {"$ref": "#/components/schemas/BillingDetailsSchema", "description": "Details the invoices of the organization are issued to"}, "payment_methods": {"description": "Active cards of the organization", "items": {"$ref": "#/components/schemas/PaymentMethodSchema"}, "title": "Payment Methods", "type": "array"}, "preferred_payment_method_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Identifier of the card charged first, null when the organization has no card", "title": "Preferred Payment Method Id"}}, "required": ["details", "payment_methods", "preferred_payment_method_id"], "title": "BillingSchema", "type": "object"}, "PaymentMethodSchema": {"properties": {"id": {"description": "Identifier of the payment method", "title": "Id", "type": "integer"}, "brand": {"description": "Card brand as Stripe reports it, e.g. visa or mastercard", "title": "Brand", "type": "string"}, "last4": {"description": "Last four digits of the card number", "title": "Last4", "type": "string"}, "exp_month": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Month the card expires in, null when Stripe reported none", "title": "Exp Month"}, "exp_year": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Year the card expires in, null when Stripe reported none", "title": "Exp Year"}, "is_preferred": {"description": "Whether this card is charged first", "title": "Is Preferred", "type": "boolean"}, "created_at": {"description": "When the card was added", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "brand", "last4", "exp_month", "exp_year", "is_preferred", "created_at"], "title": "PaymentMethodSchema", "type": "object"}, "BillingDetailsUpdateSchema": {"additionalProperties": false, "properties": {"billing_company": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Company the invoices are issued to", "title": "Billing Company"}, "billing_first_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "First name of the billing contact", "title": "Billing First Name"}, "billing_last_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Last name of the billing contact", "title": "Billing Last Name"}, "billing_address_1": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 1", "title": "Billing Address 1"}, "billing_address_2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2, empty when unused", "title": "Billing Address 2"}, "billing_city": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "City", "title": "Billing City"}, "billing_province": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Province", "title": "Billing Province"}, "billing_country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Country", "title": "Billing Country"}, "billing_zip": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Zip or postal code", "title": "Billing Zip"}, "billing_vat": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT or GST number", "title": "Billing Vat"}, "billing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address the invoices are sent to", "title": "Billing Email"}, "billing_sdi": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Italian SDI code (Codice Univoco), empty when unused", "title": "Billing Sdi"}}, "title": "BillingDetailsUpdateSchema", "type": "object"}, "AddPaymentMethodSchema": {"additionalProperties": false, "properties": {"stripe_payment_method_id": {"description": "Stripe payment method id (pm_...) created on the client with Stripe.js", "pattern": "pm_[A-Za-z0-9_]{1,240}", "title": "Stripe Payment Method Id", "type": "string"}}, "required": ["stripe_payment_method_id"], "title": "AddPaymentMethodSchema", "type": "object"}, "PagingSchema": {"properties": {"cursor": {"anyOf": [{"pattern": "^[0-9]{1,20}(:[A-Za-z0-9_-]{1,64})?$", "type": "string"}, {"type": "null"}], "description": "Opaque position to page from, \"<nanosecond timestamp>:<line key>\" as returned in next_cursor or prev_cursor; backward reads the lines older than it, forward the lines newer than it. A bare nanosecond timestamp is accepted too and reads as the position just before every line of that nanosecond", "title": "Cursor"}, "direction": {"default": "backward", "description": "backward reads from the newest line down, forward from the oldest line up", "title": "Direction", "type": "string"}, "limit": {"anyOf": [{"maximum": 1000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "How many lines to return, at most 1000; defaults to the console page size", "title": "Limit"}}, "title": "PagingSchema", "type": "object"}, "RuntimeLogFiltersSchema": {"properties": {"from": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "to": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "contains": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "level": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}, "pod": {"description": "Read only these pods of the app, repeatable; empty means every pod", "items": {"type": "integer"}, "title": "Pod", "type": "array"}}, "title": "RuntimeLogFiltersSchema", "type": "object"}, "LogPageSchema": {"properties": {"rows": {"description": "The log lines, oldest first, with the same masking of secrets the console applies", "items": {"$ref": "#/components/schemas/LogRowSchema"}, "title": "Rows", "type": "array"}, "next_cursor": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cursor of the next page in the same direction; on an empty page the cursor of the request is echoed back, so a client tailing forward keeps its position, and null when the request had none. With a search, an empty page can also come back before the end, after a long stretch of lines the search skipped: its cursor is then past that stretch, so keep paging while next_cursor changes", "title": "Next Cursor"}, "prev_cursor": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cursor of the page in the opposite direction, null when the page is empty", "title": "Prev Cursor"}, "window": {"$ref": "#/components/schemas/WindowSchema", "description": "The window the filters resolved to"}}, "required": ["rows", "next_cursor", "prev_cursor", "window"], "title": "LogPageSchema", "type": "object"}, "LogRowSchema": {"properties": {"ns": {"description": "Timestamp of the line in nanoseconds, the value to pass as ns to the context endpoint", "title": "Ns", "type": "string"}, "timestamp": {"description": "When the line was logged", "format": "date-time", "title": "Timestamp", "type": "string"}, "level": {"description": "Level detected on the line, unknown when there is none", "title": "Level", "type": "string"}, "message": {"description": "Text of the line, with any secret of the workload masked", "title": "Message", "type": "string"}, "pod": {"description": "Pod the line comes from, without the workload prefix", "title": "Pod", "type": "string"}, "container": {"description": "Container inside the pod the line comes from, empty when unknown", "title": "Container", "type": "string"}, "key": {"description": "Identifier of the line, the same one a log tail read with the same filters sends for it (a field:value search changes it), so a client that pages and then tails can skip the lines it already has", "title": "Key", "type": "string"}}, "required": ["ns", "timestamp", "level", "message", "pod", "container", "key"], "title": "LogRowSchema", "type": "object"}, "WindowSchema": {"properties": {"from": {"description": "Start of the window the lines come from", "format": "date-time", "title": "From", "type": "string"}, "to": {"description": "End of the window the lines come from", "format": "date-time", "title": "To", "type": "string"}}, "required": ["from", "to"], "title": "WindowSchema", "type": "object"}, "HistogramBucketSchema": {"properties": {"start": {"description": "Start of the bucket", "format": "date-time", "title": "Start", "type": "string"}, "end": {"description": "End of the bucket", "format": "date-time", "title": "End", "type": "string"}, "start_ns": {"description": "Start of the bucket in nanoseconds", "title": "Start Ns", "type": "string"}, "end_ns": {"description": "End of the bucket in nanoseconds", "title": "End Ns", "type": "string"}, "levels": {"additionalProperties": {"type": "integer"}, "description": "Count per detected level when counted is true; a single volume key with the bytes logged when it is false", "title": "Levels", "type": "object"}, "total": {"description": "Sum of the values in levels", "title": "Total", "type": "integer"}}, "required": ["start", "end", "start_ns", "end_ns", "levels", "total"], "title": "HistogramBucketSchema", "type": "object"}, "HistogramSchema": {"properties": {"buckets": {"description": "The buckets, oldest first", "items": {"$ref": "#/components/schemas/HistogramBucketSchema"}, "title": "Buckets", "type": "array"}, "step": {"description": "Width of every bucket in seconds", "title": "Step", "type": "integer"}, "counted": {"description": "True when the buckets count lines per level, false when they measure ingested bytes", "title": "Counted", "type": "boolean"}, "counting": {"description": "True when the filters apply but the buckets are not counted yet: repeat the request with counted=true to count the filtered lines", "title": "Counting", "type": "boolean"}, "window": {"$ref": "#/components/schemas/WindowSchema", "description": "The window the filters resolved to"}}, "required": ["buckets", "step", "counted", "counting", "window"], "title": "HistogramSchema", "type": "object"}, "LogContextSchema": {"properties": {"ns": {"description": "The line the context was asked around", "title": "Ns", "type": "string"}, "rows": {"description": "Up to 50 lines before and after it, oldest first", "items": {"$ref": "#/components/schemas/LogRowSchema"}, "title": "Rows", "type": "array"}}, "required": ["ns", "rows"], "title": "LogContextSchema", "type": "object"}, "DeployLogPageSchema": {"properties": {"operation": {"anyOf": [{"$ref": "#/components/schemas/OperationRefSchema"}, {"type": "null"}], "description": "The run the lines come from, null when the app has no run with logs"}, "operations": {"description": "The runs of the app still within the log retention, newest first", "items": {"$ref": "#/components/schemas/OperationRefSchema"}, "title": "Operations", "type": "array"}, "rows": {"description": "The log lines, oldest first, with the same masking of secrets the console applies", "items": {"$ref": "#/components/schemas/DeployLogRowSchema"}, "title": "Rows", "type": "array"}, "next_cursor": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cursor of the next page in the same direction; on an empty page the cursor of the request is echoed back, so a client tailing forward keeps its position, and null when the request had none. With a search, an empty page can also come back before the end, after a long stretch of lines the search skipped: its cursor is then past that stretch, so keep paging while next_cursor changes", "title": "Next Cursor"}, "prev_cursor": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cursor of the page in the opposite direction, null when the page is empty", "title": "Prev Cursor"}, "window": {"anyOf": [{"$ref": "#/components/schemas/WindowSchema"}, {"type": "null"}], "description": "The window of the run, null when there is no run to read"}}, "required": ["operation", "operations", "rows", "next_cursor", "prev_cursor", "window"], "title": "DeployLogPageSchema", "type": "object"}, "DeployLogRowSchema": {"properties": {"ns": {"description": "Timestamp of the line in nanoseconds, the value to pass as ns to the context endpoint", "title": "Ns", "type": "string"}, "timestamp": {"description": "When the line was logged", "format": "date-time", "title": "Timestamp", "type": "string"}, "level": {"description": "Level detected on the line, unknown when there is none", "title": "Level", "type": "string"}, "message": {"description": "Text of the line, with any secret of the workload masked", "title": "Message", "type": "string"}, "pod": {"description": "Pod the line comes from, without the workload prefix", "title": "Pod", "type": "string"}, "container": {"description": "Container inside the pod the line comes from, empty when unknown", "title": "Container", "type": "string"}, "key": {"description": "Identifier of the line, the same one a log tail read with the same filters sends for it (a field:value search changes it), so a client that pages and then tails can skip the lines it already has", "title": "Key", "type": "string"}, "stream": {"description": "Where the line comes from: build (the image build), predeploy (the predeploy script) or outcome (the final line the console adds when the run is over)", "title": "Stream", "type": "string"}}, "required": ["ns", "timestamp", "level", "message", "pod", "container", "key", "stream"], "title": "DeployLogRowSchema", "type": "object"}, "OperationRefSchema": {"properties": {"id": {"description": "Identifier of the operation, the value to pass as operation", "title": "Id", "type": "integer"}, "kind": {"description": "deploy for a push build, apply for a configuration change", "title": "Kind", "type": "string"}, "status": {"description": "Status the operation ended in, or is in", "title": "Status", "type": "string"}, "created_at": {"description": "When the run started", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "kind", "status", "created_at"], "title": "OperationRefSchema", "type": "object"}, "LogFiltersSchema": {"properties": {"from": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start of the window, an ISO 8601 datetime; without an offset it is read in the server timezone. Defaults, as the console does, to the last 6 hours of logs", "title": "From"}, "to": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End of the window, an ISO 8601 datetime; defaults to now", "title": "To"}, "contains": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search expression, the same syntax as the console search box: words, \"quoted phrases\", field:value on JSON lines, a leading - to exclude", "title": "Contains"}, "level": {"description": "Keep only these levels, repeatable; one or more of error, warn, info, debug, other. Empty means every level", "items": {"type": "string"}, "title": "Level", "type": "array"}}, "title": "LogFiltersSchema", "type": "object"}, "WorkloadRefSchema": {"properties": {"key": {"description": "Key of the workload inside resources: the pod id, or the service id", "title": "Key", "type": "string"}, "label": {"description": "Name of the pod or of the service", "title": "Label", "type": "string"}}, "required": ["key", "label"], "title": "WorkloadRefSchema", "type": "object"}, "WorkloadSeriesSchema": {"properties": {"available": {"description": "Whether the series could be built at all: false without an active plan, nodes or pods", "title": "Available", "type": "boolean"}, "failed": {"description": "Whether one of the metric queries failed; the series is then partial", "title": "Failed", "type": "boolean"}, "range": {"description": "Window of the series", "title": "Range", "type": "string"}, "label": {"description": "Human readable name of the window", "title": "Label", "type": "string"}, "step": {"description": "Seconds between two points", "title": "Step", "type": "integer"}, "units": {"additionalProperties": {"type": "string"}, "description": "Unit of every resource, keyed by resource", "title": "Units", "type": "object"}, "workloads": {"description": "The workloads the series are split by", "items": {"$ref": "#/components/schemas/WorkloadRefSchema"}, "title": "Workloads", "type": "array"}, "resources": {"additionalProperties": {"additionalProperties": {"items": {"maxItems": 2, "minItems": 2, "prefixItems": [{"type": "integer"}, {"anyOf": [{"type": "number"}, {"type": "null"}]}], "type": "array"}, "type": "array"}, "type": "object"}, "description": "The usage per workload and per resource: the outer key is the resource (cpu, memory), the inner key is the workload key, the value is one [timestamp, value] pair per step of the window, oldest first. The timestamp is in milliseconds since the epoch, the value is the percentage of what the nodes of the organization can give to workloads, null where no sample arrived", "title": "Resources", "type": "object"}, "start": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "First timestamp of the series, in milliseconds; null when unavailable", "title": "Start"}, "end": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Last timestamp of the series, in milliseconds; null when unavailable", "title": "End"}}, "required": ["available", "failed", "range", "label", "step", "units", "workloads", "resources"], "title": "WorkloadSeriesSchema", "type": "object"}, "OrganizationResourcesSchema": {"properties": {"organization": {"$ref": "#/components/schemas/OrganizationRefSchema", "description": "The organization the resources belong to"}, "range": {"description": "Window the usage was measured over", "title": "Range", "type": "string"}, "available": {"description": "Whether usage can be measured at all: false without an active plan or nodes", "title": "Available", "type": "boolean"}, "failed": {"description": "Whether reading the metrics failed; the values are then partial", "title": "Failed", "type": "boolean"}, "plan": {"anyOf": [{"$ref": "#/components/schemas/PlanSchema"}, {"type": "null"}], "description": "The active node plan, null when there is none"}, "cards": {"description": "One card per resource, as the console shows them", "items": {"$ref": "#/components/schemas/ResourceCardSchema"}, "title": "Cards", "type": "array"}, "metrics_retention_days": {"description": "How many days of metrics are kept", "title": "Metrics Retention Days", "type": "integer"}}, "required": ["organization", "range", "available", "failed", "plan", "cards", "metrics_retention_days"], "title": "OrganizationResourcesSchema", "type": "object"}, "PlanSchema": {"properties": {"name": {"description": "Name of the node plan the organization runs on", "title": "Name", "type": "string"}, "processor": {"description": "Processor of the nodes, empty when unknown", "title": "Processor", "type": "string"}, "cpu": {"description": "vCPU the plan provides", "title": "Cpu", "type": "number"}, "memory": {"description": "GiB of memory the plan provides", "title": "Memory", "type": "number"}}, "required": ["name", "processor", "cpu", "memory"], "title": "PlanSchema", "type": "object"}, "ResourceCardSchema": {"properties": {"key": {"description": "Resource the card is about: cpu or memory", "title": "Key", "type": "string"}, "label": {"description": "Name of the resource", "title": "Label", "type": "string"}, "unit": {"description": "Unit the usage is expressed in", "title": "Unit", "type": "string"}, "hint": {"description": "What the current value covers, e.g. a 5-minute average", "title": "Hint", "type": "string"}, "capacity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "How much of the resource the plan provides, null when no plan is active", "title": "Capacity"}, "capacity_unit": {"description": "Unit of capacity: vCPU for cpu, GiB for memory", "title": "Capacity Unit", "type": "string"}, "usage_percent": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Share of what the nodes can give to workloads that is in use right now, the number the console card shows; null when no measurement is available", "title": "Usage Percent"}}, "required": ["key", "label", "unit", "hint", "capacity", "capacity_unit", "usage_percent"], "title": "ResourceCardSchema", "type": "object"}, "OrganizationSeriesSchema": {"properties": {"available": {"description": "Whether the series could be built at all", "title": "Available", "type": "boolean"}, "failed": {"description": "Whether one of the metric queries failed", "title": "Failed", "type": "boolean"}, "range": {"description": "Window of the series", "title": "Range", "type": "string"}, "label": {"description": "Human readable name of the window", "title": "Label", "type": "string"}, "step": {"description": "Seconds between two points", "title": "Step", "type": "integer"}, "units": {"additionalProperties": {"type": "string"}, "description": "Unit of every resource, keyed by resource", "title": "Units", "type": "object"}, "resources": {"additionalProperties": {"$ref": "#/components/schemas/ResourceSeriesSchema"}, "description": "The series per resource: cpu and memory", "title": "Resources", "type": "object"}, "start": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "First timestamp of the series, in milliseconds; null when unavailable", "title": "Start"}, "end": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Last timestamp of the series, in milliseconds; null when unavailable", "title": "End"}}, "required": ["available", "failed", "range", "label", "step", "units", "resources"], "title": "OrganizationSeriesSchema", "type": "object"}, "ResourceSeriesSchema": {"properties": {"usage": {"description": "One [timestamp, value] pair per step of the window, oldest first: the timestamp is in milliseconds since the epoch, the value is the percentage used, null where no sample arrived", "items": {"maxItems": 2, "minItems": 2, "prefixItems": [{"type": "integer"}, {"anyOf": [{"type": "number"}, {"type": "null"}]}], "type": "array"}, "title": "Usage", "type": "array"}, "current": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Percentage used right now, null when no measurement is available", "title": "Current"}}, "required": ["usage", "current"], "title": "ResourceSeriesSchema", "type": "object"}, "ExecRequestSchema": {"additionalProperties": false, "properties": {"command": {"description": "The argv handed to the container as is. No shell is involved: pass [\"sh\", \"-c\", \"<script>\"] when you need one", "items": {"type": "string"}, "minItems": 1, "title": "Command", "type": "array"}, "stdin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Text written to the standard input of the command, which is then closed", "title": "Stdin"}, "timeout": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Seconds the command may run before the stream ends with reason \"timeout\". Defaults to 60; a larger value is clamped to 600. The stream stops there but the command is not killed and may keep running in the container: wrap it with the timeout utility of the image, as in [\"sh\", \"-c\", \"timeout 60 <command>\"], when it must be stopped", "title": "Timeout"}}, "required": ["command"], "title": "ExecRequestSchema", "type": "object"}}, "securitySchemes": {"BearerAuth": {"type": "http", "scheme": "bearer"}}}, "servers": []}