{
  "openapi": "3.0.3",
  "info": {
    "title": "OpenGrants API",
    "description": "RESTful API for accessing grants, government contracts, and funding organization data.",
    "version": "1.1.0",
    "contact": { "name": "OpenGrants", "url": "https://opengrants.io" }
  },
  "servers": [{ "url": "https://ops.opengrants.io/functions/v1", "description": "Production" }],
  "paths": {
    "/grants-api": {
      "get": {
        "summary": "List grants",
        "operationId": "listGrants",
        "parameters": [
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "search_mode", "in": "query", "description": "Ranking strategy. semantic/hybrid require a search term and enable vector relevance.", "schema": { "type": "string", "enum": ["keyword", "semantic", "hybrid"], "default": "keyword" } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["open", "posted", "closed", "forecasted"] } },
          { "name": "opportunity_type", "in": "query", "description": "'open' (default) returns applyable opportunities only. 'awarded' returns previously funded projects (research mode — not open for application; deadline is null, see project_end_date). 'all' returns both.", "schema": { "type": "string", "enum": ["open", "awarded", "all"], "default": "open" } },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "states", "in": "query", "description": "Filter by US location: comma-separated 2-letter USPS codes, e.g. CA,NY. State-specific only unless include_national=true.", "schema": { "type": "string" } },
          { "name": "include_national", "in": "query", "description": "When filtering by states, also include national / all-states opportunities.", "schema": { "type": "boolean", "default": false } },
          { "name": "geography", "in": "query", "deprecated": true, "description": "Legacy free-text location filter (best-effort, state-canonicalized on hybrid). Prefer 'states'.", "schema": { "type": "string" } },
          { "name": "min_amount", "in": "query", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "max_amount", "in": "query", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "deadline_after", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "deadline_before", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "posted_after", "in": "query", "schema": { "type": "string", "format": "date-time" } },
          { "name": "sort_by", "in": "query", "schema": { "type": "string", "enum": ["created_at", "deadline_date", "amount_min", "amount_max", "title"], "default": "created_at" } },
          { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } },
          { "name": "count_only", "in": "query", "description": "Return only { total } for the filter set.", "schema": { "type": "boolean", "default": false } },
          { "name": "include_archived", "in": "query", "schema": { "type": "boolean", "default": false } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0, "maximum": 10000 } }
        ],
        "responses": { "200": { "description": "Paginated grants list" } },
        "security": [{ "apiKey": [] }]
      }
    },
    "/contracts-api": {
      "get": {
        "summary": "List contracts",
        "operationId": "listContracts",
        "parameters": [
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "search_mode", "in": "query", "description": "Ranking strategy. semantic/hybrid require a search term and enable vector relevance.", "schema": { "type": "string", "enum": ["keyword", "semantic", "hybrid"], "default": "keyword" } },
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "opportunity_type", "in": "query", "description": "'open' (default) returns active solicitations only. 'awarded' returns already-awarded contracts (research mode). 'all' returns both.", "schema": { "type": "string", "enum": ["open", "awarded", "all"], "default": "open" } },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "naics", "in": "query", "schema": { "type": "string" } },
          { "name": "set_aside", "in": "query", "schema": { "type": "string" } },
          { "name": "states", "in": "query", "description": "Filter by US location: comma-separated 2-letter USPS codes, e.g. CA,NY. State-specific only unless include_national=true.", "schema": { "type": "string" } },
          { "name": "include_national", "in": "query", "description": "When filtering by states, also include national / all-states opportunities.", "schema": { "type": "boolean", "default": false } },
          { "name": "geography", "in": "query", "deprecated": true, "description": "Legacy free-text location filter (best-effort, state-canonicalized on hybrid). Prefer 'states'.", "schema": { "type": "string" } },
          { "name": "min_amount", "in": "query", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "max_amount", "in": "query", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "deadline_after", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "deadline_before", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "posted_after", "in": "query", "schema": { "type": "string", "format": "date-time" } },
          { "name": "sort_by", "in": "query", "schema": { "type": "string", "enum": ["created_at", "deadline_date", "amount_min", "amount_max", "title"], "default": "created_at" } },
          { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } },
          { "name": "count_only", "in": "query", "description": "Return only { total } for the filter set.", "schema": { "type": "boolean", "default": false } },
          { "name": "include_archived", "in": "query", "schema": { "type": "boolean", "default": false } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0, "maximum": 10000 } }
        ],
        "responses": { "200": { "description": "Paginated contracts list" } },
        "security": [{ "apiKey": [] }]
      }
    },
    "/funders-api": {
      "get": {
        "summary": "List funders",
        "operationId": "listFunders",
        "parameters": [
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated funders list" } },
        "security": [{ "apiKey": [] }]
      }
    },
    "/semantic-search": {
      "post": {
        "summary": "Semantic search",
        "operationId": "semanticSearch",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string" }, "type": { "type": "string", "enum": ["grants", "contracts"] }, "limit": { "type": "integer", "default": 10 } } } } }
        },
        "responses": { "200": { "description": "Semantically matched results" } },
        "security": [{ "apiKey": [] }]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": { "type": "http", "scheme": "bearer", "description": "API key from the OpenGrants Developer portal" }
    }
  }
}
