{
  "openapi": "3.0.4",
  "info": {
    "title": "Management API",
    "description": "Programmatic access to Featureflip — projects, environments, feature flags, variations, targeting, segments, and SDK keys. Authenticate with a Personal Access Token or Service Token via the Authorization: Bearer header.",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://api.featureflip.io",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/orgs/{org}/projects/{project}/environments": {
      "post": {
        "tags": [
          "Environments"
        ],
        "summary": "Creates an environment in the resolved project.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateEnvironmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateEnvironmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateEnvironmentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicEnvironmentResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Environments"
        ],
        "summary": "Lists environments in the resolved project, cursor-paginated.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicEnvironmentResponsePagedResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/environments/{env}": {
      "get": {
        "tags": [
          "Environments"
        ],
        "summary": "Gets an environment in the resolved project by key or id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicEnvironmentResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Environments"
        ],
        "summary": "Updates an environment's name/color/sort order.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateEnvironmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateEnvironmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateEnvironmentRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Environments"
        ],
        "summary": "Deletes an environment.",
        "description": "Requires at least Member. Deleting a project's last environment\nthrows the existing `LAST_ENVIRONMENT`ValidationException, which the\nexception filter maps to a 400 `validation_failed` envelope.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Creates a feature flag in the resolved project.",
        "description": "Requires at least Member.\nType is passed through verbatim to\nType (a bare string) — an invalid value surfaces as\nthe handler's own validation failure. Re-fetches via GetFeatureFlagQuery so\nthe response reflects exactly what was persisted (e.g. server-assigned variation ids).",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateFeatureFlagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateFeatureFlagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateFeatureFlagRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicFlagResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Lists feature flags in the resolved project, cursor-paginated.",
        "description": "Unlike\nList, ListFeatureFlagsQuery IS\n`Skip`/`Take`-based and returns a precise `Total`, so the next cursor is\ncomputed from the query result rather than an in-memory count. `type` is parsed\nleniently — an unrecognized value degrades to \"no type filter\" (matching\nDecode's \"garbage input degrades gracefully\" precedent)\nrather than a 400, since it's a non-critical list filter, not a mutation.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "archived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicFlagListItemPagedResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/removal-candidates": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Lists confidently-dead (or, with `staleness=stale`, stale-or-dead) flags the Featureflip Flag Cleanup Action should remove, cursor-paginated, each with its kill `treatment` (true = keep the on-branch, false = keep the off-branch).",
        "description": "Only flags the staleness engine marks at or\nabove the requested tier via a decisive StuckRolledOut/StuckRolledBack reason are returned;\nZeroTraffic/CreatedUnused, cross-env-divergent, and archived flags are omitted (no confident code\ntreatment). The ONLY public projection of staleness.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "staleness",
            "in": "query",
            "description": "Minimum staleness tier to include: `dead` (default) or `stale` (includes Stale + Dead).\nOmitted or any unrecognized value falls back to `dead` — the safe default never widens\nsilently.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicFlagRemovalCandidatePagedResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Gets a feature flag in the resolved project by key or id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicFlagResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Updates a flag's name/description/tags/client-side visibility.",
        "description": "Requires at least Member.\nKey and type are immutable via this endpoint (mirrors UpdateFeatureFlagCommand,\nwhich carries no `Key`/`Type`).",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFeatureFlagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFeatureFlagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFeatureFlagRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Deletes a flag.",
        "description": "Requires at least Member. A flag with dependent prerequisites throws the\nexisting `FLAG_HAS_DEPENDENTS`ValidationException, which the\nexception filter maps to a 400 `validation_failed` envelope — this action doesn't\nspecial-case it.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/archive": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Archives a flag.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/restore": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Restores a previously archived flag.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Gets the resolved flag's config in every environment of the resolved project.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicFlagEnvConfigResponse"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Gets the resolved flag's config in a single resolved environment.",
        "description": "There is no\nsingle-environment query on the Application side, so this dispatches the same\nGetFlagEnvironmentConfigurationsQuery as GetAll and finds the\nresolved environment by id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicFlagEnvConfigResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Updates the resolved flag's default variation, strategy, and (optionally) prerequisites in a resolved environment.",
        "description": "Requires at least Member. A null\nPrerequisites leaves prerequisites untouched;\na non-null list replaces them wholesale.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFlagEnvConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFlagEnvConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateFlagEnvConfigRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/toggle": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Enables or disables the resolved flag in a resolved environment.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicToggleFlagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicToggleFlagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicToggleFlagRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/targeting": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Gets the resolved flag's full targeting configuration (enabled flag + ordered rules) in the resolved environment.",
        "description": "GetTargetingConfigurationQuery returns null when\nno `FlagEnvironmentConfiguration` exists yet for this flag/environment pair — treated\nas 404 here (rather than an empty PublicTargetingConfigResponse) for\nconsistency with every other resolved-resource 404 on this surface.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicTargetingConfigResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Declaratively replaces the resolved flag's entire targeting rule set in the resolved environment.",
        "description": "The ordered Rules list is applied in\narray order (= evaluation order); an empty or omitted list clears all rules. Segment-scoped\nrules are supported. The replace is atomic. Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicPutTargetingRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicPutTargetingRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicPutTargetingRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/rules": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Creates a targeting rule on the resolved flag in the resolved environment.",
        "description": "Requires at\nleast Member. Re-fetches via GetTargetingRuleQuery using the id returned\nfrom CreateTargetingRuleCommand so the response reflects exactly what was\npersisted (e.g. server-assigned priority and condition/group ids).",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateTargetingRuleRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateTargetingRuleRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateTargetingRuleRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicTargetingRuleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/rules/{ruleId}": {
      "get": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Gets a single targeting rule on the resolved flag in the resolved environment by id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicTargetingRuleResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Updates a targeting rule's variation/description/rollout/segment/conditions wholesale.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateTargetingRuleRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateTargetingRuleRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateTargetingRuleRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Deletes a targeting rule from the resolved flag in the resolved environment.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/rules/reorder": {
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Reorders the resolved flag's targeting rules in the resolved environment by priority.",
        "description": "Requires at least Member. Must include every existing rule id exactly once — see the\ntype-level remarks on the dup/omission 500 wart.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicReorderRulesRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicReorderRulesRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicReorderRulesRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/variations": {
      "post": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Adds a variation to the resolved flag.",
        "description": "Requires at least Member. Re-fetches the flag via\nGetFeatureFlagQuery and locates the new variation by the id returned from\nAddVariationCommand so the response reflects exactly what was persisted.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicAddVariationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicAddVariationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicAddVariationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicVariationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/flags/{flag}/variations/{variationId}": {
      "put": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Updates a variation's name/value/description.",
        "description": "Requires at least Member. The variation's key is immutable via this endpoint.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateVariationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateVariationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateVariationRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Feature Flags"
        ],
        "summary": "Removes a variation from the resolved flag.",
        "description": "Requires at least Member. A variation with\ndependents (used as default variation, referenced by a targeting rule, or flagged\n`VARIATION_HAS_DEPENDENTS`) throws the existing\nValidationException, which the\nexception filter maps to a 400 `validation_failed` envelope — this action doesn't\nspecial-case it.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "tags": [
          "Me"
        ],
        "summary": "Returns the authenticated caller's public identity (see MeResponse).",
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "Lists the caller's organizations, cursor-paginated.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationResponsePagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "Gets one of the caller's organizations by slug or id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects": {
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Creates a project in the resolved organization.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateProjectRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateProjectRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateProjectRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Lists projects in the resolved organization, cursor-paginated.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectResponsePagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Gets a project in the resolved organization by key or id.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Updates a project's name/description.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateProjectRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateProjectRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateProjectRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Deletes a project.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys": {
      "post": {
        "tags": [
          "SDK Keys"
        ],
        "summary": "Creates an SDK key in the resolved environment.",
        "description": "Requires at least Member. Returns the\nplaintext key exactly once — see the type-level remarks.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSdkKeyRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSdkKeyRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSdkKeyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCreateSdkKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "SDK Keys"
        ],
        "summary": "Lists SDK keys in the resolved environment, cursor-paginated.",
        "description": "Like\nList, ListSdkKeysQuery has no\n`Skip`/`Take` (an environment's key count is small), so this fetches the full\nset and pages in-memory to still expose the standard cursor contract.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSdkKeyResponsePagedResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys/{sdkKey}": {
      "get": {
        "tags": [
          "SDK Keys"
        ],
        "summary": "Gets an SDK key in the resolved environment by id (guid-only — see the type-level remarks).",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sdkKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSdkKeyResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "SDK Keys"
        ],
        "summary": "Updates an SDK key's name/description.",
        "description": "Requires at least Member. Type and key material are immutable via this endpoint.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sdkKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSdkKeyRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSdkKeyRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSdkKeyRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys/{sdkKey}/revoke": {
      "post": {
        "tags": [
          "SDK Keys"
        ],
        "summary": "Revokes an SDK key.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sdkKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/segments": {
      "post": {
        "tags": [
          "User Segments"
        ],
        "summary": "Creates a user segment in the resolved project.",
        "description": "Requires at least Member. Re-fetches via\nListUserSegmentsQuery (there is no single-segment query) and locates the new\nsegment by the id returned from CreateUserSegmentCommand so the response\nreflects exactly what was persisted (e.g. server-assigned condition ids, folded into the\npublic shape via FromDto).",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSegmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSegmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateSegmentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSegmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "User Segments"
        ],
        "summary": "Lists user segments in the resolved project, cursor-paginated.",
        "description": "Like\nList, ListUserSegmentsQuery has no\n`Skip`/`Take` (a project's segment count is small), so this fetches the full set\nand pages in-memory to still expose the standard cursor contract.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSegmentResponsePagedResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{org}/projects/{project}/segments/{segment}": {
      "get": {
        "tags": [
          "User Segments"
        ],
        "summary": "Gets a user segment in the resolved project by key or id.",
        "description": "There is no\nListUserSegments-adjacent single-item\nquery, so this resolves `{segment}` then dispatches ListUserSegmentsQuery\nand finds the match — see the type-level remarks for why a list+find is acceptable here.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "segment",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSegmentResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "User Segments"
        ],
        "summary": "Updates a segment's name/description/conditions.",
        "description": "Requires at least Member. The segment's key is immutable via this endpoint.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "segment",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSegmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSegmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateSegmentRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "User Segments"
        ],
        "summary": "Deletes a user segment.",
        "description": "Requires at least Member.",
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "segment",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is required, or the supplied API token is invalid or expired.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval indicated by the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ActionCapability": {
        "type": "object",
        "properties": {
          "allowed": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One entry in a resource's `_actions` block: may the caller perform it, and if not, why."
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "emailVerified": {
            "type": "boolean",
            "nullable": true
          },
          "organizationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "role": {
            "type": "string",
            "nullable": true
          },
          "projectScope": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The authenticated caller's identity, returned by `GET /api/v1/me`. The public API\nauthenticates two kinds of principal, so this is a `type`-discriminated shape.\nA `\"user\"` caller (a session/JWT user or a personal access token, `ffp_...`) carries\n`email` + `emailVerified`. A `\"service_token\"` caller (`ffs_...`) has no\nbacking user row, so it carries `organizationId` + `role` + `projectScope` (the\ntoken's org, its role in that org, and its project allowlist) instead. The type-inapplicable\nfields are omitted from the response body. `projectScope` is omitted for an unrestricted\nservice token (access to every project), never an empty list."
      },
      "NextAction": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "nullable": true
          },
          "path": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "OrganizationResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "plan": {
            "enum": [
              "Solo",
              "Pro",
              "Business",
              "Enterprise"
            ],
            "type": "string",
            "description": "Allowed values: Solo, Pro, Business, Enterprise.",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Public representation of an organization, returned by both `GET /api/v1/orgs` (list) and\n`GET /api/v1/orgs/{org}` (detail). Drops dashboard-only fields (`BillingEmail` is\nbilling-contact PII, `UpdatedAt` is dashboard audit trivia) from the dashboard's\nOrganizationDto/OrganizationListItemDto."
      },
      "OrganizationResponsePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrganizationResponse"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "ProjectResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public representation of a project, returned by `GET /api/v1/orgs/{org}/projects` (list),\n`GET .../projects/{project}` (detail), and the body of a successful create/update. Drops\nthe dashboard-only nested `Environments` collection from ProjectDto — the\npublic API surfaces environments via their own endpoint (Task 6), not embedded here.\nUpdatedAt is only populated from ProjectDto (the detail/create\nshape); ProjectListItemDto doesn't carry it, so list rows leave it `null`.",
        "example": {
          "id": "0197b69f-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
          "key": "checkout",
          "name": "Checkout",
          "description": "Checkout and payments surfaces.",
          "createdAt": "2026-06-01T12:00:00Z",
          "updatedAt": "2026-06-15T08:30:00Z"
        }
      },
      "ProjectResponsePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectResponse"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "PublicAddVariationRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for\n`POST /api/v1/orgs/{org}/projects/{project}/flags/{flag}/variations`. Named distinctly\nfrom the dashboard's own `AddVariationRequest` —\nsee PublicCreateEnvironmentRequest for the schemaId-collision rationale (both\ncontrollers share one Swagger document).",
        "example": {
          "key": "express",
          "name": "Express Checkout",
          "value": "express",
          "description": "One-click express checkout variant."
        }
      },
      "PublicApiErrorEnvelope": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "docs_url": {
            "type": "string",
            "nullable": true
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "nullable": true
          },
          "retry_after": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "did_you_mean": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "next_actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NextAction"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The frozen public-API error contract. `error` codes are stable snake_case strings. Wire keys\nare frozen snake_case too (`error`, `message`, `docs_url`, `fields`,\n`retry_after`) — the global camelCase naming policy would otherwise emit\n`docsUrl`/`retryAfter`, breaking the published spec. !:JsonPropertyName\nalways wins over the policy, so these are pinned explicitly rather than relying on the\nproperty names already being lowercase for the single-word ones.\n`did_you_mean` and `next_actions` are ADDITIVE optional keys (null → omitted via\nthe global `DefaultIgnoreCondition = WhenWritingNull`), so pre-existing error bodies\nare byte-for-byte unchanged when they're absent.",
        "example": {
          "error": "not_found",
          "message": "Flag 'new-checkout-flw' was not found in project 'checkout'.",
          "docs_url": "https://featureflip.io/docs/management-api/errors/not_found",
          "did_you_mean": [
            "new-checkout-flow"
          ],
          "next_actions": [
            {
              "method": "GET",
              "path": "/api/v1/orgs/acme/projects/checkout/flags"
            }
          ]
        }
      },
      "PublicConditionGroupRequest": {
        "type": "object",
        "properties": {
          "operator": {
            "enum": [
              "And",
              "Or"
            ],
            "type": "string",
            "description": "Allowed values: And, Or.",
            "nullable": true
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicConditionRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request-side condition group, symmetric with PublicConditionGroupResponse."
      },
      "PublicConditionGroupResponse": {
        "type": "object",
        "properties": {
          "operator": {
            "enum": [
              "And",
              "Or"
            ],
            "type": "string",
            "description": "Allowed values: And, Or.",
            "nullable": true
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicConditionResponse"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A condition group within a PublicTargetingRuleResponse. Maps 1:1 onto\nConditionGroupDto. Operator is a bare wire string naming one of\nthe `ConditionGroupOperator` members (`\"And\"`/`\"Or\"`) —\ngroups are ANDed together at the rule level; within a group, its conditions combine using\nthis operator."
      },
      "PublicConditionRequest": {
        "type": "object",
        "properties": {
          "attribute": {
            "type": "string",
            "nullable": true
          },
          "operator": {
            "enum": [
              "Equals",
              "NotEquals",
              "Contains",
              "NotContains",
              "GreaterThan",
              "LessThan",
              "GreaterThanOrEqual",
              "LessThanOrEqual",
              "In",
              "NotIn",
              "MatchesRegex",
              "StartsWith",
              "EndsWith",
              "Before",
              "After",
              "SemverEquals",
              "SemverGreaterThan",
              "SemverGreaterThanOrEqual",
              "SemverLessThan",
              "SemverLessThanOrEqual"
            ],
            "type": "string",
            "description": "Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.",
            "nullable": true
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "negate": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "Request-side condition, symmetric with PublicConditionResponse."
      },
      "PublicConditionResponse": {
        "type": "object",
        "properties": {
          "attribute": {
            "type": "string",
            "nullable": true
          },
          "operator": {
            "enum": [
              "Equals",
              "NotEquals",
              "Contains",
              "NotContains",
              "GreaterThan",
              "LessThan",
              "GreaterThanOrEqual",
              "LessThanOrEqual",
              "In",
              "NotIn",
              "MatchesRegex",
              "StartsWith",
              "EndsWith",
              "Before",
              "After",
              "SemverEquals",
              "SemverGreaterThan",
              "SemverGreaterThanOrEqual",
              "SemverLessThan",
              "SemverLessThanOrEqual"
            ],
            "type": "string",
            "description": "Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.",
            "nullable": true
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "negate": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "A single condition within a PublicConditionGroupResponse. Maps 1:1 onto\nConditionDto. Operator is a bare wire string naming one of the\n`OperatorType` members (e.g. `\"Equals\"`, `\"In\"`)."
      },
      "PublicCreateEnvironmentRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST /api/v1/orgs/{org}/projects/{project}/environments`. Named\ndistinctly from the dashboard's own `CreateEnvironmentRequest`\n— both controllers share one Swagger document (see `Program.cs`'s `AddSwaggerGen``DocInclusionPredicate` override), and Swashbuckle's default schemaId is the bare type\nname, so an identical name in either namespace throws a schemaId collision at\n`--export-openapi` time.",
        "example": {
          "key": "production",
          "name": "Production",
          "color": "#16A34A",
          "sortOrder": 2
        }
      },
      "PublicCreateFeatureFlagRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "Boolean",
              "String",
              "Number",
              "Json"
            ],
            "type": "string",
            "description": "Allowed values: Boolean, String, Number, Json.",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "initialVariations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicCreateVariationDto"
            },
            "nullable": true
          },
          "clientSideVisible": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST /api/v1/orgs/{org}/projects/{project}/flags`. Named distinctly\nfrom the dashboard's own `CreateFeatureFlagRequest`\n— see PublicCreateEnvironmentRequest for the\nschemaId-collision rationale (both controllers share one Swagger document). Type\nis passed through verbatim to Type, which itself takes a\nbare string (Boolean/String/Number/Json) rather than the domain enum — invalid values surface\nas the handler's own validation failure, not a controller-level 400.",
        "example": {
          "key": "new-checkout-flow",
          "name": "New Checkout Flow",
          "type": "Boolean",
          "description": "Gates the redesigned checkout experience.",
          "tags": [
            "checkout",
            "q3-launch"
          ],
          "initialVariations": [
            {
              "key": "true",
              "name": "Enabled",
              "value": "true",
              "description": "Serve the new checkout."
            },
            {
              "key": "false",
              "name": "Disabled",
              "value": "false",
              "description": "Serve the legacy checkout."
            }
          ],
          "clientSideVisible": false
        }
      },
      "PublicCreateProjectRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST /api/v1/orgs/{org}/projects`. Named distinctly from the\ndashboard's own `CreateProjectRequest` — both\ncontrollers share one Swagger document (see `Program.cs`'s `AddSwaggerGen``DocInclusionPredicate` override), and Swashbuckle's default schemaId is the bare type\nname, so an identical name in either namespace throws a schemaId collision at\n`--export-openapi` time.",
        "example": {
          "key": "checkout",
          "name": "Checkout",
          "description": "Checkout and payments surfaces."
        }
      },
      "PublicCreateSdkKeyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "ClientSide",
              "ServerSide"
            ],
            "type": "string",
            "description": "Allowed values: ClientSide, ServerSide.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST /api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys`.\nType is a bare string (\"ClientSide\" or \"ServerSide\") — the controller parses it\nagainst a NAME allowlist (not a bare TryParse``1(ReadOnlySpan{Char},Boolean,``0@), which would\nsilently accept a numeric string like `\"0\"`) before dispatching. Named distinctly from\nthe dashboard's own `CreateSdkKeyRequest` — both\ncontrollers share one Swagger document, and an identical type name in either namespace throws\na schemaId collision at `--export-openapi` time.",
        "example": {
          "name": "Production server key",
          "description": "Used by the checkout backend.",
          "type": "ServerSide"
        }
      },
      "PublicCreateSdkKeyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "lastFourCharacters": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "ClientSide",
              "ServerSide"
            ],
            "type": "string",
            "description": "Allowed values: ClientSide, ServerSide.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "warning": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Response body for a successful `POST .../sdk-keys`. The ONLY place the plaintext\nKey is ever returned — PublicSdkKeyResponse (list/get) carries just\n`LastFourCharacters`. Built directly from CreateSdkKeyResult rather than a\nre-fetch (unlike `FeatureFlagsController.Create`'s re-fetch pattern) because the\nplaintext key only ever exists on the create result — a subsequent\nGetSdkKeyQuery can't recover it.",
        "example": {
          "id": "0197b6a2-4d5e-7f6a-9b7c-8d9e0f1a2b3c",
          "key": "ff_server_9f8e7d6c5b4a39281706f5e4d3c2b1a0",
          "lastFourCharacters": "b1a0",
          "type": "ServerSide",
          "name": "Production server key",
          "createdAt": "2026-06-01T12:00:00Z",
          "warning": "Store this key securely — it will not be shown again."
        }
      },
      "PublicCreateSegmentRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSegmentConditionDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST /api/v1/orgs/{org}/projects/{project}/segments`. Named distinctly\nfrom the dashboard's own `CreateUserSegmentRequest` — see\nPublicCreateEnvironmentRequest for the schemaId-collision rationale (both\ncontrollers share one Swagger document).",
        "example": {
          "key": "beta-testers",
          "name": "Beta Testers",
          "description": "Users enrolled in the beta program.",
          "conditions": [
            {
              "attribute": "email",
              "operator": "EndsWith",
              "values": [
                "@acme.com"
              ],
              "negate": false
            }
          ]
        }
      },
      "PublicCreateTargetingRuleRequest": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "nullable": true
          },
          "variationId": {
            "type": "string",
            "format": "uuid"
          },
          "rolloutPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "userSegmentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "conditionGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicConditionGroupRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST .../rules`. The Application-side\n`CreateTargetingRuleDto`/`CreateConditionGroupDto`/`CreateConditionDto` all take\ntheir `Operator` as a bare string, re-parsed CASE-SENSITIVELY inside\n`CreateTargetingRuleCommandHandler` — `FlagTargetingController`'s mapping helpers\nvalidate every operator against the enum's member-name allowlist AND canonicalize the casing\n(e.g. `\"in\"` → `\"In\"`) before building the command DTO, so a valid\ncase-insensitive match never trips the handler's strict re-parse.",
        "example": {
          "description": "North American users get the new flow at 25%.",
          "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e",
          "rolloutPercentage": 25,
          "conditionGroups": [
            {
              "operator": "And",
              "conditions": [
                {
                  "attribute": "country",
                  "operator": "In",
                  "values": [
                    "US",
                    "CA"
                  ],
                  "negate": false
                }
              ]
            }
          ]
        }
      },
      "PublicCreateVariationDto": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A variation supplied at flag-creation time. Maps 1:1 onto\nCreateVariationDto."
      },
      "PublicEnvironmentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public representation of an environment, returned by\n`GET /api/v1/orgs/{org}/projects/{project}/environments` (list),\n`GET .../environments/{env}` (detail), and the body of a successful create/update. Drops\ninternal fields (e.g. `ProjectId` is implicit in the route) — mirrors\n`ProjectResponse`'s minimal shape. Named `PublicEnvironmentResponse` rather than\n`EnvironmentResponse` (unlike the sibling `ProjectResponse`, which didn't collide)\nbecause the dashboard already has its own\n`EnvironmentResponse` — see\nPublicCreateEnvironmentRequest for the schemaId-collision rationale.",
        "example": {
          "id": "0197b69f-2b3c-7d4e-9f5a-6b7c8d9e0f1a",
          "key": "production",
          "name": "Production",
          "color": "#16A34A",
          "sortOrder": 2
        }
      },
      "PublicEnvironmentResponsePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicEnvironmentResponse"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "PublicFlagEnvConfigResponse": {
        "type": "object",
        "properties": {
          "environmentId": {
            "type": "string",
            "format": "uuid"
          },
          "environmentKey": {
            "type": "string",
            "nullable": true
          },
          "isEnabled": {
            "type": "boolean"
          },
          "defaultVariationId": {
            "type": "string",
            "format": "uuid"
          },
          "strategy": {
            "enum": [
              "SingleVariation",
              "PercentageRollout",
              "TargetedRollout"
            ],
            "type": "string",
            "description": "Allowed values: SingleVariation, PercentageRollout, TargetedRollout.",
            "nullable": true
          },
          "prerequisites": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicPrerequisiteDto"
            },
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public representation of a flag's config within a single environment, returned by\n`GET .../flags/{flag}/environments` and `GET .../flags/{flag}/environments/{env}`.\nDrops internal/dashboard-only fields present on FlagEnvironmentConfigurationDto\n— Id (an internal row id, not part of the public\ncontract; EnvironmentId is the addressable key), `FeatureFlagId` (implicit\nin the route), the environment's name/color/sort-order (dashboard display fields — the public\ncontract only needs the addressable EnvironmentKey), and `Staleness` (an\ninternal analytics signal).",
        "example": {
          "environmentId": "0197b69f-2b3c-7d4e-9f5a-6b7c8d9e0f1a",
          "environmentKey": "production",
          "isEnabled": true,
          "defaultVariationId": "0197b6a0-6a1b-7d4f-8c2e-3a4b5c6d7e8f",
          "strategy": "PercentageRollout",
          "prerequisites": [
            {
              "prerequisiteFlagKey": "checkout-api-enabled",
              "expectedVariationKey": "true"
            }
          ]
        }
      },
      "PublicFlagListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "Boolean",
              "String",
              "Number",
              "Json"
            ],
            "type": "string",
            "description": "Allowed values: Boolean, String, Number, Json.",
            "nullable": true
          },
          "isArchived": {
            "type": "boolean"
          },
          "clientSideVisible": {
            "type": "boolean"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Public list-item representation of a feature flag, returned by\n`GET .../flags`. Narrower than PublicFlagResponse — drops\nVariations (a summary-only shape upstream) and\nStaleness, matching the \"list is narrower than detail\"\nsplit already present on the Application-layer DTOs."
      },
      "PublicFlagListItemPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFlagListItem"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`).",
        "example": {
          "items": [
            {
              "id": "0197b6a0-5f2a-7c3e-9b4d-1e2f3a4b5c6d",
              "key": "new-checkout-flow",
              "name": "New Checkout Flow",
              "type": "Boolean",
              "isArchived": false,
              "clientSideVisible": false,
              "tags": [
                "checkout",
                "q3-launch"
              ],
              "createdAt": "2026-06-01T12:00:00Z",
              "updatedAt": "2026-06-15T08:30:00Z"
            }
          ],
          "next_cursor": "MjA"
        }
      },
      "PublicFlagRemovalCandidate": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "treatment": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One dead flag the Featureflip Flag Cleanup Action should remove, returned by\n`GET .../flags/removal-candidates`. `Treatment` is the kill decision: true → keep the\nflag's on-branch, false → keep the off-branch. `Status` is the flag's staleness tier\n(`\"Stale\"` or `\"Dead\"`, never `\"Active\"`) — lets a caller distinguish the two when\n`?staleness=stale` widens the response to include both tiers. This is the ONLY public\nprojection of staleness — PublicFlagResponse and PublicFlagListItem\nstill omit it by design."
      },
      "PublicFlagRemovalCandidatePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFlagRemovalCandidate"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "PublicFlagResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "Boolean",
              "String",
              "Number",
              "Json"
            ],
            "type": "string",
            "description": "Allowed values: Boolean, String, Number, Json.",
            "nullable": true
          },
          "isArchived": {
            "type": "boolean"
          },
          "clientSideVisible": {
            "type": "boolean"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "variations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicVariationResponse"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public detail representation of a feature flag, returned by\n`GET .../flags/{flag}` and the body of a successful create. Drops internal/dashboard-only\nfields present on FeatureFlagDto — notably `ProjectId` (implicit in the\nroute) and `Staleness` (an internal analytics signal, not part of the public contract).",
        "example": {
          "id": "0197b6a0-5f2a-7c3e-9b4d-1e2f3a4b5c6d",
          "key": "new-checkout-flow",
          "name": "New Checkout Flow",
          "description": "Gates the redesigned checkout experience.",
          "type": "Boolean",
          "isArchived": false,
          "clientSideVisible": false,
          "tags": [
            "checkout",
            "q3-launch"
          ],
          "variations": [
            {
              "id": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e",
              "key": "true",
              "name": "Enabled",
              "value": "true",
              "description": "Serve the new checkout."
            },
            {
              "id": "0197b6a0-6a1b-7d4f-8c2e-3a4b5c6d7e8f",
              "key": "false",
              "name": "Disabled",
              "value": "false",
              "description": "Serve the legacy checkout."
            }
          ],
          "createdAt": "2026-06-01T12:00:00Z",
          "updatedAt": "2026-06-15T08:30:00Z"
        }
      },
      "PublicPrerequisiteDto": {
        "type": "object",
        "properties": {
          "prerequisiteFlagKey": {
            "type": "string",
            "nullable": true
          },
          "expectedVariationKey": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A single prerequisite entry on a flag's per-environment config. Maps 1:1 onto\nPrerequisiteDto (read side) and PrerequisiteInput (write side)."
      },
      "PublicPutTargetingRequest": {
        "type": "object",
        "properties": {
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicCreateTargetingRuleRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT .../targeting` — a declarative full replace of the environment's\nordered targeting rule set. Rules are applied in array order (index = priority, so the array\norder IS the evaluation order). Rules is nullable so that an OMITTED `rules`\nfield (a body of `{}`) binds successfully instead of failing ASP.NET Core's implicit\nrequired-property check on non-nullable reference types — both an omitted `rules` field\nand an explicit empty list (`{ \"rules\": [] }`) clear all targeting rules for the\nenvironment. Each element is a PublicCreateTargetingRuleRequest (identical to the\n`POST .../rules` body), so `UserSegmentId` is supported — segment-scoped rules can be\nsubmitted through this endpoint. The replace is atomic (all-or-nothing): the whole rule set is\nswapped in one transaction, or nothing changes."
      },
      "PublicReorderRulesRequest": {
        "type": "object",
        "properties": {
          "ruleIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT .../rules/reorder`. Must include every existing rule id exactly\nonce — `ReorderTargetingRulesCommandHandler` rejects duplicate, omitted, or unknown rule\nids with `BadRequestException`, surfaced as an HTTP 400 `bad_request` envelope\ncarrying the handler's message."
      },
      "PublicSdkKeyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "enum": [
              "ClientSide",
              "ServerSide"
            ],
            "type": "string",
            "description": "Allowed values: ClientSide, ServerSide.",
            "nullable": true
          },
          "lastFourCharacters": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public representation of an SDK key, returned by\n`GET /api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys` (list) and\n`GET .../sdk-keys/{sdkKey}` (detail). Deliberately narrower than\nSdkKeyDto — drops `RevokedBy` (an internal user id) and\n`EnvironmentId` (implicit in the route), and carries no plaintext key field: only\nLastFourCharacters is ever exposed once the key has been created. The plaintext\nkey is a one-time value that appears solely in PublicCreateSdkKeyResponse.",
        "example": {
          "id": "0197b6a2-4d5e-7f6a-9b7c-8d9e0f1a2b3c",
          "name": "Production server key",
          "description": "Used by the checkout backend.",
          "type": "ServerSide",
          "lastFourCharacters": "b1a0",
          "isActive": true,
          "createdAt": "2026-06-01T12:00:00Z",
          "lastUsedAt": "2026-06-20T09:15:00Z"
        }
      },
      "PublicSdkKeyResponsePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSdkKeyResponse"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "PublicSegmentConditionDto": {
        "type": "object",
        "properties": {
          "attribute": {
            "type": "string",
            "nullable": true
          },
          "operator": {
            "enum": [
              "Equals",
              "NotEquals",
              "Contains",
              "NotContains",
              "GreaterThan",
              "LessThan",
              "GreaterThanOrEqual",
              "LessThanOrEqual",
              "In",
              "NotIn",
              "MatchesRegex",
              "StartsWith",
              "EndsWith",
              "Before",
              "After",
              "SemverEquals",
              "SemverGreaterThan",
              "SemverGreaterThanOrEqual",
              "SemverLessThan",
              "SemverLessThanOrEqual"
            ],
            "type": "string",
            "description": "Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.",
            "nullable": true
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "negate": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "A single targeting condition on a segment, used both as input (create/update) and output\n(Conditions). Operator is a bare string on\nboth sides of the wire — on write it's parsed to\nOperatorType by `SegmentsController` (an unknown\nvalue fails closed with a 400, never silently dropped or defaulted); on read it's mapped\nstraight through from Operator, which is already a string."
      },
      "PublicSegmentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSegmentConditionDto"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "Public representation of a user segment, returned by `GET .../segments`,\n`GET .../segments/{segment}`, and the body of a successful create.",
        "example": {
          "id": "0197b6a1-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
          "key": "beta-testers",
          "name": "Beta Testers",
          "description": "Users enrolled in the beta program.",
          "conditions": [
            {
              "attribute": "email",
              "operator": "EndsWith",
              "values": [
                "@acme.com"
              ],
              "negate": false
            }
          ],
          "createdAt": "2026-06-01T12:00:00Z",
          "updatedAt": "2026-06-15T08:30:00Z"
        }
      },
      "PublicSegmentResponsePagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSegmentResponse"
            },
            "nullable": true
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A page of results plus an opaque cursor for the next page, or null when this is the last\npage. Wire keys are frozen: `items` (already lowercase under the camelCase policy) and\n`next_cursor` (pinned explicitly — the policy alone would emit `nextCursor`)."
      },
      "PublicTargetingConfigResponse": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicTargetingRuleResponse"
            },
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "The full targeting configuration for a flag in a single environment, returned by\n`GET .../targeting`. Maps 1:1 onto TargetingConfigurationDto — including\nits IsEnabled field, which reflects the parent\n`FlagEnvironmentConfiguration.IsEnabled` (whether the flag is on in this environment at\nall), not anything specific to targeting itself."
      },
      "PublicTargetingRuleResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "priority": {
            "type": "integer",
            "format": "int32"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "variationId": {
            "type": "string",
            "format": "uuid"
          },
          "rolloutPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "userSegmentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "conditionGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicConditionGroupResponse"
            },
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A single targeting rule, returned by `GET .../rules/{ruleId}`,\n`POST .../rules` (201 body), and nested within PublicTargetingConfigResponse.\nMaps 1:1 onto TargetingRuleDto, dropping nothing — every field on the\nApplication DTO is part of the public contract.",
        "example": {
          "id": "0197b6a3-5e6f-7a7b-8c8d-9e0f1a2b3c4d",
          "priority": 0,
          "description": "North American users get the new flow at 25%.",
          "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e",
          "rolloutPercentage": 25,
          "userSegmentId": "0197b6a1-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
          "conditionGroups": [
            {
              "operator": "And",
              "conditions": [
                {
                  "attribute": "country",
                  "operator": "In",
                  "values": [
                    "US",
                    "CA"
                  ],
                  "negate": false
                }
              ]
            }
          ]
        }
      },
      "PublicToggleFlagRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `POST .../flags/{flag}/environments/{env}/toggle`. Named distinctly from\nthe dashboard's own `ToggleFlagInEnvironmentRequest`\n(which uses `IsEnabled`) — the public field is named Enabled per the phase-3c\ncontract. Enabled is a NULLABLE `bool?` deliberately: a non-nullable value\ntype would bind an omitted/empty body to `false` with no validation error (ASP.NET's\nimplicit-required only covers non-nullable reference types, not value types), silently disabling\nthe flag. The controller rejects a null Enabled with a `validation_failed` 400\nso the intent is never ambiguous (#1806)."
      },
      "PublicUpdateEnvironmentRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT /api/v1/orgs/{org}/projects/{project}/environments/{env}`. See\nPublicCreateEnvironmentRequest for why this is named distinctly from the\ndashboard's `UpdateEnvironmentRequest`."
      },
      "PublicUpdateFeatureFlagRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "clientSideVisible": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT /api/v1/orgs/{org}/projects/{project}/flags/{flag}`. See\nPublicCreateFeatureFlagRequest for why this is named distinctly from the\ndashboard's `UpdateFeatureFlagRequest`. The flag's key and type are immutable via this\nendpoint (mirrors `UpdateFeatureFlagCommand`, which has no `Key`/`Type`)."
      },
      "PublicUpdateFlagEnvConfigRequest": {
        "type": "object",
        "properties": {
          "defaultVariationId": {
            "type": "string",
            "format": "uuid"
          },
          "strategy": {
            "enum": [
              "SingleVariation",
              "PercentageRollout",
              "TargetedRollout"
            ],
            "type": "string",
            "description": "Allowed values: SingleVariation, PercentageRollout, TargetedRollout.",
            "nullable": true
          },
          "prerequisites": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicPrerequisiteDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT .../flags/{flag}/environments/{env}`. Named distinctly from the\ndashboard's own `UpdateFlagEnvironmentConfigurationRequest`\n— see PublicCreateEnvironmentRequest for the schemaId-collision rationale (both\ncontrollers share one Swagger document). Strategy is passed through verbatim to\nStrategy\n— the existing command validator name-allowlists it (SingleVariation/PercentageRollout/\nTargetedRollout or null), so an invalid value surfaces as the handler's own 400, not a\ncontroller-level guard. A null Prerequisites leaves prerequisites untouched; a\nnon-null list replaces them wholesale (mirrors UpdateFlagPrerequisitesCommand's\nreplace-all semantics).",
        "example": {
          "defaultVariationId": "0197b6a0-6a1b-7d4f-8c2e-3a4b5c6d7e8f",
          "strategy": "PercentageRollout",
          "prerequisites": [
            {
              "prerequisiteFlagKey": "checkout-api-enabled",
              "expectedVariationKey": "true"
            }
          ]
        }
      },
      "PublicUpdateProjectRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT /api/v1/orgs/{org}/projects/{project}`. See\nPublicCreateProjectRequest for why this is named distinctly from the\ndashboard's `UpdateProjectRequest`."
      },
      "PublicUpdateSdkKeyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT /api/v1/orgs/{org}/projects/{project}/environments/{env}/sdk-keys/{sdkKey}`.\nType and key material are immutable via this endpoint (mirrors\nUpdateSdkKeyCommand, which\ncarries no `Type`)."
      },
      "PublicUpdateSegmentRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSegmentConditionDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT /api/v1/orgs/{org}/projects/{project}/segments/{segment}`. The\nsegment's key is immutable via this endpoint (mirrors `UpdateUserSegmentCommand`, which\ncarries no `Key`)."
      },
      "PublicUpdateTargetingRuleRequest": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "nullable": true
          },
          "variationId": {
            "type": "string",
            "format": "uuid"
          },
          "rolloutPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "userSegmentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "conditionGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicConditionGroupRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for `PUT .../rules/{ruleId}`. Same shape as\nPublicCreateTargetingRuleRequest — see its remarks on operator\nvalidation/canonicalization, which applies identically here."
      },
      "PublicUpdateVariationRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for\n`PUT /api/v1/orgs/{org}/projects/{project}/flags/{flag}/variations/{variationId}`. The\nvariation's key is immutable via this endpoint (mirrors\n`UpdateVariationCommand`, which\ncarries no `Key`)."
      },
      "PublicVariationResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "_actions": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ActionCapability"
            },
            "description": "Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it."
          }
        },
        "additionalProperties": false,
        "description": "A single variation on a flag, as returned in Variations.",
        "example": {
          "id": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e",
          "key": "true",
          "name": "Enabled",
          "value": "true",
          "description": "Serve the new checkout."
        }
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "description": "The maximum number of requests permitted per rate-limit window for this caller.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "The number of requests remaining in the current rate-limit window.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "The UTC time at which the current rate-limit window resets, as a Unix timestamp in seconds.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "apiKey",
        "description": "JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below.",
        "name": "Authorization",
        "in": "header"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ],
  "tags": [
    {
      "name": "Environments",
      "description": "Environments within a resolved organization + project — one level deeper than\nProjectsController. Every route here carries `{org}`, so\nResolveTenantFilter has already resolved + access-checked\nit before any action runs. `{project}` is resolved key-or-guid, scoped to the resolved\norg, via ResolveProjectIdAsync for every action (list\nneeds it too, unlike ProjectsController's org-only list). `{env}`\n(get/update/delete) is then resolved key-or-guid, scoped to the resolved project, via\nResolveEnvironmentIdAsync. Dispatched commands/queries\nalways use the resolved GUIDs, never the raw route strings. Writes (create/update/delete)\nrequire at least Member (RequireRole);\na Viewer attempting one gets a 403 `forbidden` envelope. Deleting a project's last\nenvironment surfaces the existing `LAST_ENVIRONMENT` guard\n(DeleteEnvironmentCommandHandler) as-is — it throws the custom\nValidationException, which\nPublicApiExceptionFilterAttribute maps to a 400\n`validation_failed` envelope automatically, so Delete doesn't special-case it.\nListEnvironmentsQuery has no `Skip`/`Take` (unlike\n`ListProjectsQuery`) — a project's environment count is small, so List\nfetches the full set and paginates in-memory to still expose the standard cursor contract."
    },
    {
      "name": "Feature Flags",
      "description": "Feature flags within a resolved organization + project — mirrors\nEnvironmentsController's resolve-then-dispatch shape one level deeper.\n`{project}` is resolved key-or-guid, scoped to the resolved org (with the service-token\nproject allowlist forwarded), via ResolveProjectIdAsync\nfor every action. `{flag}` (get/update/archive/restore/delete) is then resolved\nkey-or-guid, scoped to the resolved project, via\nResolveFlagIdAsync. Dispatched commands/queries always\nuse the resolved GUIDs, never the raw route strings. Writes (create/update/archive/restore/\ndelete) require at least Member\n(RequireRole); a Viewer attempting one gets a 403\n`forbidden` envelope. Flag deletion/variation-removal guards (`FLAG_HAS_DEPENDENTS`,\nplan limits on create, etc.) surface as-is via the existing handlers' custom\nValidationException, which\nPublicApiExceptionFilterAttribute maps to a 400 `validation_failed`\nenvelope automatically — no action here special-cases them. Defers flag *runtime config*\n(env-config, toggle, targeting rules, prerequisites) and variations to their own controllers\n(phase 3b Task 3 / phase 3c)."
    },
    {
      "name": "Me",
      "description": "The caller's own identity. This route has no `{org}` segment, so\nResolveTenantFilter is a pass-through here — the caller\nis read entirely from the authenticated principal (via GetCurrentUserQuery for a\nuser/PAT, or directly from claims for a service token), never from\nResolvedOrgId."
    },
    {
      "name": "Organizations",
      "description": "The caller's organizations. `List` has no `{org}` segment (pass-through tenant\nfilter) and dispatches ListOrganizationsQuery, which already scopes to the\ncaller's own memberships. `Get` carries `{org}`, so\nResolveTenantFilter resolves + access-checks it first —\nthe action dispatches GetOrganizationQuery with the resolved GUID\n(ResolvedOrgId), never the raw route string."
    },
    {
      "name": "Projects",
      "description": "Projects within a resolved organization. Every route here carries `{org}`, so\nResolveTenantFilter has already resolved + access-checked\nit before any action runs — dispatched commands/queries always use\nResolvedOrgId, never the raw route string.\n`{project}` (get/update/delete) is resolved key-or-guid, scoped to the resolved org, via\nResolveProjectIdAsync — same addressing pattern as\nOrganizationsController uses for `{org}`. Writes (create/update/delete)\nrequire at least Member\n(RequireRole); a Viewer attempting one gets a 403\n`forbidden` envelope."
    },
    {
      "name": "SDK Keys",
      "description": "SDK keys within a resolved organization + project + environment — one level deeper than\nEnvironmentsController. Every action resolves `{project}` (key-or-guid,\nscoped to the resolved org, with the service-token project allowlist forwarded) then\n`{env}` (key-or-guid, scoped to the resolved project) via\nIPublicApiTenantResolver, mirroring FeatureFlagsController's\nresolve-then-dispatch shape. Unlike `{project}`/`{env}`, `{sdkKey}` is\nguid-only — SDK keys have no key/slug of their own — resolved via\nResolveSdkKeyIdAsync, which throws the same\nnot-found error for a non-guid segment as a genuinely missing key. Writes\n(create/update/revoke) require at least Member\n(RequireRole); a Viewer attempting one gets a 403\n`forbidden` envelope.\n\nType is a bare string on the wire; Create\nparses it to SdkKeyType against a NAME allowlist\n(`Enum.TryParse` + `Enum.GetNames().Contains(...)`) rather than a bare\n`Enum.TryParse`/`Enum.IsDefined` pair — the latter would silently accept a numeric\nstring (e.g. `\"0\"`) and resolve it to the first enum member. An unrecognized value throws\nthe custom ValidationException BEFORE the environment is resolved or any command\nis dispatched, mapped to a 400 `validation_failed` envelope by\nPublicApiExceptionFilterAttribute — same pattern as\nMapConditions's operator parse.\nThe plaintext key returned by CreateSdkKeyResult is a one-time value — it is\nnever recoverable afterward, so unlike Create's\nre-fetch-after-write pattern, Create builds its response directly from the\ncommand result rather than dispatching a follow-up query. List and\nGet return PublicSdkKeyResponse, which carries only\n`LastFourCharacters` — never the plaintext."
    },
    {
      "name": "User Segments",
      "description": "User segments within a resolved organization + project — mirrors\nEnvironmentsController's resolve-then-dispatch shape one level deeper.\n`{project}` is resolved key-or-guid, scoped to the resolved org (with the service-token\nproject allowlist forwarded), via ResolveProjectIdAsync\nfor every action. `{segment}` (get/update/delete) is then resolved key-or-guid, scoped to\nthe resolved project, via ResolveSegmentIdAsync.\nDispatched commands/queries always use the resolved GUIDs, never the raw route strings. Writes\n(create/update/delete) require at least Member\n(RequireRole); a Viewer attempting one gets a 403\n`forbidden` envelope.\n\nThere is no `GetUserSegmentQuery` — Get resolves `{segment}` then\ndispatches ListUserSegmentsQuery and finds the match in-memory, throwing\nNotFoundException if absent. This keeps the task scoped to the public layer with\nno new Application handler: the resolver has already validated the id exists within the\nproject, and a project's segment set is bounded (unlike flags/environments' own list, this\nnever needs true server-side pagination for the lookup).\nOperator is a bare string on the wire; write actions\nparse it to OperatorType via TryParse``1(ReadOnlySpan{Char},Boolean,``0@)\n(case-insensitive). An unrecognized value throws the custom\nValidationException BEFORE any command is dispatched — mapped to a 400\n`validation_failed` envelope by PublicApiExceptionFilterAttribute, same as\nevery other handler-thrown validation failure on this surface."
    }
  ]
}