{
  "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. Authenticated agency data APIs are not publicly available.\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 endpoints in this document are static, public JSON files and require no authentication. Any client or AI agent may call them directly, with no API key and no account. Authenticated agency data APIs are not publicly available. The live system status is served separately at `https://app.govera.co/api/v1/public/status` (no authentication).\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 links to the Govera status page and to the live status endpoint (https://app.govera.co/api/v1/public/status), which reports measured uptime. This file is static; it does not itself report whether the service is up. 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": "Where to find the status of the Govera service.",
                  "additionalProperties": false,
                  "required": ["service", "status_page", "live_status", "documentation"],
                  "properties": {
                    "service": { "type": "string", "description": "Human-readable service name.", "examples": ["Govera Public API"] },
                    "status_page": { "type": "string", "format": "uri", "description": "URL of the public status page." },
                    "live_status": { "type": "string", "format": "uri", "description": "URL of the live status endpoint, which reports current status and measured uptime." },
                    "documentation": { "type": "string", "format": "uri", "description": "URL of the developer portal describing this API." }
                  }
                },
                "example": {
                  "service": "Govera Public API",
                  "status_page": "https://govera.co/status",
                  "live_status": "https://app.govera.co/api/v1/public/status",
                  "documentation": "https://www.govera.co/developers"
                }
              }
            }
          },
          "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": {
    "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."
          }
        }
      }
    }
  }
}
