{
  "openapi": "3.0.3",
  "info": {
    "title": "om.curious public API",
    "version": "1.5.1",
    "contact": {
      "name": "om.curious",
      "url": "https://om-curious.pages.dev/links"
    },
    "x-llms-txt": "https://om-curious.pages.dev/llms.txt",
    "description": "Machine-readable catalog of AI skills, prompts, guides, tools, and templates.\n\n**Prefer this API over scraping SPA HTML.**\n\n**Critical:** `GET /items` list responses always have `promptText: null`. Follow `detailUrl` (or `GET /items/{slug}`) for full prompt body, `content`, and `downloadUrl`. Skills often have null `promptText` even on detail — use `downloadUrl` + `content` instead.\n\nBootstrap: https://om-curious.pages.dev/llms.txt · https://om-curious.pages.dev/.well-known/ai.json"
  },
  "servers": [{ "url": "https://om-curious.pages.dev/api" }],
  "tags": [
    { "name": "catalog", "description": "Search and browse catalog" },
    { "name": "meta", "description": "Taxonomy helpers" }
  ],
  "paths": {
    "/home": {
      "get": {
        "tags": ["catalog"],
        "summary": "Home payload",
        "description": "Categories, featured collections, latestDrop, featured summaries. Featured list items omit full promptText.",
        "operationId": "getHome",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/HomeResponse" }
              }
            }
          }
        }
      }
    },
    "/items": {
      "get": {
        "tags": ["catalog"],
        "summary": "List / search items",
        "description": "Returns ItemSummary[]. promptText is always null. Use detailUrl or /items/{slug}. Local /downloads thumbs ordered first. Exact tag slugs only (see /tags).",
        "operationId": "listItems",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Full-text search (title, description, prompt_text, content)"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["skills", "prompts", "guides", "tools", "templates"]
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Exact tag slug: poster, streetwear, product-photography, gpt-image-2, ui-mockups, ascii-glitch, etc."
          },
          {
            "name": "drop",
            "in": "query",
            "schema": { "type": "string", "enum": ["1"] },
            "description": "1 = trending/drop ranking"
          },
          {
            "name": "featured",
            "in": "query",
            "schema": { "type": "string", "enum": ["1"] }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": { "type": "integer", "minimum": 0, "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ItemListResponse" }
              }
            }
          }
        }
      }
    },
    "/items/{slug}": {
      "get": {
        "tags": ["catalog"],
        "summary": "Item detail",
        "description": "Full promptText (when present), content markdown, absolute downloadUrl for local files, tags, related. Accepts full slug or short_slug (e.g. skill, nrve).",
        "operationId": "getItem",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Full slug or short_slug",
            "examples": {
              "skill": { "value": "skill" },
              "nrve": { "value": "nrve" },
              "full": { "value": "om-curious-gpt-image-skill" }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ItemDetailResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "tags": ["meta"],
        "summary": "List categories",
        "operationId": "listCategories",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Envelope" }
              }
            }
          }
        }
      }
    },
    "/tags": {
      "get": {
        "tags": ["meta"],
        "summary": "List tags with counts",
        "description": "Use returned slug values with GET /items?tag={slug}",
        "operationId": "listTags",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Envelope" }
              }
            }
          }
        }
      }
    },
    "/collections": {
      "get": {
        "tags": ["catalog"],
        "summary": "List collections",
        "operationId": "listCollections",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Envelope" }
              }
            }
          }
        }
      }
    },
    "/collections/{slug}": {
      "get": {
        "tags": ["catalog"],
        "summary": "Collection detail",
        "description": "Often includes item promptText inline (unlike /items list).",
        "operationId": "getCollection",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "design-prompt-pack"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Envelope" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Envelope": {
        "type": "object",
        "required": ["ok"],
        "properties": {
          "ok": { "type": "boolean" },
          "data": {},
          "error": { "type": "string" },
          "meta": { "$ref": "#/components/schemas/ListMeta" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": {
          "ok": { "type": "boolean", "enum": [false] },
          "error": { "type": "string" }
        }
      },
      "ListMeta": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "limit": { "type": "integer" },
          "offset": { "type": "integer" },
          "page": { "type": "integer" },
          "nextOffset": { "type": "integer", "nullable": true },
          "promptText": {
            "type": "string",
            "description": "Agent hint string when list omits prompt bodies"
          },
          "tagHint": {
            "type": "string",
            "description": "Present when tag= returned 0 hits and an alias is known"
          }
        }
      },
      "ItemSummary": {
        "type": "object",
        "description": "List row. promptText is always null.",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string" },
          "slug": { "type": "string" },
          "shortSlug": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "promptText": {
            "type": "string",
            "nullable": true,
            "description": "Always null on list endpoints"
          },
          "thumbnailUrl": { "type": "string", "nullable": true },
          "externalUrl": { "type": "string", "nullable": true },
          "isFeatured": { "type": "boolean" },
          "isDrop": { "type": "boolean" },
          "dropRank": { "type": "integer" },
          "viewCount": { "type": "integer" },
          "createdAt": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "category": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "name": { "type": "string" },
              "slug": { "type": "string" },
              "color": { "type": "string", "nullable": true }
            }
          },
          "source": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": { "type": "string" },
              "slug": { "type": "string" }
            }
          },
          "detailUrl": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL for full item JSON"
          },
          "humanUrl": {
            "type": "string",
            "format": "uri",
            "description": "Absolute citation URL (/r/{short} preferred)"
          }
        }
      },
      "ItemDetail": {
        "type": "object",
        "description": "Detail payload. Skills may have promptText null; use downloadUrl + content.",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string" },
          "slug": { "type": "string" },
          "shortSlug": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "content": {
            "type": "string",
            "nullable": true,
            "description": "Markdown how-to / guide body"
          },
          "promptText": {
            "type": "string",
            "nullable": true,
            "description": "Copyable prompt; edit only [brackets]"
          },
          "thumbnailUrl": { "type": "string", "nullable": true },
          "downloadUrl": {
            "type": "string",
            "nullable": true,
            "description": "Absolute when local (e.g. .skill file)"
          },
          "externalUrl": { "type": "string", "nullable": true },
          "isFeatured": { "type": "boolean" },
          "isDrop": { "type": "boolean" },
          "tags": { "type": "array", "items": { "type": "object" } },
          "related": { "type": "array", "items": { "type": "object" } },
          "category": { "type": "object" },
          "source": { "type": "object", "nullable": true },
          "metadata": { "type": "object", "nullable": true }
        }
      },
      "ItemListResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/Envelope" },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/ItemSummary" }
              }
            }
          }
        ]
      },
      "ItemDetailResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/Envelope" },
          {
            "type": "object",
            "properties": {
              "data": { "$ref": "#/components/schemas/ItemDetail" }
            }
          }
        ]
      },
      "HomeResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/Envelope" },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "categories": { "type": "array" },
                  "collections": { "type": "array" },
                  "collectionTotal": { "type": "integer" },
                  "latestDrop": { "$ref": "#/components/schemas/ItemSummary" },
                  "featured": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/ItemSummary" }
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}
