{
  "openapi": "3.1.0",
  "info": {
    "title": "Govera Public API",
    "version": "1.0.0",
    "summary": "Public, read-only API describing the Govera governance platform: service status, product metadata, capabilities, and guides.",
    "description": "The Govera Public API exposes non-sensitive, read-only information about the Govera governance platform: what it is, what it can do, and how to learn more. It contains no agency, tenant, or user data. Tenant-scoped drafting, search, and workspace operations run inside an agency's authenticated workspace and are not part of this public API.\n\nEvery operation is HTTP GET and returns `application/json` on success. Errors return `application/problem+json` following RFC 9457 (Problem Details for HTTP APIs): a `type` URI, a `title`, a numeric `status`, and optional `detail` / `instance` fields. Every error across the API uses the same ProblemDetails schema.\n\nAuthentication: the public read-only endpoints in this document require NO authentication — any client or AI agent may call them directly, with no API key and no account. The `X-Govera-Key` and OAuth 2.0 schemes described under `components.securitySchemes` apply only to the separate authenticated tenant workspace (drafting and search), which is not part of this public API; they are documented here for completeness and do not gate any operation below (the document-level `security` is the empty set).\n\nRate limiting: every response carries the RFC draft RateLimit headers — `RateLimit-Limit` (requests permitted in the current window), `RateLimit-Remaining` (requests left in the window), and `RateLimit-Reset` (seconds until the window resets). A `429 Too Many Requests` response additionally carries a `Retry-After` header (seconds to wait before retrying). Agents should self-throttle using these headers.\n\nVersioning and deprecation policy: the API is versioned in the URL path — this document describes `v1` at `https://www.govera.co/api/v1`. No version is retired without at least 90 days' notice: an operation slated for removal is first marked `deprecated: true` here and begins returning a `Deprecation` response header, then a `Sunset` header (RFC 8594) naming the retirement date, and the version is removed no earlier than that date. See `x-sunset-policy` on this document for the machine-readable statement of the same policy.\n\nRelated resources: developer portal at https://www.govera.co/developers, human-readable API reference at https://www.govera.co/docs, the MCP server manifest at https://www.govera.co/.well-known/mcp, the official CLI (`npx govera-cli`), and the official MCP server (`npx -y govera-mcp-server`).",
    "contact": {
      "name": "Govera",
      "email": "mike@govera.co",
      "url": "https://www.govera.co/developers"
    }
  },
  "servers": [
    {
      "url": "https://www.govera.co/api/v1",
      "description": "Production v1"
    }
  ],
  "externalDocs": {
    "description": "Developer portal and API reference",
    "url": "https://www.govera.co/developers"
  },
  "security": [],
  "x-no-auth": "The public read-only endpoints in this document require no authentication. Call them directly with no API key and no account.",
  "x-rate-limit": {
    "policy": "A fixed window applies per client. Every response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset (seconds to window reset). A 429 response carries Retry-After (seconds).",
    "headers": ["RateLimit-Limit", "RateLimit-Remaining", "RateLimit-Reset", "Retry-After"],
    "standard": "IETF draft-ietf-httpapi-ratelimit-headers"
  },
  "x-sunset-policy": "Endpoints are versioned via the URL path (currently /api/v1). A version is never removed without at least 90 days' advance notice: retiring operations are first marked deprecated: true in this document and start returning a Deprecation response header naming the successor version, then a Sunset response header (RFC 8594) naming the retirement date, and the version is removed no earlier than that date.",
  "tags": [
    { "name": "meta", "description": "Service metadata and health." },
    { "name": "product", "description": "Public product information." }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Get service status",
        "description": "Returns the operational status, version, and current server timestamp for the Govera Public API. Use this as a lightweight reachability and version check. No authentication required.",
        "tags": ["meta"],
        "deprecated": false,
        "security": [],
        "parameters": [],
        "x-sunset-policy": "Not deprecated. When this operation is scheduled for retirement, responses will carry a Deprecation header before a Sunset header is added ahead of removal, per the document-level x-sunset-policy.",
        "responses": {
          "200": {
            "description": "The current service status.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Status",
                  "description": "Operational status of the Govera Public API.",
                  "additionalProperties": false,
                  "required": ["service", "status", "version", "documentation", "timestamp"],
                  "properties": {
                    "service": { "type": "string", "description": "Human-readable service name.", "examples": ["Govera Public API"] },
                    "status": { "type": "string", "enum": ["operational", "degraded", "maintenance"], "description": "Current operational status of the API." },
                    "version": { "type": "string", "description": "The API version currently serving this response.", "examples": ["1.0.0"] },
                    "documentation": { "type": "string", "format": "uri", "description": "URL of the developer portal describing this API." },
                    "timestamp": { "type": "string", "format": "date-time", "description": "Server time at which this status was generated, as an RFC 3339 timestamp." }
                  }
                },
                "example": {
                  "service": "Govera Public API",
                  "status": "operational",
                  "version": "1.0.0",
                  "documentation": "https://www.govera.co/developers",
                  "timestamp": "2026-08-25T00:00:00Z"
                }
              }
            }
          },
          "400": { "description": "The request was malformed.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/bad-request", "title": "Bad Request", "status": 400, "detail": "The request could not be understood or was missing required parameters.", "instance": "/api/v1/status" } } } },
          "404": { "description": "The requested resource does not exist.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/not-found", "title": "Not Found", "status": 404, "detail": "The requested resource does not exist.", "instance": "/api/v1/status" } } } },
          "429": { "description": "The client has sent too many requests in a given amount of time.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/rate-limited", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded. Retry after the interval named in the Retry-After header.", "instance": "/api/v1/status" } } } }
        }
      }
    },
    "/product": {
      "get": {
        "operationId": "getProduct",
        "summary": "Get product information",
        "description": "Returns public metadata about the Govera product: its name, description, the categories of public agency it serves, and its home URL. Contains no agency or user data. No authentication required.",
        "tags": ["product"],
        "deprecated": false,
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Public product metadata.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Product",
                  "description": "Public metadata about the Govera product.",
                  "additionalProperties": false,
                  "required": ["name", "description", "categories", "url"],
                  "properties": {
                    "name": { "type": "string", "description": "The product name.", "examples": ["Govera"] },
                    "description": { "type": "string", "description": "A one-paragraph description of the product." },
                    "categories": {
                      "type": "array",
                      "description": "The categories of public agency Govera serves.",
                      "items": { "type": "string", "description": "A single category of public agency, e.g. \"Cities\" or \"School districts\"." },
                      "examples": [["Cities", "Counties", "School districts", "Special districts"]]
                    },
                    "url": { "type": "string", "format": "uri", "description": "The product's home URL." }
                  }
                },
                "example": {
                  "name": "Govera",
                  "description": "Govera is the governance platform for public agencies. It reads an agency's own meeting record and drafts new agendas, staff reports, and follow-ups grounded in that history, with every factual claim cited to a source document.",
                  "categories": ["Cities", "Counties", "School districts", "Special districts", "Councils of government"],
                  "url": "https://www.govera.co"
                }
              }
            }
          },
          "400": { "description": "The request was malformed.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/bad-request", "title": "Bad Request", "status": 400, "detail": "The request could not be understood or was missing required parameters.", "instance": "/api/v1/product" } } } },
          "404": { "description": "The requested resource does not exist.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/not-found", "title": "Not Found", "status": 404, "detail": "The requested resource does not exist.", "instance": "/api/v1/product" } } } },
          "429": { "description": "The client has sent too many requests in a given amount of time.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/rate-limited", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded. Retry after the interval named in the Retry-After header.", "instance": "/api/v1/product" } } } }
        }
      }
    },
    "/capabilities": {
      "get": {
        "operationId": "listCapabilities",
        "summary": "List product capabilities",
        "description": "Returns the list of Govera product capabilities, each with a stable identifier, a name, and a description. Use this to learn programmatically what Govera can do for a public agency. No authentication required.",
        "tags": ["product"],
        "deprecated": false,
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The list of product capabilities.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Capabilities",
                  "description": "The list of Govera product capabilities.",
                  "additionalProperties": false,
                  "required": ["capabilities"],
                  "properties": {
                    "capabilities": {
                      "type": "array",
                      "description": "Each Govera product capability, with a stable identifier, name, and description.",
                      "items": {
                        "type": "object",
                        "title": "Capability",
                        "description": "A single Govera product capability.",
                        "additionalProperties": false,
                        "required": ["id", "name", "description"],
                        "properties": {
                          "id": { "type": "string", "description": "Stable, machine-readable identifier for the capability.", "examples": ["agenda_drafting"] },
                          "name": { "type": "string", "description": "Human-readable name of the capability." },
                          "description": { "type": "string", "description": "A description of what the capability does." }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "The request was malformed.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/bad-request", "title": "Bad Request", "status": 400, "detail": "The request could not be understood or was missing required parameters.", "instance": "/api/v1/capabilities" } } } },
          "404": { "description": "The requested resource does not exist.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/not-found", "title": "Not Found", "status": 404, "detail": "The requested resource does not exist.", "instance": "/api/v1/capabilities" } } } },
          "429": { "description": "The client has sent too many requests in a given amount of time.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/rate-limited", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded. Retry after the interval named in the Retry-After header.", "instance": "/api/v1/capabilities" } } } }
        }
      }
    },
    "/guides": {
      "get": {
        "operationId": "listGuides",
        "summary": "List public guides",
        "description": "Returns the public Govera platform guides — human-readable pages describing how staff and board members use Govera — each with a title and URL. No authentication required.",
        "tags": ["product"],
        "deprecated": false,
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The list of public guides.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Guides",
                  "description": "The list of public Govera platform guides.",
                  "additionalProperties": false,
                  "required": ["guides"],
                  "properties": {
                    "guides": {
                      "type": "array",
                      "description": "Each public platform guide, with a title and URL.",
                      "items": {
                        "type": "object",
                        "title": "Guide",
                        "description": "A single public Govera platform guide.",
                        "additionalProperties": false,
                        "required": ["title", "url"],
                        "properties": {
                          "title": { "type": "string", "description": "The guide's title." },
                          "url": { "type": "string", "format": "uri", "description": "The guide's URL." }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "The request was malformed.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/bad-request", "title": "Bad Request", "status": 400, "detail": "The request could not be understood or was missing required parameters.", "instance": "/api/v1/guides" } } } },
          "404": { "description": "The requested resource does not exist.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/not-found", "title": "Not Found", "status": 404, "detail": "The requested resource does not exist.", "instance": "/api/v1/guides" } } } },
          "429": { "description": "The client has sent too many requests in a given amount of time.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" }, "example": { "type": "https://www.govera.co/problems/rate-limited", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded. Retry after the interval named in the Retry-After header.", "instance": "/api/v1/guides" } } } }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Govera-Key",
        "description": "Static API key for the authenticated tenant workspace (NOT required for the public read-only endpoints in this document). Send it as the X-Govera-Key request header."
      },
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 client-credentials grant for the authenticated tenant workspace (NOT required for the public read-only endpoints in this document). Exchange a client_id/client_secret pair at the token endpoint for a bearer token, then send it as an Authorization: Bearer header.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://www.govera.co/oauth/token",
            "scopes": {
              "read:status": "Read service status and version.",
              "read:product": "Read public product metadata.",
              "read:capabilities": "Read the list of product capabilities.",
              "read:guides": "Read the list of public platform guides."
            }
          }
        }
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "The number of requests permitted in the current rate-limit window.",
        "schema": { "type": "integer", "examples": [120] }
      },
      "RateLimitRemaining": {
        "description": "The number of requests remaining in the current rate-limit window.",
        "schema": { "type": "integer", "examples": [119] }
      },
      "RateLimitReset": {
        "description": "The number of seconds until the current rate-limit window resets.",
        "schema": { "type": "integer", "examples": [60] }
      },
      "RetryAfter": {
        "description": "The number of seconds to wait before retrying, sent on a 429 response.",
        "schema": { "type": "integer", "examples": [60] }
      }
    },
    "schemas": {
      "ProblemDetails": {
        "type": "object",
        "title": "ProblemDetails",
        "description": "RFC 9457 Problem Details for HTTP APIs — the single error schema returned by every non-2xx response across this API.",
        "additionalProperties": false,
        "required": ["type", "title", "status"],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference that identifies the problem type. Defaults to \"about:blank\" when no more specific type is available."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type that does not change from occurrence to occurrence."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code generated by the origin server for this occurrence of the problem."
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "instance": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference that identifies the specific occurrence of the problem, e.g. the request path."
          }
        }
      }
    }
  }
}
