{
  "openapi": "3.1.0",
  "info": {
    "title": "Growth Choice Agent API",
    "version": "1.0.0",
    "description": "Public API for the Growth Choice marketing intelligence system. Provides structured access to services, case studies, verified results, and marketing knowledge via Model Context Protocol (MCP) and NLWeb.\n\n**Versioning policy**: The current version is v1, returned in the `X-API-Version` response header. Breaking changes are announced via the `Sunset` response header (RFC 8594) at least 90 days before removal. The `Deprecation` header (RFC 9745) is set to the date on which the operation was deprecated. Non-breaking additions are made without notice.\n\n**Authentication**: No API key or account required — all endpoints accept unauthenticated requests.\n\n**Rate limits**: 1,000 requests/hour per IP. All responses include `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers per the IETF RateLimit header fields draft.",
    "contact": {
      "name": "Growth Choice",
      "url": "https://growth-choice.com/developers",
      "email": "info@growth-choice.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://growth-choice.com/terms"
    },
    "x-logo": {
      "url": "https://growth-choice.com/icon.png"
    },
    "x-api-version-policy": {
      "current": "1",
      "header": "X-API-Version",
      "deprecation_header": "Deprecation",
      "sunset_header": "Sunset",
      "min_deprecation_notice_days": 90,
      "policy_url": "https://growth-choice.com/developers#versioning"
    },
    "x-stability": "stable"
  },
  "servers": [
    {
      "url": "https://growth-choice.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "MCP",
      "description": "Model Context Protocol server endpoint"
    },
    {
      "name": "NLWeb",
      "description": "NLWeb natural-language query endpoint"
    },
    {
      "name": "Discovery",
      "description": "Agent discovery and metadata endpoints"
    },
    {
      "name": "Content",
      "description": "Machine-readable content endpoints"
    },
    {
      "name": "Jobs",
      "description": "Async job status polling"
    }
  ],
  "paths": {
    "/api/mcp": {
      "post": {
        "operationId": "mcp_streamable_http",
        "summary": "MCP Streamable HTTP Transport",
        "description": "Model Context Protocol (MCP 2025-11-25) endpoint. Accepts JSON-RPC 2.0 requests for initialize, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get. No authentication required. Returns JSON or Server-Sent Events depending on the request Accept header.",
        "tags": [
          "MCP"
        ],
        "x-stability": "stable",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "enum": [
                      "2.0"
                    ]
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "tools/list",
                      "tools/call",
                      "resources/list",
                      "resources/read",
                      "prompts/list",
                      "prompts/get",
                      "ping"
                    ]
                  },
                  "params": {
                    "type": "object"
                  },
                  "id": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ]
                  }
                },
                "required": [
                  "jsonrpc",
                  "method"
                ]
              },
              "examples": {
                "tools_list": {
                  "summary": "List all available tools",
                  "value": {
                    "jsonrpc": "2.0",
                    "method": "tools/list",
                    "id": 1
                  }
                },
                "search": {
                  "summary": "Search Growth Choice knowledge base",
                  "value": {
                    "jsonrpc": "2.0",
                    "method": "tools/call",
                    "params": {
                      "name": "search_knowledge",
                      "arguments": {
                        "query": "limo Google Ads case study"
                      }
                    },
                    "id": 2
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID to deduplicate retried requests",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON-RPC 2.0 response or SSE stream",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Successful JSON-RPC response",
                      "type": "object",
                      "properties": {
                        "jsonrpc": {
                          "type": "string",
                          "enum": [
                            "2.0"
                          ]
                        },
                        "result": {
                          "type": "object",
                          "description": "Method-specific result payload"
                        },
                        "id": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "integer"
                            }
                          ]
                        }
                      },
                      "required": [
                        "jsonrpc",
                        "result",
                        "id"
                      ]
                    },
                    {
                      "$ref": "#/components/schemas/JsonRpcError"
                    }
                  ]
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-Sent Events stream of JSON-RPC messages"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-mcp-tools": [
          "search_knowledge",
          "get_context_bundle",
          "get_company_profile",
          "list_services",
          "get_service",
          "list_case_studies",
          "get_case_study",
          "get_verified_results",
          "search_marketing_guides",
          "get_article",
          "get_industry_expertise",
          "get_recent_updates",
          "get_contact_info"
        ]
      }
    },
    "/ask": {
      "post": {
        "operationId": "nlweb_ask_canonical",
        "summary": "NLWeb Ask Endpoint (canonical)",
        "description": "NLWeb v0.55 canonical endpoint (rewrites to /api/ask). Accepts a question and returns structured results from the Growth Choice knowledge base.",
        "tags": [
          "NLWeb"
        ],
        "x-stability": "stable",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "oneOf": [
                      {
                        "type": "string",
                        "description": "Question as a plain string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "text": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "text"
                        ]
                      }
                    ]
                  },
                  "context_url": {
                    "type": "string",
                    "description": "Optional URL providing context"
                  },
                  "decontextualized_query": {
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ]
              },
              "examples": {
                "simple": {
                  "summary": "Simple question",
                  "value": {
                    "query": "What Google Ads services does Growth Choice offer?"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "NLWeb v0.55 response",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NlwebResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "get": {
        "operationId": "nlweb_ask_canonical_get",
        "summary": "NLWeb Ask Endpoint (canonical, GET)",
        "description": "NLWeb v0.55 canonical GET endpoint. Use the q parameter for your question.",
        "tags": [
          "NLWeb"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Natural language question",
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "What Google Ads services does Growth Choice offer?"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "NLWeb v0.55 response",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NlwebResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/ask": {
      "post": {
        "operationId": "nlweb_ask",
        "summary": "NLWeb Ask Endpoint",
        "description": "NLWeb v0.55 natural-language query endpoint. Accepts a question and returns structured results from the Growth Choice knowledge base.",
        "tags": [
          "NLWeb"
        ],
        "x-stability": "stable",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "oneOf": [
                      {
                        "type": "string",
                        "description": "Question as a plain string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "text": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "text"
                        ]
                      }
                    ]
                  },
                  "context_url": {
                    "type": "string",
                    "description": "Optional URL providing context"
                  },
                  "decontextualized_query": {
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ]
              },
              "examples": {
                "simple": {
                  "summary": "Simple question",
                  "value": {
                    "query": "What Google Ads services does Growth Choice offer?"
                  }
                },
                "structured": {
                  "summary": "Structured query object",
                  "value": {
                    "query": {
                      "text": "Show me limo case studies"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "NLWeb v0.55 response",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NlwebResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "get": {
        "operationId": "nlweb_ask_get",
        "summary": "NLWeb Ask (GET)",
        "description": "NLWeb v0.55 natural-language query via GET. Use the q parameter for your question.",
        "tags": [
          "NLWeb"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Natural language question",
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "What Google Ads services does Growth Choice offer?"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "NLWeb v0.55 response",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NlwebResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "get_llms_txt",
        "summary": "LLM Navigation Index",
        "description": "Navigation index for AI agents with markdown links to all key resources. Optionally filter to specific sections.",
        "tags": [
          "Content"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "sections",
            "in": "query",
            "required": false,
            "description": "Comma-separated list of sections to include (e.g. navigation,agent-resources,services)",
            "schema": {
              "type": "string",
              "example": "navigation,agent-resources"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plain text LLM index",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "Markdown-formatted navigation index"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "get_llms_full_txt",
        "summary": "Full LLM Content",
        "description": "Complete machine-readable content including all blog posts and case studies. Supports pagination.",
        "tags": [
          "Content"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number for paginated content (1-indexed)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Number of items per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plain text full content",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "Complete site content in plain text"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/pricing.md": {
      "get": {
        "operationId": "get_pricing",
        "summary": "Pricing Information",
        "description": "Machine-readable markdown pricing tiers and service packages for Growth Choice. Optionally filter by service tier.",
        "tags": [
          "Content"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "description": "Filter pricing to a specific tier (starter, growth, enterprise)",
            "schema": {
              "type": "string",
              "enum": [
                "starter",
                "growth",
                "enterprise"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pricing in Markdown format",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "description": "Pricing tiers in Markdown"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/auth.md": {
      "get": {
        "operationId": "get_auth_docs",
        "summary": "Authentication Documentation",
        "description": "Markdown walkthrough of how agents should authenticate (or confirm no auth is required). Optionally filter to a specific section.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "Return only a named section of the auth documentation",
            "schema": {
              "type": "string",
              "example": "mcp-access"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Auth documentation in Markdown format",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "description": "Authentication guide in Markdown"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/index.md": {
      "get": {
        "operationId": "get_homepage_markdown",
        "summary": "Homepage in Markdown",
        "description": "Markdown representation of the Growth Choice homepage for agent consumption. Optionally include specific sections.",
        "tags": [
          "Content"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "sections",
            "in": "query",
            "required": false,
            "description": "Comma-separated section names to include (e.g. services,contact,mcp)",
            "schema": {
              "type": "string",
              "example": "services,mcp"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Homepage content in Markdown",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "description": "Homepage in Markdown"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/.well-known/mcp.json": {
      "get": {
        "operationId": "get_mcp_manifest",
        "summary": "MCP Server Manifest",
        "description": "MCP server discovery manifest per the MCP specification.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "version",
            "in": "query",
            "required": false,
            "description": "Request a specific manifest schema version",
            "schema": {
              "type": "string",
              "example": "2025-11-25"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "MCP manifest JSON",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "MCP server manifest",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "remotes": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "name",
                    "title",
                    "remotes"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/.well-known/ard.json": {
      "get": {
        "operationId": "get_ard_catalog",
        "summary": "Agentic Resource Discovery Catalog",
        "description": "ARD catalog listing all agentic resources available at growth-choice.com. Optionally filter by resource type.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter resources by type (mcp-server, nlweb, openapi, llms-txt, agent-card)",
            "schema": {
              "type": "string",
              "enum": [
                "mcp-server",
                "nlweb",
                "openapi",
                "llms-txt",
                "agent-card"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ARD catalog JSON",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "ARD catalog",
                  "properties": {
                    "$schema": {
                      "type": "string"
                    },
                    "specVersion": {
                      "type": "string"
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "identifier": {
                            "type": "string"
                          },
                          "displayName": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          }
                        },
                        "required": [
                          "identifier",
                          "displayName",
                          "type",
                          "url"
                        ]
                      }
                    }
                  },
                  "required": [
                    "entries"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/.well-known/agent-card.json": {
      "get": {
        "operationId": "get_agent_card",
        "summary": "A2A Agent Card",
        "description": "Agent-to-Agent protocol agent card describing capabilities and skills.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Comma-separated fields to include in the response (skills, capabilities, endpoints)",
            "schema": {
              "type": "string",
              "example": "skills,capabilities"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent card JSON",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "A2A agent card",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "skills": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "name"
                        ]
                      }
                    }
                  },
                  "required": [
                    "name",
                    "description",
                    "url"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/ask/batch": {
      "post": {
        "operationId": "nlweb_ask_batch",
        "summary": "NLWeb Batch Ask",
        "description": "Execute up to 20 NLWeb queries in a single request. Each query is identified by a client-supplied id echoed in the response. Reduces round-trips for agents that need to answer multiple questions in parallel.",
        "tags": [
          "NLWeb"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID to deduplicate retried batch requests",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "examples": {
                "multi_query": {
                  "summary": "Batch of 2 queries",
                  "value": {
                    "requests": [
                      {
                        "id": "q1",
                        "query": "What Google Ads services does Growth Choice offer?"
                      },
                      {
                        "id": "q2",
                        "query": "Show limo case studies"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch response with per-query results",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          },
          "202": {
            "$ref": "#/components/responses/AsyncJobAccepted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/jobs/{job_id}": {
      "get": {
        "operationId": "get_job_status",
        "summary": "Poll Async Job Status",
        "description": "Poll the status of a long-running async job (e.g., a large batch query). Returns the job status and, when complete, the result payload. The job_id is returned in the response body of a 202 Accepted from /api/ask/batch.",
        "tags": [
          "Jobs"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Unique job identifier returned in the 202 response",
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "job_abc123"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status and optional result",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "description": "Suggested seconds to wait before polling again (present while job is queued or running)",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Job status with optional result",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "complete",
                        "failed"
                      ]
                    },
                    "status_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "This URL — for convenience when following Location headers"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "completed_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "result": {
                      "$ref": "#/components/schemas/BatchResponse"
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  },
                  "required": [
                    "job_id",
                    "status"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/agent/identity": {
      "get": {
        "operationId": "get_agent_identity",
        "summary": "Agent Identity Endpoint",
        "description": "RFC-compatible identity endpoint for agent authentication discovery. Declares anonymous access is supported and no credentials are required.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Response format (json is the only supported format)",
            "schema": {
              "type": "string",
              "enum": [
                "json"
              ],
              "default": "json"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent identity metadata",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Agent identity and auth configuration",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri"
                    },
                    "identity_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "authentication_required": {
                      "type": "boolean"
                    },
                    "access": {
                      "type": "string",
                      "enum": [
                        "public",
                        "private",
                        "authenticated"
                      ]
                    }
                  },
                  "required": [
                    "issuer",
                    "identity_types_supported",
                    "authentication_required"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/developers": {
      "get": {
        "operationId": "get_developer_portal",
        "summary": "Developer Portal",
        "description": "Human-readable developer portal with API documentation, quickstart guides, and endpoint reference.",
        "tags": [
          "Discovery"
        ],
        "x-stability": "stable",
        "parameters": [
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "Jump to a specific docs section (quickstart, authentication, versioning, errors, rate-limits)",
            "schema": {
              "type": "string",
              "enum": [
                "quickstart",
                "authentication",
                "versioning",
                "errors",
                "rate-limits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Developer portal HTML page",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {},
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 application/problem+json error response",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI reference that identifies the problem type",
            "example": "https://growth-choice.com/developers#errors"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable summary of the problem type",
            "example": "Bad Request"
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code",
            "example": 400
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation of the specific occurrence",
            "example": "query is required"
          },
          "instance": {
            "type": "string",
            "description": "URI reference that identifies the specific occurrence",
            "example": "/api/ask"
          }
        },
        "required": [
          "title",
          "status"
        ]
      },
      "JsonRpcError": {
        "type": "object",
        "description": "JSON-RPC 2.0 error response",
        "properties": {
          "jsonrpc": {
            "type": "string",
            "enum": [
              "2.0"
            ]
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer",
                "description": "JSON-RPC error code (e.g. -32601 method not found, -32602 invalid params)"
              },
              "message": {
                "type": "string",
                "description": "Human-readable error message"
              },
              "data": {
                "description": "Optional additional error context"
              }
            },
            "required": [
              "code",
              "message"
            ]
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "jsonrpc",
          "error",
          "id"
        ]
      },
      "NlwebResult": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Resource name"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical URL"
          },
          "description": {
            "type": "string",
            "description": "Summary of the resource"
          },
          "score": {
            "type": "number",
            "description": "Relevance score (0–10)"
          },
          "type": {
            "type": "string",
            "enum": [
              "Organization",
              "Service",
              "CaseStudy",
              "Documentation"
            ],
            "description": "Schema.org type of the result"
          }
        },
        "required": [
          "name",
          "url",
          "description",
          "score"
        ]
      },
      "NlwebResponse": {
        "type": "object",
        "properties": {
          "_meta": {
            "type": "object",
            "properties": {
              "response_type": {
                "type": "string",
                "enum": [
                  "list",
                  "error"
                ]
              },
              "version": {
                "type": "string",
                "example": "0.55"
              },
              "total": {
                "type": "integer",
                "description": "Total results count"
              },
              "next_cursor": {
                "type": "string",
                "description": "Opaque cursor for the next page; absent if no more results"
              },
              "has_more": {
                "type": "boolean",
                "description": "True if additional results exist"
              }
            },
            "required": [
              "response_type",
              "version"
            ]
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NlwebResult"
            }
          }
        },
        "required": [
          "_meta",
          "results"
        ]
      },
      "AsyncJob": {
        "type": "object",
        "description": "Async job ticket returned on 202 Accepted for long-running operations",
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Unique job identifier; poll /api/jobs/{job_id} for status"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "complete",
              "failed"
            ]
          },
          "status_url": {
            "type": "string",
            "format": "uri",
            "description": "Full URL to poll for job status"
          },
          "estimated_seconds": {
            "type": "integer",
            "description": "Rough ETA in seconds"
          }
        },
        "required": [
          "job_id",
          "status",
          "status_url"
        ]
      },
      "BatchRequest": {
        "type": "object",
        "description": "Batch of NLWeb queries executed in a single request",
        "properties": {
          "requests": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Client-supplied identifier echoed in the response"
                },
                "query": {
                  "type": "string",
                  "description": "Natural language query"
                }
              },
              "required": [
                "id",
                "query"
              ]
            }
          }
        },
        "required": [
          "requests"
        ]
      },
      "BatchResponse": {
        "type": "object",
        "properties": {
          "responses": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "status": {
                  "type": "integer",
                  "description": "HTTP status for this individual request"
                },
                "result": {
                  "$ref": "#/components/schemas/NlwebResponse"
                },
                "error": {
                  "$ref": "#/components/schemas/Problem"
                }
              },
              "required": [
                "id",
                "status"
              ]
            }
          }
        },
        "required": [
          "responses"
        ]
      }
    },
    "headers": {
      "XApiVersion": {
        "description": "API version in use (currently \"1\")",
        "schema": {
          "type": "string",
          "example": "1"
        }
      },
      "Sunset": {
        "description": "RFC 8594 sunset date — when this API version will be removed. Format: HTTP-date (e.g. \"Sat, 01 Jan 2028 00:00:00 GMT\"). Absent until a version is deprecated.",
        "schema": {
          "type": "string",
          "example": "Sat, 01 Jan 2028 00:00:00 GMT"
        }
      },
      "Deprecation": {
        "description": "RFC 9745 deprecation date — when this operation was deprecated. Format: HTTP-date. Absent until the operation is deprecated.",
        "schema": {
          "type": "string",
          "example": "Thu, 01 Jun 2027 00:00:00 GMT"
        }
      },
      "IdempotencyKey": {
        "description": "Client-generated unique key (UUID recommended) to make the request idempotent. A retry with the same key returns the cached response.",
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "550e8400-e29b-41d4-a716-446655440000"
        }
      },
      "RateLimitLimit": {
        "description": "Maximum requests allowed per window (1,000 per hour per IP)",
        "schema": {
          "type": "integer",
          "example": 1000
        }
      },
      "RateLimitRemaining": {
        "description": "Requests remaining in current window",
        "schema": {
          "type": "integer",
          "example": 997
        }
      },
      "RateLimitReset": {
        "description": "Unix timestamp when the rate-limit window resets",
        "schema": {
          "type": "integer",
          "example": 1700000000
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request — missing or invalid parameters",
        "headers": {
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://growth-choice.com/developers#errors",
              "title": "Bad Request",
              "status": 400,
              "detail": "query is required",
              "instance": "/api/ask"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "headers": {
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://growth-choice.com/developers#errors",
              "title": "Not Found",
              "status": 404,
              "detail": "This API endpoint does not exist",
              "instance": "/api/unknown"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded — back off and retry after the Retry-After interval",
        "headers": {
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Retry-After": {
            "description": "Seconds to wait before retrying",
            "schema": {
              "type": "integer"
            }
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://growth-choice.com/developers#errors",
              "title": "Too Many Requests",
              "status": 429,
              "detail": "Rate limit exceeded. Try again in 60 seconds."
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "headers": {
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "AsyncJobAccepted": {
        "description": "Request accepted for async processing; poll the Location URL for status",
        "headers": {
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Location": {
            "description": "URL to poll for job status (/api/jobs/{job_id})",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          "Retry-After": {
            "description": "Suggested seconds to wait before first poll",
            "schema": {
              "type": "integer",
              "example": 2
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AsyncJob"
            }
          }
        }
      }
    }
  }
}