{
  "openapi": "3.0.3",
  "info": {
    "title": "Agentic Card API",
    "version": "1.0.0",
    "description": "Machine-readable JSON API for Agentic Card: search, list, detail, trust, health, stats, and categories. Successful responses use `{ \"ok\": true, \"data\": ... }`; list endpoints add `meta` with pagination. Errors use `{ \"ok\": false, \"error\": { \"code\", \"message\" } }`. No authentication required for read endpoints. Replace the server URL with your deployment origin.",
    "contact": {
      "url": "https://orangecat.group"
    }
  },
  "servers": [
    {
      "url": "https://example.com",
      "description": "Set this to your site origin (e.g. NEXT_PUBLIC_APP_URL)."
    }
  ],
  "paths": {
    "/api/stats": {
      "get": {
        "operationId": "getStats",
        "summary": "Agentic Card overview",
        "description": "Agentic Card aggregate counts, protocol mix, average trust, endpoint and health summaries.",
        "responses": {
          "200": {
            "description": "Stats payload",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/OkWrapper" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "$ref": "#/components/schemas/StatsData" }
                      }
                    }
                  ]
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/categories": {
      "get": {
        "operationId": "listCategories",
        "summary": "Categories with agent counts",
        "responses": {
          "200": {
            "description": "Category list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/OkWrapper" },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/CategoryRow" }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "searchAgents",
        "summary": "Full-text search",
        "description": "Requires query parameter `q`. Results ordered by trust score (desc).",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Search terms (websearch syntax)."
          },
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "default": 1 }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated agents",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaginatedAgents" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/agents": {
      "get": {
        "operationId": "listAgents",
        "summary": "List and filter agents",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Optional full-text filter."
          },
          {
            "name": "protocol",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Comma-separated: a2a, wildcard, mcp, manual, unknown."
          },
          {
            "name": "category",
            "in": "query",
            "schema": { "type": "string" }
          },
          {
            "name": "tags",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Comma-separated tags (array containment)."
          },
          {
            "name": "min_trust",
            "in": "query",
            "schema": { "type": "integer" }
          },
          {
            "name": "max_trust",
            "in": "query",
            "schema": { "type": "integer" }
          },
          {
            "name": "verification",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["unverified", "claimed", "email_matched", "verified"]
            }
          },
          {
            "name": "has_endpoint",
            "in": "query",
            "schema": { "type": "string", "enum": ["true"] }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["trust", "stars", "newest", "name"],
              "default": "trust"
            }
          },
          {
            "name": "order",
            "in": "query",
            "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" }
          },
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "default": 1 }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated agents",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaginatedAgents" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/agents/{slug}": {
      "get": {
        "operationId": "getAgent",
        "summary": "Agent detail",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Full agent record",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/OkWrapper" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "$ref": "#/components/schemas/AgentDetail" }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/agents/{slug}/trust": {
      "get": {
        "operationId": "getAgentTrust",
        "summary": "Trust score and breakdown",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Trust payload",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/OkWrapper" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "$ref": "#/components/schemas/TrustPayload" }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/agents/{slug}/health": {
      "get": {
        "operationId": "getAgentHealthHistory",
        "summary": "Health checks for a period",
        "description": "Only agents with status `active` are returned (not `evaluating`).",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "period",
            "in": "query",
            "schema": { "type": "string", "enum": ["7d", "30d", "90d"], "default": "30d" }
          }
        ],
        "responses": {
          "200": {
            "description": "Summary and timeseries",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/OkWrapper" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "$ref": "#/components/schemas/HealthHistoryData" }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "OkWrapper": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "enum": [true] }
        },
        "required": ["ok"]
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page": { "type": "integer" },
          "per_page": { "type": "integer" }
        },
        "required": ["total", "page", "per_page"]
      },
      "StatsData": {
        "type": "object",
        "properties": {
          "total_agents": { "type": "integer" },
          "verified_agents": { "type": "integer" },
          "by_protocol": {
            "type": "object",
            "additionalProperties": { "type": "integer" }
          },
          "avg_trust_score": { "type": "number" },
          "agents_with_endpoint": { "type": "integer" },
          "agents_up_now": { "type": "integer" }
        }
      },
      "CategoryRow": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "agent_count": { "type": "integer" }
        }
      },
      "AgentListItem": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "source_protocol": { "type": "string" },
          "endpoint": { "type": "string", "nullable": true },
          "categories": { "type": "array", "items": { "type": "string" } },
          "tags": { "type": "array", "items": { "type": "string" } },
          "trust_score": { "type": "integer" },
          "trust_label": { "type": "string" },
          "verification_tier": { "type": "string" },
          "github": {
            "type": "object",
            "nullable": true,
            "properties": {
              "stars": { "type": "integer" },
              "last_push": { "type": "string", "nullable": true }
            }
          },
          "health": {
            "type": "object",
            "nullable": true,
            "properties": {
              "is_up": { "type": "boolean" },
              "uptime_30d": { "type": "number", "nullable": true },
              "avg_latency_ms": { "type": "integer", "nullable": true }
            }
          }
        }
      },
      "PaginatedAgents": {
        "allOf": [
          { "$ref": "#/components/schemas/OkWrapper" },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/AgentListItem" }
              },
              "meta": { "$ref": "#/components/schemas/PaginationMeta" }
            },
            "required": ["data", "meta"]
          }
        ]
      },
      "TrustPayload": {
        "type": "object",
        "properties": {
          "score": { "type": "integer" },
          "label": { "type": "string" },
          "breakdown": { "type": "object", "additionalProperties": true },
          "last_evaluated_at": { "type": "string", "nullable": true }
        }
      },
      "AgentDetail": {
        "type": "object",
        "description": "Full agent detail including trust, verification, capabilities, github, health summary, and raw_card.",
        "additionalProperties": true,
        "properties": {
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "long_description": { "type": "string", "nullable": true },
          "source_protocol": { "type": "string" },
          "endpoint": { "type": "string", "nullable": true },
          "trust": { "$ref": "#/components/schemas/TrustPayload" },
          "verification": { "type": "object", "additionalProperties": true },
          "github": { "type": "object", "nullable": true, "additionalProperties": true },
          "health": { "type": "object", "nullable": true, "additionalProperties": true },
          "capabilities": { "type": "object", "nullable": true, "additionalProperties": true },
          "raw_card": { "nullable": true }
        }
      },
      "HealthHistoryData": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "object",
            "properties": {
              "uptime_pct": { "type": "number", "nullable": true },
              "avg_latency_ms": { "type": "integer", "nullable": true },
              "p95_latency_ms": { "type": "integer", "nullable": true },
              "checks_total": { "type": "integer" },
              "checks_failed": { "type": "integer" }
            }
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "t": { "type": "string" },
                "up": { "type": "boolean" },
                "ms": { "type": "integer", "nullable": true }
              }
            }
          }
        }
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "enum": [false] },
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" }
            },
            "required": ["code", "message"]
          }
        },
        "required": ["ok", "error"]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameters",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" },
            "example": {
              "ok": false,
              "error": { "code": "BAD_REQUEST", "message": "Search query \"q\" is required" }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      },
      "InternalError": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      }
    }
  }
}
