{
  "openapi": "3.1.1",
  "info": {
    "title": "SkyState.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://console.skystate.io/api"
    }
  ],
  "paths": {
    "/v1/{accountId}/projects/{slug}/public-state/{env}": {
      "get": {
        "tags": [
          "Public State"
        ],
        "summary": "Get the current public state for an environment.",
        "description": "Returns the current public-state document for the project/environment. 204 when the project exists but no state has been written yet.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStateBody"
                }
              }
            }
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          },
          {
            "apiKey": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Public State"
        ],
        "summary": "Replace the public state for an environment.",
        "description": "Full replace of the public-state document. Requires a write precondition: If-Match with the version you expect to modify, or If-None-Match: * to create when no state exists yet. A missing or malformed precondition returns 400; a stale version or failed create precondition returns 412.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Update precondition. Send a quoted positive version (for example, \"3\"). Use either this header or If-None-Match. If both are sent, If-Match is evaluated first. Version \"0\" never creates state and fails with 412.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "description": "Create-only precondition. Send only * to create when no state exists; existing state fails with 412. Use either this header or If-Match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateConfigBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStateBody"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "412": {
            "description": "Precondition Failed",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConflictResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          },
          "415": {
            "description": "The request body Content-Type is not application/json, so the body could not be bound. Possible error codes: unsupported_media_type.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "unsupported_media_type"
            ]
          },
          "413": {
            "description": "The request body exceeds the server's request-size limit. Possible error codes: payload_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "payload_too_large"
            ]
          },
          "408": {
            "description": "The request body was not received within the server's body-read timeout or minimum data rate. Possible error codes: request_timeout.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "request_timeout"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          },
          {
            "apiKey": [ ]
          }
        ]
      },
      "patch": {
        "tags": [
          "Public State"
        ],
        "summary": "Apply a JSON Patch to the public state for an environment.",
        "description": "Applies RFC 6902 JSON Patch operations to the public-state document. Requires a write precondition: If-Match with the version you expect to modify, or If-None-Match: * to create when no state exists yet. A missing or malformed precondition returns 400; a stale version or failed create precondition returns 412. The server is RFC-6902 strict, so a remove against an absent path fails (idempotency is the client's responsibility).",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Update precondition. Send a quoted positive version (for example, \"3\"). Use either this header or If-None-Match. If both are sent, If-Match is evaluated first. Version \"0\" never creates state and fails with 412.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "description": "Create-only precondition. Send only * to create when no state exists; existing state fails with 412. Use either this header or If-Match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchStateBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStateBody"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error, patch_invalid, patch_unsupported_operation, patch_invalid_path, patch_missing_value, patch_path_not_found, patch_path_untraversable, patch_invalid_array_index, patch_invalid_state_root, patch_state_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error",
              "patch_invalid",
              "patch_unsupported_operation",
              "patch_invalid_path",
              "patch_missing_value",
              "patch_path_not_found",
              "patch_path_untraversable",
              "patch_invalid_array_index",
              "patch_invalid_state_root",
              "patch_state_too_large"
            ]
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "412": {
            "description": "Precondition Failed",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConflictResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          },
          "415": {
            "description": "The request body Content-Type is not application/json, so the body could not be bound. Possible error codes: unsupported_media_type.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "unsupported_media_type"
            ]
          },
          "413": {
            "description": "The request body exceeds the server's request-size limit. Possible error codes: payload_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "payload_too_large"
            ]
          },
          "408": {
            "description": "The request body was not received within the server's body-read timeout or minimum data rate. Possible error codes: request_timeout.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "request_timeout"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          },
          {
            "apiKey": [ ]
          }
        ]
      }
    },
    "/v1/{accountId}/projects/{slug}/public-state/{env}/versions": {
      "get": {
        "tags": [
          "Public State"
        ],
        "summary": "List public-state versions for an environment.",
        "description": "Returns every stored version of the public-state document for the environment, newest to oldest. An empty array when the project exists but no state has been written yet (not 204, since this is a list endpoint).",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicStateBody"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          },
          {
            "apiKey": [ ]
          }
        ]
      }
    },
    "/v1/{accountId}/projects/{slug}/user-states/{env}": {
      "get": {
        "tags": [
          "User State"
        ],
        "summary": "List end-users with state in an environment.",
        "description": "Paginated list of end-users that have state in the given environment, newest first.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of items to return. Defaults to 50 when absent; values outside 1-50 are silently clamped into that range.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque pagination cursor taken from the previous response's cursor field. Omit to start from the newest end-user. A malformed value returns a 400 validation_error.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStateListBody"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          }
        ]
      }
    },
    "/v1/{accountId}/projects/{slug}/user-states/{env}/{endUserId}": {
      "get": {
        "tags": [
          "User State"
        ],
        "summary": "Get a specific end-user's latest state.",
        "description": "Returns the given end-user's state in the environment. 204 when no state has been written for this end-user yet; there is no separate check for whether the end-user id itself is known.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "endUserId",
            "in": "path",
            "description": "End-user identifier. Trimmed before validation; the trimmed value must be non-empty, at most 512 characters, and contain no control characters. A value that fails this check returns a 404, the same status returned when the project itself does not exist. A well-formed but unrecognized end-user id instead returns 204: there is no separate check for whether the id is known.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStateBody"
                }
              }
            }
          },
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          }
        ]
      }
    },
    "/v1/{accountId}/projects/{slug}/user-states/{endUserId}": {
      "delete": {
        "tags": [
          "User State"
        ],
        "summary": "Delete an end-user's state.",
        "description": "Removes the end-user's state across every environment in the project.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "endUserId",
            "in": "path",
            "description": "End-user identifier. Trimmed before validation; the trimmed value must be non-empty, at most 512 characters, and contain no control characters. A value that fails this check is rejected with a 400 validation_error.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "bearer": [ ]
          }
        ]
      }
    },
    "/v1/{accountId}/projects/{slug}/user-state/{env}": {
      "get": {
        "tags": [
          "User State"
        ],
        "summary": "Get the authenticated end-user's own state.",
        "description": "Returns the calling end-user's state for the environment their token is scoped to. 204 when no state has been written for this end-user yet.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 from route-format validation before the handler runs. A valid lowercase value that does not match the env: scope of the presented end-user token returns 404.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStateBody"
                }
              }
            }
          },
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [
          {
            "endUserBearer": [ ]
          }
        ]
      },
      "patch": {
        "tags": [
          "User State"
        ],
        "summary": "Apply a JSON Patch to the authenticated end-user's own state.",
        "description": "Applies RFC 6902 JSON Patch operations to the calling end-user's state. Requires a write precondition: If-Match with the version you expect to modify, or If-None-Match: * to create when no state exists yet. A missing or malformed precondition returns 400; a stale version or failed create precondition returns 412. Every passing PATCH writes a new version and returns 200 (never 201 or 204).",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 from route-format validation before the handler runs. A valid lowercase value that does not match the env: scope of the presented end-user token returns 404.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          },
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Update precondition. Send a quoted positive version (for example, \"3\"). Use either this header or If-None-Match. If both are sent, If-Match is evaluated first. Version \"0\" never creates state and fails with 412.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "description": "Create-only precondition. Send only * to create when no state exists; existing state fails with 412. Use either this header or If-Match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchStateBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStateBody"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error, patch_invalid, patch_unsupported_operation, patch_invalid_path, patch_missing_value, patch_path_not_found, patch_path_untraversable, patch_invalid_array_index, patch_invalid_state_root, patch_state_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error",
              "patch_invalid",
              "patch_unsupported_operation",
              "patch_invalid_path",
              "patch_missing_value",
              "patch_path_not_found",
              "patch_path_untraversable",
              "patch_invalid_array_index",
              "patch_invalid_state_root",
              "patch_state_too_large"
            ]
          },
          "402": {
            "description": "Payment Required. Possible error codes: QUOTA_API_REQUESTS, QUOTA_END_USERS.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds until the monthly API-request quota resets. Sent only when the 402 carries QUOTA_API_REQUESTS; quotas that do not reset on a schedule return 402 without it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "QUOTA_API_REQUESTS",
              "QUOTA_END_USERS"
            ]
          },
          "412": {
            "description": "Precondition Failed",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConflictResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "description": "Authentication challenge. \"Bearer\" when no credential was presented; \"Bearer error=\"invalid_token\", ...\" when the presented token was rejected. Always advertises Bearer, even on operations that also accept an API key.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          },
          "415": {
            "description": "The request body Content-Type is not application/json, so the body could not be bound. Possible error codes: unsupported_media_type.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "unsupported_media_type"
            ]
          },
          "413": {
            "description": "The request body exceeds the server's request-size limit. Possible error codes: payload_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "payload_too_large"
            ]
          },
          "408": {
            "description": "The request body was not received within the server's body-read timeout or minimum data rate. Possible error codes: request_timeout.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "request_timeout"
            ]
          }
        },
        "security": [
          {
            "endUserBearer": [ ]
          }
        ]
      }
    },
    "/v1/readonly/{accountId}/projects/{slug}/public-state/{env}": {
      "get": {
        "tags": [
          "Public State"
        ],
        "summary": "Get the current public state for an environment (no authentication).",
        "description": "World-readable public-state read by canonical project identifier (account id + slug), for browser/SDK callers that hold neither a developer token nor an API key. 204 when the project exists but no state has been written yet.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "description": "Account identifier assigned at signup (e.g. \"acc_1a2b3c\"). Must match ^acc_[0-9A-Za-z]+$; a non-matching value returns a 400 validation_error before the handler runs.",
            "required": true,
            "schema": {
              "pattern": "^acc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "description": "Project slug, chosen when the project is created and permanent for the life of the project.",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9]+(?:[-_][a-z0-9]+)*$",
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "description": "Environment name. Must be exactly one of development, staging, or production (lowercase). Any other value, including a casing variant, returns 400 before the handler runs.",
            "required": true,
            "schema": {
              "enum": [
                "development",
                "staging",
                "production"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Optimistic-concurrency version token for this state resource, quoted per RFC 9110 (e.g. \"3\"). Send back on write via If-Match to detect a lost-update conflict (412).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnonymousPublicStateBody"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "404": {
            "description": "Not Found. Possible error codes: not_found.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "not_found"
            ]
          },
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error. Possible error codes: internal_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "internal_error"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [ ]
      }
    },
    "/v1/auth/token": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Exchange an authorization code or refresh token for SkyState access tokens.",
        "description": "Single OAuth 2.0 token endpoint for both grants: authorization_code (PKCE) for a fresh sign-in, and refresh_token to mint a new access token from a stored session. Body is application/x-www-form-urlencoded. Errors the endpoint returns itself use the RFC 6749 §5.2 JSON shape ({error, error_description}). A body that cannot be parsed as a form returns 400 invalid_request in that shape. Failures outside form parsing, such as a database outage, return the shared ErrorResponse envelope instead.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "required": [
                  "grant_type",
                  "client_id"
                ],
                "type": "object",
                "properties": {
                  "grant_type": {
                    "enum": [
                      "authorization_code",
                      "refresh_token"
                    ],
                    "description": "The two OAuth grants accepted by the unified token endpoint."
                  },
                  "client_id": {
                    "type": "string",
                    "description": "The OAuth client identifier: either the configured developer client id\n    (\"skystate-developer\") or a per-project end-user client, formatted \"{accountId}.{slug}\"."
                  },
                  "code": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "authorization_code grant only: the code minted by /auth/authorize/callback."
                  },
                  "redirect_uri": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "authorization_code grant only: must match the redirect_uri the code was issued for."
                  },
                  "code_verifier": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "authorization_code grant only: the PKCE code verifier."
                  },
                  "refresh_token": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "refresh_token grant only: the refresh token from a prior token response."
                  },
                  "scope": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "refresh_token grant, optional: when omitted the session's existing scope is\n    preserved; when supplied it must exactly match it."
                  },
                  "previous_access_token": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "refresh_token grant, optional SkyState extension: a previous end-user access\n    token to copy email/name forward from, since refresh has no Firebase uid to re-fetch."
                  }
                },
                "description": "One flat application/x-www-form-urlencoded body covers both grants: grant_type and client_id are\nalways required; code/redirect_uri/code_verifier are required for grant_type=authorization_code;\nrefresh_token is required for grant_type=refresh_token, with scope and the SkyState extension\nprevious_access_token both optional. Requiredness beyond the two common fields varies by grant\nand is enforced server-side at the form-parsing boundary, not expressible as a single JSON\nSchema \"required\" list, so every grant-specific field is nullable here."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenExchangeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: invalid_request, invalid_client, invalid_scope, invalid_grant, unsupported_grant_type.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            },
            "x-skystate-error-codes": [
              "invalid_request",
              "invalid_client",
              "invalid_scope",
              "invalid_grant",
              "unsupported_grant_type"
            ]
          },
          "401": {
            "description": "Unauthorized. Possible error codes: invalid_grant.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            },
            "x-skystate-error-codes": [
              "invalid_grant"
            ]
          },
          "500": {
            "description": "Internal Server Error. Possible error codes: server_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            },
            "x-skystate-error-codes": [
              "server_error"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          }
        },
        "security": [ ]
      }
    },
    "/v1/auth/logout": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Revoke a refresh token, ending the session.",
        "description": "Refresh-token revocation (RFC 7009 family revocation). A well-formed request is always 204, including when the token is already unknown or expired. An empty or malformed JSON body fails to bind before revocation runs and is rejected with a 400 validation_error.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LogoutRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Possible error codes: validation_error.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "validation_error"
            ]
          },
          "429": {
            "description": "The request exceeded its rate limit and was rejected. Possible error codes: rate_limited.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after the per-minute rate limit is exceeded.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "rate_limited"
            ]
          },
          "503": {
            "description": "The database is unavailable, so the request was not processed. Possible error codes: service_unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying after a database outage.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "service_unavailable"
            ]
          },
          "415": {
            "description": "The request body Content-Type is not application/json, so the body could not be bound. Possible error codes: unsupported_media_type.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "unsupported_media_type"
            ]
          },
          "413": {
            "description": "The request body exceeds the server's request-size limit. Possible error codes: payload_too_large.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "payload_too_large"
            ]
          },
          "408": {
            "description": "The request body was not received within the server's body-read timeout or minimum data rate. Possible error codes: request_timeout.",
            "headers": {
              "API-Version": {
                "description": "Version of the SkyState product API that served the response. Always \"1\" for this document.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "x-skystate-error-codes": [
              "request_timeout"
            ]
          }
        },
        "security": [ ]
      }
    }
  },
  "components": {
    "schemas": {
      "AnonymousPublicStateBody": {
        "required": [
          "version",
          "lastModified",
          "state"
        ],
        "type": "object",
        "properties": {
          "version": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Optimistic-concurrency version number for this state document, matching the\n    quoted value in the ETag response header.",
            "format": "int32"
          },
          "lastModified": {
            "type": [
              "null",
              "string"
            ],
            "description": "ISO 8601 timestamp this version was written. Always set: the anonymous\n    read returns 204, not this body, when the project has no state yet for this slot."
          },
          "state": {
            "description": "The state document for this version. Always a JSON object: PUT rejects a\n    non-object body and PATCH rejects any patch whose result is not an object (both 400\n    validation_error).",
            "$ref": "#/components/schemas/JsonElement"
          }
        },
        "description": "Public-state document returned by the world-readable anonymous read (no authentication). Carries\nthe same version and state as PublicStateBody, plus the write timestamp as a\npre-formatted string instead of a structured field, and no byte-size or comment."
      },
      "ConflictResponse": {
        "required": [
          "message"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Human-readable explanation of the version mismatch (e.g. the If-Match\n    version presented versus the state's actual current version)."
          }
        },
        "description": "Conflict response returned on 412 Precondition Failed."
      },
      "CreateConfigBody": {
        "required": [
          "state"
        ],
        "type": "object",
        "properties": {
          "state": {
            "description": "The full state document to write, replacing whatever is currently stored.\n    Must be a JSON object (not an array, string, number, boolean, or null); a non-object value is\n    rejected with 400 validation_error. Serialized size is capped at 256,000 characters; a larger\n    value is rejected with 400 validation_error.",
            "$ref": "#/components/schemas/JsonElement"
          },
          "comment": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional caller-supplied note stored alongside the new version. Omit for no\n    comment."
          }
        },
        "description": "PUT endpoint body - version is computed server-side. State must be a JSON object."
      },
      "ErrorResponse": {
        "required": [
          "error",
          "message"
        ],
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable, machine-readable error code (e.g. `validation_error`,\n    `not_found`). See the operation's own documented error-code list for the closed set it can\n    actually return."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation, safe to display but not guaranteed stable\n    across releases; code should branch on `error`, never on this text."
          }
        },
        "description": "Standard error envelope for 4xx/5xx responses, used everywhere except the RFC 6749\n    OAuth error shape (`error`/`error_description`) on the token endpoint."
      },
      "JsonElement": {
        "description": "An arbitrary JSON value: object, array, string, number, boolean, or null. Individual properties that use this schema may impose their own additional constraints; see that property's own description."
      },
      "JsonPatchOperation": {
        "required": [
          "op",
          "path"
        ],
        "type": "object",
        "properties": {
          "op": {
            "enum": [
              "add",
              "remove",
              "replace"
            ],
            "type": "string",
            "description": "The patch verb: `add`, `remove`, or `replace` (case-sensitive; any\n    other value, including a differently-cased spelling of one of these three, is rejected with a 400\n    patch_unsupported_operation)."
          },
          "path": {
            "type": "string",
            "description": "RFC 6901 JSON Pointer to the target location (e.g. `/settings/theme`), or\n    the empty string to target the document root. Must start with `/` unless empty; a value that\n    doesn't returns 400 patch_invalid_path."
          },
          "value": {
            "description": "The value to write for `add`/`replace`; required for both (a missing\n    value returns 400 patch_missing_value). Ignored, and may be omitted, for `remove`. May be any\n    JSON value: object, array, string, number, boolean, or null."
          }
        },
        "description": "One RFC 6902 JSON Patch operation."
      },
      "LogoutRequest": {
        "required": [
          "refreshToken"
        ],
        "type": "object",
        "properties": {
          "refreshToken": {
            "type": "string",
            "description": "The refresh token to revoke, ending that session. A well-formed request\n    is always 204, including when the token is already unknown, expired, or revoked."
          }
        },
        "description": "Request body for POST /auth/logout."
      },
      "OAuthError": {
        "required": [
          "error",
          "error_description"
        ],
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "RFC 6749 §5.2 error code. See the operation's own documented error-code list for the closed set this status can actually return."
          },
          "error_description": {
            "type": "string",
            "description": "Human-readable detail explaining the `error` code."
          }
        },
        "description": "RFC 6749 section 5.2 error response body."
      },
      "PatchStateBody": {
        "required": [
          "ops"
        ],
        "type": "object",
        "properties": {
          "ops": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonPatchOperation"
            },
            "description": "The JSON Patch operations to apply, in order. Applied to the current state as\n    one atomic write; if the result is not a JSON object or exceeds the 256,000-character size cap,\n    the whole request is rejected and nothing is written."
          },
          "comment": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional caller-supplied note stored alongside the resulting version. Omit\n    for no comment."
          }
        },
        "description": "Body for PATCH requests on public state and user state."
      },
      "PublicStateBody": {
        "required": [
          "version",
          "state",
          "comment",
          "createdAt",
          "stateSizeBytes"
        ],
        "type": "object",
        "properties": {
          "version": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Optimistic-concurrency version number for this state document, matching the quoted value in the ETag response header.",
            "format": "int32"
          },
          "state": {
            "description": "The state document for this version. Always a JSON object: PUT rejects a non-object body and PATCH rejects any patch whose result is not an object (both 400 validation_error).",
            "$ref": "#/components/schemas/JsonElement"
          },
          "comment": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional caller-supplied note stored alongside this version. Null when none was given."
          },
          "createdAt": {
            "type": "string",
            "description": "When this version was written, assigned by the server at write time.",
            "format": "date-time"
          },
          "stateSizeBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Size of the stored state document in bytes (its serialized JSON text, UTF-8 byte length).",
            "format": "int32"
          }
        },
        "description": "A versioned public-state document: the project/environment's shared configuration."
      },
      "QuotaResponse": {
        "required": [
          "code",
          "message",
          "resource",
          "current",
          "limit",
          "resetAt"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable quota code: `QUOTA_API_REQUESTS`,\n    `QUOTA_PROJECTS`, `QUOTA_API_KEYS`, or `QUOTA_END_USERS`."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation, safe to display but not guaranteed stable across\n    releases; code should branch on `code`, never on this text."
          },
          "resource": {
            "type": "string",
            "description": "The limited resource, matching `code`: `api_requests`,\n    `projects`, `api_keys`, or `end_users`."
          },
          "current": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The caller's current usage of `resource` at the moment the limit\n    was checked.",
            "format": "int64"
          },
          "limit": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The tier's limit for `resource` that `current`\n    reached or exceeded.",
            "format": "int64"
          },
          "resetAt": {
            "type": [
              "null",
              "string"
            ],
            "description": "ISO 8601 timestamp the limit next resets, for the monthly\n    `QUOTA_API_REQUESTS` code only. Null for every other code, since project/API-key/end-user\n    counts don't reset on a schedule; they free up when the caller deletes something."
          }
        },
        "description": "Structured response body for 402 quota exceeded responses. Returned for every tier-based limit\nviolation: monthly API requests, project count, API keys, and stored end-users."
      },
      "TokenExchangeResponse": {
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "refresh_token"
        ],
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "description": "The minted SkyState access token. Send as Authorization: Bearer <access_token> on subsequent requests."
          },
          "token_type": {
            "type": "string",
            "description": "Always \"Bearer\"."
          },
          "expires_in": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Seconds until access_token expires. Always 3600 (1 hour).",
            "format": "int32"
          },
          "refresh_token": {
            "type": "string",
            "description": "Opaque refresh token for the next grant_type=refresh_token call. Rotates on every refresh: the previous refresh token stops working once this one is issued."
          },
          "scope": {
            "type": [
              "null",
              "string"
            ],
            "description": "The end-user session's environment scope, or null for the developer flow (which carries no environment scope)."
          }
        },
        "description": "Response body for POST /v1/auth/token (both grant types). RFC 6749 §5.1 snake_case."
      },
      "UserStateBody": {
        "required": [
          "version",
          "state"
        ],
        "type": "object",
        "properties": {
          "version": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Optimistic-concurrency version number for this state document, matching the\n    quoted value in the ETag response header.",
            "format": "int32"
          },
          "state": {
            "description": "The state document for this version. Always a JSON object: PATCH (the only\n    write path for user state) rejects any patch whose result is not an object (400\n    validation_error).",
            "$ref": "#/components/schemas/JsonElement"
          }
        },
        "description": "A user-state document for one project/environment/end-user: version and current state.\n    Returned both when an authenticated end-user reads their own state and when a developer reads a\n    specific end-user's state."
      },
      "UserStateListBody": {
        "required": [
          "items",
          "cursor",
          "hasMore"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserStateListItemResponse"
            },
            "description": "The end-user state documents on this page."
          },
          "cursor": {
            "type": [
              "null",
              "string"
            ],
            "description": "Opaque pagination cursor for the next page, or null when there is no next\n    page (see `hasMore`). Pass back as the `cursor` query parameter to continue."
          },
          "hasMore": {
            "type": "boolean",
            "description": "True when additional items exist beyond this page."
          }
        },
        "description": "A page of end-users with state in a project/environment, newest first."
      },
      "UserStateListItemResponse": {
        "required": [
          "endUserId",
          "version",
          "state",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "endUserId": {
            "type": "string",
            "description": "The end-user identifier this state document belongs to."
          },
          "version": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Optimistic-concurrency version number for this end-user's state\n    document.",
            "format": "int32"
          },
          "state": {
            "description": "The state document for this version. Always a JSON object: PATCH (the only\n    write path for user state) rejects any patch whose result is not an object (400\n    validation_error).",
            "$ref": "#/components/schemas/JsonElement"
          },
          "updatedAt": {
            "type": "string",
            "description": "When this end-user's state was last written.",
            "format": "date-time"
          }
        },
        "description": "One end-user's state document within a developer-facing list page."
      }
    },
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "description": "SkyState developer access token, minted by POST /v1/auth/token.",
        "scheme": "bearer"
      },
      "apiKey": {
        "type": "http",
        "description": "Project-scoped API key, sent as `Authorization: ApiKey <key>` (note the `ApiKey` prefix, not `Bearer`).",
        "scheme": "ApiKey"
      },
      "endUserBearer": {
        "type": "http",
        "description": "SkyState-issued end-user access token, scoped to a single project and environment. Distinct from `bearer`, which authenticates a developer.",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Public State"
    },
    {
      "name": "User State"
    },
    {
      "name": "Auth"
    }
  ]
}