{
  "openapi": "3.1.0",
  "info": {
    "title": "Iwo Szapar Public Content API",
    "version": "1.0.0",
    "description": "A read-only API for published Iwo Szapar blog and Context Engineering Directory content. This contract intentionally excludes customer, checkout, webhook, admin, and product APIs. Start with the developer guide at https://www.iwoszapar.com/developers.",
    "license": { "name": "All rights reserved", "url": "https://www.iwoszapar.com/terms-of-service" }
  },
  "servers": [{ "url": "https://www.iwoszapar.com" }],
  "security": [],
  "tags": [
    { "name": "Blog", "description": "Published articles and case studies." },
    { "name": "Directory", "description": "Published Context Engineering Directory listings." }
  ],
  "paths": {
    "/api/blog/posts": {
      "get": {
        "operationId": "listPublishedBlogPosts",
        "summary": "List published blog posts",
        "description": "Returns a paginated list of published articles or case studies, newest first.",
        "tags": ["Blog"],
        "parameters": [
          { "$ref": "#/components/parameters/Page" },
          { "$ref": "#/components/parameters/Limit" },
          { "name": "orderBy", "in": "query", "description": "Sort field. Defaults to published_at.", "schema": { "type": "string", "enum": ["published_at", "view_count", "created_at"], "default": "published_at" } },
          { "name": "type", "in": "query", "description": "Optional post type filter.", "schema": { "type": "string", "enum": ["case_study"] } }
        ],
        "responses": {
          "200": { "description": "Published posts and pagination metadata.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlogPostListResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/blog/search": {
      "get": {
        "operationId": "searchPublishedBlogPosts",
        "summary": "Search published blog posts",
        "description": "Runs a full-text search over published blog posts.",
        "tags": ["Blog"],
        "parameters": [
          { "name": "q", "in": "query", "required": true, "description": "Non-empty search term.", "schema": { "type": "string", "minLength": 1 } },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": { "description": "Matching published posts.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlogSearchResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/blog/{slug}": {
      "get": {
        "operationId": "getPublishedBlogPost",
        "summary": "Get one published blog post",
        "description": "Returns the published blog post for a slug without recording a view.",
        "tags": ["Blog"],
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "description": "Published blog post slug.", "schema": { "type": "string", "minLength": 1 } }
        ],
        "responses": {
          "200": { "description": "Published blog post.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlogPostResponse" } } } },
          "404": { "$ref": "#/components/responses/NotFound" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/directory/categories": {
      "get": {
        "operationId": "listDirectoryCategories",
        "summary": "List directory categories",
        "description": "Returns published Context Engineering Directory categories with listing counts.",
        "tags": ["Directory"],
        "responses": {
          "200": { "description": "Published directory categories.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectoryCategoryListResponse" } } } },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/directory/listings": {
      "get": {
        "operationId": "listDirectoryListings",
        "summary": "List directory listings",
        "description": "Returns published directory listing summaries. Results can be filtered by category or text search.",
        "tags": ["Directory"],
        "parameters": [
          { "name": "category", "in": "query", "description": "Optional category slug.", "schema": { "type": "string" } },
          { "name": "q", "in": "query", "description": "Optional text search term.", "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/DirectoryLimit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": { "description": "Published directory listing summaries.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectoryListingListResponse" } } } },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/directory/listing": {
      "get": {
        "operationId": "getDirectoryListing",
        "summary": "Get one directory listing",
        "description": "Returns a published Context Engineering Directory listing by slug.",
        "tags": ["Directory"],
        "parameters": [
          { "name": "slug", "in": "query", "required": true, "description": "Directory listing slug.", "schema": { "type": "string", "minLength": 1 } }
        ],
        "responses": {
          "200": { "description": "Published directory listing.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectoryListing" } } } },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "Page": { "name": "page", "in": "query", "description": "One-based page number.", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
      "Limit": { "name": "limit", "in": "query", "description": "Maximum records to return.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } },
      "DirectoryLimit": { "name": "limit", "in": "query", "description": "Maximum directory listings to return.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } },
      "Offset": { "name": "offset", "in": "query", "description": "Zero-based record offset.", "schema": { "type": "integer", "minimum": 0, "default": 0 } }
    },
    "responses": {
      "InvalidParameter": { "description": "A required parameter is missing or invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "MethodNotAllowed": { "description": "The requested HTTP method is not supported.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "NotFound": { "description": "The requested published item was not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "InternalError": { "description": "An unexpected server error occurred.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "resolution"],
            "properties": {
              "code": { "type": "string", "enum": ["method_not_allowed", "invalid_parameter", "missing_parameter", "not_found", "rate_limited", "internal_error"] },
              "message": { "type": "string" },
              "resolution": { "type": "string" }
            }
          }
        }
      },
      "BlogPostSummary": { "type": "object", "required": ["id", "slug", "title", "published_at", "view_count"], "properties": { "id": { "type": "string" }, "slug": { "type": "string" }, "title": { "type": "string" }, "subtitle": { "type": ["string", "null"] }, "excerpt": { "type": ["string", "null"] }, "published_at": { "type": "string", "format": "date-time" }, "view_count": { "type": "integer", "minimum": 0 }, "reading_time_minutes": { "type": ["integer", "null"], "minimum": 0 }, "post_type": { "type": ["string", "null"], "enum": ["article", "case_study", null] } } },
      "BlogPostListResponse": { "type": "object", "required": ["posts", "pagination"], "properties": { "posts": { "type": "array", "items": { "$ref": "#/components/schemas/BlogPostSummary" } }, "pagination": { "type": "object", "required": ["page", "limit", "total", "totalPages", "hasNext", "hasPrev"], "properties": { "page": { "type": "integer" }, "limit": { "type": "integer" }, "total": { "type": "integer" }, "totalPages": { "type": "integer" }, "hasNext": { "type": "boolean" }, "hasPrev": { "type": "boolean" } } } } },
      "BlogSearchResponse": { "type": "object", "required": ["query", "posts", "count", "limit", "offset"], "properties": { "query": { "type": "string" }, "posts": { "type": "array", "items": { "$ref": "#/components/schemas/BlogPostSummary" } }, "count": { "type": "integer", "description": "Number of posts returned by this request." }, "limit": { "type": "integer" }, "offset": { "type": "integer" } } },
      "BlogPost": { "type": "object", "description": "A published blog post in full.", "required": ["id", "slug", "title", "content_html", "author", "published_at", "updated_at", "created_at", "status", "view_count"], "properties": { "id": { "type": "string" }, "slug": { "type": "string" }, "title": { "type": "string" }, "subtitle": { "type": ["string", "null"] }, "excerpt": { "type": ["string", "null"] }, "content_html": { "type": "string" }, "content_markdown": { "type": ["string", "null"] }, "featured_image_url": { "type": ["string", "null"], "format": "uri" }, "thumbnail_url": { "type": ["string", "null"], "format": "uri" }, "og_image": { "type": ["string", "null"], "format": "uri" }, "author": { "type": "string" }, "published_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "created_at": { "type": "string", "format": "date-time" }, "status": { "type": "string", "const": "published" }, "view_count": { "type": "integer", "minimum": 0 }, "reading_time_minutes": { "type": ["integer", "null"], "minimum": 0 }, "seo_title": { "type": ["string", "null"] }, "seo_description": { "type": ["string", "null"] }, "post_type": { "type": ["string", "null"], "enum": ["article", "case_study", null] } } },
      "BlogPostResponse": { "type": "object", "required": ["post"], "properties": { "post": { "$ref": "#/components/schemas/BlogPost" } } },
      "DirectoryCategory": { "type": "object", "required": ["category", "category_slug", "count"], "properties": { "category": { "type": "string" }, "category_slug": { "type": "string" }, "count": { "type": "integer", "minimum": 0 } } },
      "DirectoryCategoryListResponse": { "type": "object", "required": ["categories"], "properties": { "categories": { "type": "array", "items": { "$ref": "#/components/schemas/DirectoryCategory" } } } },
      "DirectoryListingSummary": { "type": "object", "required": ["id", "slug", "title", "profession", "category", "category_slug", "description", "difficulty", "tags", "view_count", "is_featured"], "properties": { "id": { "type": "string" }, "slug": { "type": "string" }, "title": { "type": "string" }, "profession": { "type": "string" }, "category": { "type": "string" }, "category_slug": { "type": "string" }, "description": { "type": "string" }, "difficulty": { "type": "string", "enum": ["beginner", "intermediate", "advanced"] }, "tags": { "type": "array", "items": { "type": "string" } }, "view_count": { "type": "integer", "minimum": 0 }, "is_featured": { "type": "boolean" } } },
      "DirectoryWorkflow": { "type": "object", "required": ["name", "description", "command"], "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "command": { "type": "string" } } },
      "DirectoryMcpServer": { "type": "object", "required": ["name", "reason"], "properties": { "name": { "type": "string" }, "reason": { "type": "string" } } },
      "DirectorySkill": { "type": "object", "required": ["name", "description", "icon"], "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "icon": { "type": "string" } } },
      "DirectoryListing": { "allOf": [{ "$ref": "#/components/schemas/DirectoryListingSummary" }, { "type": "object", "required": ["claude_md_content", "mcp_servers", "workflows", "created_at", "skills", "updated_at"], "properties": { "claude_md_content": { "type": "string" }, "mcp_servers": { "type": "array", "items": { "$ref": "#/components/schemas/DirectoryMcpServer" } }, "workflows": { "type": "array", "items": { "$ref": "#/components/schemas/DirectoryWorkflow" } }, "meta_title": { "type": ["string", "null"] }, "meta_description": { "type": ["string", "null"] }, "created_at": { "type": "string", "format": "date-time" }, "skills": { "type": "array", "items": { "$ref": "#/components/schemas/DirectorySkill" } }, "updated_at": { "type": "string", "format": "date-time" } } }] },
      "DirectoryListingListResponse": { "type": "object", "required": ["listings", "total"], "properties": { "listings": { "type": "array", "items": { "$ref": "#/components/schemas/DirectoryListingSummary" } }, "total": { "type": "integer", "minimum": 0 } } }
    }
  }
}
