{
  "openapi": "3.1.0",
  "info": {
    "title": "cectoken.com Public API",
    "description": "Public, read-only JSON API for the cectoken.com collectible-token catalog. Built for AI agents, researchers, and integrators. No authentication required.",
    "version": "1.0.0",
    "contact": {
      "name": "cectoken.com",
      "email": "contact@cectoken.com",
      "url": "https://cectoken.com/contact"
    }
  },
  "servers": [
    { "url": "https://cectoken.com/api/v1", "description": "Production" }
  ],
  "paths": {
    "/items/search": {
      "get": {
        "summary": "Search tokens",
        "description": "Search the cectoken.com catalog by keyword, brand, and/or composition.",
        "operationId": "searchItems",
        "parameters": [
          { "name": "q", "in": "query", "description": "Free-text search (matches name, catalog code, front/back text, location, variety).", "required": false, "schema": { "type": "string", "maxLength": 200 } },
          { "name": "brand", "in": "query", "description": "Brand id or slug.", "required": false, "schema": { "type": "string" } },
          { "name": "composition", "in": "query", "description": "Exact composition string (e.g., \"Brass\", \"Nickel-Silver\").", "required": false, "schema": { "type": "string" } },
          { "name": "per_page", "in": "query", "description": "Results per page (max 100).", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
          { "name": "page", "in": "query", "description": "Page number.", "required": false, "schema": { "type": "integer", "minimum": 1, "default": 1 } }
        ],
        "responses": {
          "200": {
            "description": "Paginated item list",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ItemList" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/items/{slug}": {
      "get": {
        "summary": "Get a single token by slug",
        "description": "Returns the full token record including current pricing, peak/last sale, recent sales history, and narrative description.",
        "operationId": "getItem",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Token detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/ItemDetail" } }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/brands/{slug}": {
      "get": {
        "summary": "Get a brand entity",
        "description": "Returns the brand record with catalog stats, aggregate sales, and a list of top tokens.",
        "operationId": "getBrand",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Brand detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/BrandDetail" } }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/guides": {
      "get": {
        "summary": "List published guides",
        "description": "Returns a paginated list of published guides. Filter by category if desired.",
        "operationId": "listGuides",
        "parameters": [
          { "name": "category", "in": "query", "required": false, "schema": { "type": "string", "enum": ["cec", "showbiz", "discovery-zone", "other-brands", "how-to", "market"] } },
          { "name": "per_page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
          { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "default": 1 } }
        ],
        "responses": {
          "200": {
            "description": "Paginated guide list",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GuideList" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/guides/{slug}": {
      "get": {
        "summary": "Get a guide",
        "description": "Returns a single guide including its full markdown content.",
        "operationId": "getGuide",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Guide detail with markdown content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/GuideDetail" } }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "NotFound": {
        "description": "Resource not found",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (60 requests per minute per IP).",
        "headers": {
          "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until the limit resets." }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": { "message": { "type": "string" } }
      },
      "ItemSummary": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": "string" },
          "catalog_code": { "type": "string", "nullable": true },
          "name": { "type": "string" },
          "composition": { "type": "string", "nullable": true },
          "vintage": { "type": "integer", "nullable": true },
          "diameter_mm": { "type": "number", "nullable": true },
          "is_coin": { "type": "boolean" },
          "rarity": {
            "type": "object",
            "properties": {
              "level": { "type": "integer", "minimum": 1, "maximum": 5 },
              "label": { "type": "string", "nullable": true }
            }
          },
          "brand": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": { "type": "integer" },
              "slug": { "type": "string" },
              "name": { "type": "string" }
            }
          },
          "urls": {
            "type": "object",
            "properties": {
              "web": { "type": "string", "format": "uri" },
              "api": { "type": "string", "format": "uri" }
            }
          }
        }
      },
      "ItemDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/ItemSummary" },
          {
            "type": "object",
            "properties": {
              "narrative": { "type": "string" },
              "inscriptions": {
                "type": "object",
                "properties": {
                  "front": { "type": "string", "nullable": true },
                  "back": { "type": "string", "nullable": true }
                }
              },
              "pricing": {
                "type": "object",
                "properties": {
                  "currency": { "type": "string", "example": "USD" },
                  "fair_value_cents": { "type": "integer", "nullable": true },
                  "last_price_cents": { "type": "integer", "nullable": true },
                  "last_sold_at": { "type": "string", "format": "date", "nullable": true },
                  "peak_price_cents": { "type": "integer", "nullable": true },
                  "peak_sold_at": { "type": "string", "format": "date", "nullable": true },
                  "tracked_sales_count": { "type": "integer" },
                  "tracked_sales_total_cents": { "type": "integer" }
                }
              },
              "recent_sales": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "sold_at": { "type": "string", "format": "date" },
                    "quantity": { "type": "integer" },
                    "unit_price_cents": { "type": "integer" },
                    "currency": { "type": "string" }
                  }
                }
              }
            }
          }
        ]
      },
      "ItemList": {
        "type": "object",
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/ItemSummary" } },
          "links": { "type": "object" },
          "meta": { "type": "object" }
        }
      },
      "BrandDetail": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "significance": { "type": "string", "nullable": true },
          "established_year": { "type": "integer", "nullable": true },
          "logo_url": { "type": "string", "format": "uri", "nullable": true },
          "stats": {
            "type": "object",
            "properties": {
              "item_count": { "type": "integer" },
              "vintage_min": { "type": "integer", "nullable": true },
              "vintage_max": { "type": "integer", "nullable": true },
              "tracked_sales_count": { "type": "integer" },
              "tracked_sales_total_cents": { "type": "integer" },
              "peak_price_cents": { "type": "integer", "nullable": true },
              "currency": { "type": "string" }
            }
          }
        }
      },
      "GuideSummary": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "excerpt": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true },
          "tags": { "type": "array", "items": { "type": "string" } },
          "urls": {
            "type": "object",
            "properties": {
              "web": { "type": "string", "format": "uri" },
              "api": { "type": "string", "format": "uri" }
            }
          },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "updated_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "GuideDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/GuideSummary" },
          {
            "type": "object",
            "properties": {
              "content_markdown": { "type": "string" }
            }
          }
        ]
      },
      "GuideList": {
        "type": "object",
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/GuideSummary" } },
          "links": { "type": "object" },
          "meta": { "type": "object" }
        }
      }
    }
  }
}
