{
  "openapi": "3.0.3",
  "info": {
    "title": "pipeAgent Consumer API",
    "description": "Discovery and feed consumption for AI agents.\n\n**Authentication (read key required):** `/v1/catalog`, `/v1/search`, `/v1/feed/{id}/metadata`, `/v1/feed/{id}` require an active **read** API key via `x-api-key` or `Authorization: Bearer`. Write-only keys get 403.\n\n**Pagination:** `catalog` and `search` use `limit` (default 20, max 100) and `offset` (default 0); responses include `total`, `has_more`, `limit`, `offset`.\n\n**Public (no key):** `GET /public/feeds/{id}/openclaw-skill` — see product docs.\n\n**Feed id:** UUID or `endpoint_path` for `/v1/feed/{id}/metadata` (same as website detail page).",
    "version": "1.1.0"
  },
  "servers": [
    { "url": "https://api.pipeagent.dev", "description": "Production API host" },
    { "url": "http://localhost:3000", "description": "Local Next.js app" }
  ],
  "tags": [
    { "name": "Discovery", "description": "Search and catalog (read key, paginated)" },
    { "name": "Feed", "description": "Metadata and data reads (read key)" }
  ],
  "paths": {
    "/v1/catalog": {
      "get": {
        "tags": ["Discovery"],
        "summary": "List active feeds",
        "description": "Paginated directory of active feeds with consumer_type.",
        "security": [{ "ApiKeyAuth": [] }, { "BearerAuth": [] }],
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CatalogResponse" }
              }
            }
          },
          "401": { "description": "Missing API key" },
          "403": { "description": "Invalid or non-read key" },
          "500": { "description": "Server error" }
        }
      }
    },
    "/v1/search": {
      "get": {
        "tags": ["Discovery"],
        "summary": "Full-text search feeds",
        "security": [{ "ApiKeyAuth": [] }, { "BearerAuth": [] }],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Search query"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "400": { "description": "Missing q" },
          "401": { "description": "Missing API key" },
          "403": { "description": "Invalid or non-read key" },
          "500": { "description": "Server error" }
        }
      }
    },
    "/v1/feed/{id}/metadata": {
      "get": {
        "tags": ["Feed"],
        "summary": "Feed metadata (no data payload)",
        "description": "Schema, storage model, sample, pricing hints for agents; does not return feed_data rows.",
        "security": [{ "ApiKeyAuth": [] }, { "BearerAuth": [] }],
        "parameters": [{ "$ref": "#/components/parameters/FeedId" }],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/FeedMetadata" }
              }
            }
          },
          "401": { "description": "Missing API key" },
          "403": { "description": "Invalid or non-read key" },
          "404": { "description": "Not found or inactive" }
        }
      }
    },
    "/v1/feed/{id}": {
      "get": {
        "tags": ["Feed"],
        "summary": "Fetch feed data",
        "security": [{ "ApiKeyAuth": [] }, { "BearerAuth": [] }],
        "parameters": [
          { "$ref": "#/components/parameters/FeedId" },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100 }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": { "type": "integer", "minimum": 0 }
          },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } },
          { "name": "jsonpath", "in": "query", "schema": { "type": "string" } },
          { "name": "ids", "in": "query", "schema": { "type": "string" } },
          {
            "name": "start_time",
            "in": "query",
            "schema": { "type": "string", "format": "date-time" }
          },
          {
            "name": "end_time",
            "in": "query",
            "schema": { "type": "string", "format": "date-time" }
          }
        ],
        "responses": {
          "200": {
            "description": "Feed payload",
            "content": {
              "application/json": {
                "schema": { "type": "object" }
              }
            }
          },
          "401": { "description": "Missing API key" },
          "402": { "description": "Payment required" },
          "403": { "description": "Invalid key" },
          "404": { "description": "Not found" },
          "429": { "description": "Rate limited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-KEY"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key"
      }
    },
    "parameters": {
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size (1–100, default 20)",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "description": "Row offset",
        "schema": { "type": "integer", "minimum": 0, "default": 0 }
      },
      "FeedId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Feed UUID or endpoint_path",
        "schema": { "type": "string" }
      }
    },
    "schemas": {
      "CatalogResponse": {
        "type": "object",
        "properties": {
          "message": { "type": "string" },
          "total": { "type": "integer" },
          "total_feeds": {
            "type": "integer",
            "description": "Same as total (legacy alias)"
          },
          "limit": { "type": "integer" },
          "offset": { "type": "integer" },
          "has_more": { "type": "boolean" },
          "feeds": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CatalogFeed" }
          },
          "instructions": { "type": "string" }
        }
      },
      "CatalogFeed": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "category": { "type": "string" },
          "feed_type": { "type": "string" },
          "consumer_type": { "type": "string" },
          "endpoint_path": { "type": "string", "nullable": true },
          "pricing": { "type": "string" },
          "update_frequency": { "type": "string", "nullable": true },
          "reliability": { "type": "string" },
          "last_sync_at": { "type": "string", "format": "date-time", "nullable": true },
          "schema_hint": { "type": "array", "items": { "type": "string" } }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "total": { "type": "integer" },
          "limit": { "type": "integer" },
          "offset": { "type": "integer" },
          "has_more": { "type": "boolean" },
          "results": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/SearchHit" }
          }
        }
      },
      "SearchHit": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "category": { "type": "string" },
          "feed_type": { "type": "string" },
          "consumer_type": { "type": "string" },
          "endpoint_path": { "type": "string", "nullable": true },
          "price_per_1k": { "type": "number" },
          "reliability_score": { "type": "number", "nullable": true },
          "last_sync_at": { "type": "string", "format": "date-time", "nullable": true },
          "update_frequency_text": { "type": "string", "nullable": true }
        }
      },
      "FeedMetadata": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "endpoint_path": { "type": "string", "nullable": true },
          "readme_md": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true },
          "feed_type": { "type": "string", "nullable": true },
          "consumer_type": { "type": "string" },
          "price_per_1k": { "type": "number", "nullable": true },
          "reliability_score": { "type": "number", "nullable": true },
          "last_sync_at": { "type": "string", "format": "date-time", "nullable": true },
          "sync_interval_mins": { "type": "integer", "nullable": true },
          "update_frequency_text": { "type": "string", "nullable": true },
          "storage_config": { "type": "object", "nullable": true },
          "schema_definition": { "nullable": true },
          "sample_response": { "nullable": true },
          "status": { "type": "string" },
          "provider": { "type": "object", "nullable": true }
        }
      }
    }
  }
}
