{
  "openapi": "3.1.0",
  "info": {
    "title": "TokenJam Website Content API",
    "version": "1.0.0",
    "summary": "Read-only JSON and markdown access to everything published on tokenjam.dev.",
    "description": "A read-only API over the published contents of tokenjam.dev: blog posts, documentation pages, and the catalog of TokenJam optimization analyzers.\n\n**Authentication:** none. Every operation is public, unauthenticated, and safe to call anonymously. Do not send an Authorization header; there is no OAuth flow, no API key, and no signup for this API.\n\n**Rate limits:** no application-level rate limit is enforced. The site is served from a CDN and normal agent traffic needs no coordination; sustained abusive volume may be throttled at the CDN edge.\n\n**Shape:** every response is a JSON object. Collections use a `{ object: \"list\", resource, count, data }` envelope and are returned in full (no pagination). Each item carries `url` (human HTML page), `markdown_url` (clean markdown for LLM consumption), and `api_url` (this API) so an agent can move between representations without guessing.\n\n**Versioning and deprecation:** v1 is current and stable. Breaking changes ship as a new path segment (/api/v2/), never in place. A deprecated endpoint carries a Deprecation header (RFC 9745) and a Sunset header (RFC 8594), is marked `deprecated: true` here, and keeps responding for at least 90 days after that first appears. Full policy: https://tokenjam.dev/api#lifecycle\n\n**Not this API:** the TokenJam CLI runs a separate local server (`tj serve`) on http://127.0.0.1:7391 with its own OpenAPI document at /api/v1/openapi.json and its own bearer-token auth. That one reads your private telemetry; this one only serves public website content.",
    "contact": {
      "name": "TokenJam support",
      "email": "support@tokenjam.dev",
      "url": "https://tokenjam.dev/contact"
    },
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "externalDocs": {
    "description": "TokenJam documentation",
    "url": "https://tokenjam.dev/docs"
  },
  "servers": [
    {
      "url": "https://tokenjam.dev",
      "description": "Production"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "discovery",
      "description": "Entry points that tell an agent what exists and where."
    },
    {
      "name": "blog",
      "description": "Published blog posts."
    },
    {
      "name": "docs",
      "description": "Product documentation pages."
    },
    {
      "name": "products",
      "description": "The TokenJam optimization analyzers."
    },
    {
      "name": "markdown",
      "description": "Plain-markdown representations intended for LLM context."
    }
  ],
  "paths": {
    "/api/v1/index.json": {
      "get": {
        "operationId": "getApiIndex",
        "tags": [
          "discovery"
        ],
        "summary": "API discovery document",
        "description": "Lists every endpoint of this API plus the other machine-readable files on the site (OpenAPI document, llms.txt, agent instructions, sitemap). Start here when you do not already know what tokenjam.dev exposes.",
        "responses": {
          "200": {
            "description": "The discovery document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/posts.json": {
      "get": {
        "operationId": "listBlogPosts",
        "tags": [
          "blog"
        ],
        "summary": "List all published blog posts",
        "description": "Returns every published post, newest first. Future-dated posts are excluded until their publish date passes. Use `markdown_url` to read a post body cheaply, or `api_url` for the same body as JSON.",
        "responses": {
          "200": {
            "description": "All published posts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPostList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/posts/{postId}.json": {
      "get": {
        "operationId": "getBlogPost",
        "tags": [
          "blog"
        ],
        "summary": "Get one blog post, including its markdown body",
        "description": "Returns a single post with full metadata and its complete markdown source in `content_markdown`.",
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "description": "The post identifier, which is its filename slug — always `YYYY-MM-DD-title-slug`. Take these from listBlogPosts rather than constructing them.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}-[a-z0-9-]+$"
            },
            "example": "2026-08-05-ai-budget-overruns-forecasting-agent-spend"
          }
        ],
        "responses": {
          "200": {
            "description": "The post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPostDetail"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist. Served as an application/json Error object when the site is served by the TokenJam Node server (server/index.mjs); the static CDN deployment returns the same 404 status with the HTML/markdown 404 page instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/html",
                  "description": "The HTML 404 page, which carries a recovery map of the site."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/docs.json": {
      "get": {
        "operationId": "listDocs",
        "tags": [
          "docs"
        ],
        "summary": "List all documentation pages",
        "description": "Returns every documentation page with its section and sidebar order, so an agent can reconstruct the docs tree without scraping HTML.",
        "responses": {
          "200": {
            "description": "All documentation pages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/docs/{docId}.json": {
      "get": {
        "operationId": "getDoc",
        "tags": [
          "docs"
        ],
        "summary": "Get one documentation page, including its markdown body",
        "description": "Returns a single documentation page with its complete markdown source in `content_markdown`.",
        "parameters": [
          {
            "name": "docId",
            "in": "path",
            "required": true,
            "description": "The documentation page identifier, which is its filename slug (for example `quickstart`, `cli`, `mcp-server`). The docs index is `index`.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            },
            "example": "quickstart"
          }
        ],
        "responses": {
          "200": {
            "description": "The documentation page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocDetail"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist. Served as an application/json Error object when the site is served by the TokenJam Node server (server/index.mjs); the static CDN deployment returns the same 404 status with the HTML/markdown 404 page instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/html",
                  "description": "The HTML 404 page, which carries a recovery map of the site."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products.json": {
      "get": {
        "operationId": "listProducts",
        "tags": [
          "products"
        ],
        "summary": "List the TokenJam optimization analyzers",
        "description": "Returns the analyzer catalog — Downsize, Trim, Cache, Script, Reuse, Subagent, Lens and the rest. `has_product_page` is false for analyzers that ship in the CLI but have no dedicated marketing page yet; for those, `url` points at the closest documentation page.",
        "responses": {
          "200": {
            "description": "The analyzer catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{productSlug}.json": {
      "get": {
        "operationId": "getProduct",
        "tags": [
          "products"
        ],
        "summary": "Get one analyzer, including its mechanism and confidence tiers",
        "description": "Returns a single analyzer with the problem it addresses, how it works, its confidence tiers, CLI usage, and the research it draws on. Fields that have no written narrative yet are null.",
        "parameters": [
          {
            "name": "productSlug",
            "in": "path",
            "required": true,
            "description": "The analyzer slug, for example `downsize`, `trim`, `cache`, `script`, `reuse`, `subagent`, `lens`.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            },
            "example": "downsize"
          }
        ],
        "responses": {
          "200": {
            "description": "The analyzer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductDetail"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist. Served as an application/json Error object when the site is served by the TokenJam Node server (server/index.mjs); the static CDN deployment returns the same 404 status with the HTML/markdown 404 page instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/html",
                  "description": "The HTML 404 page, which carries a recovery map of the site."
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "tags": [
          "discovery"
        ],
        "summary": "This OpenAPI document",
        "description": "Returns the OpenAPI 3.1 description of this API. Also served at /api/openapi.json.",
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                }
              }
            }
          }
        }
      }
    },
    "/agents.md": {
      "get": {
        "operationId": "getAgentInstructions",
        "tags": [
          "discovery",
          "markdown"
        ],
        "summary": "Agent instructions: when to use TokenJam and how to call it",
        "description": "A markdown briefing written for AI agents: what TokenJam is for, which jobs it is and is not the right tool for, and the exact commands and endpoints to reach for.",
        "responses": {
          "200": {
            "description": "The agent instruction document.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/markdown",
                  "description": "Agent instructions: when to use TokenJam, the commands to run, and the machine-readable URLs on this site."
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsIndex",
        "tags": [
          "discovery",
          "markdown"
        ],
        "summary": "llms.txt index of the site",
        "description": "The llms.txt index: a short description of TokenJam plus links to every post, documentation page, and developer resource, each with its markdown URL.",
        "responses": {
          "200": {
            "description": "The llms.txt index.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/markdown",
                  "description": "llms.txt: a markdown index of every page on the site with its markdown URL."
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullText",
        "tags": [
          "discovery",
          "markdown"
        ],
        "summary": "Full-text dump of the site for LLM ingestion",
        "description": "Every published page concatenated as markdown in one response. Large — prefer llms.txt plus targeted markdown fetches when context is tight.",
        "responses": {
          "200": {
            "description": "The concatenated site text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/markdown",
                  "description": "Every published page concatenated as one markdown document."
                }
              }
            }
          }
        }
      }
    },
    "/blog/{postId}.md": {
      "get": {
        "operationId": "getBlogPostMarkdown",
        "tags": [
          "blog",
          "markdown"
        ],
        "summary": "Get a blog post as plain markdown",
        "description": "The same post as getBlogPost, but as a raw markdown document with no JSON envelope and no HTML chrome. Cheapest way to put a post into a context window.",
        "parameters": [
          {
            "name": "postId",
            "in": "path",
            "required": true,
            "description": "The post identifier, as returned by listBlogPosts.",
            "schema": {
              "type": "string"
            },
            "example": "2026-08-05-ai-budget-overruns-forecasting-agent-spend"
          }
        ],
        "responses": {
          "200": {
            "description": "The post as markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/markdown",
                  "description": "The post as a markdown document: an H1 title, the description, the publication line, then the body."
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist. Served as an application/json Error object when the site is served by the TokenJam Node server (server/index.mjs); the static CDN deployment returns the same 404 status with the HTML/markdown 404 page instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/html",
                  "description": "The HTML 404 page, which carries a recovery map of the site."
                }
              }
            }
          }
        }
      }
    },
    "/docs/{docId}.md": {
      "get": {
        "operationId": "getDocMarkdown",
        "tags": [
          "docs",
          "markdown"
        ],
        "summary": "Get a documentation page as plain markdown",
        "description": "The same page as getDoc, as a raw markdown document. The docs index is served at /docs.md rather than /docs/index.md.",
        "parameters": [
          {
            "name": "docId",
            "in": "path",
            "required": true,
            "description": "The documentation page identifier, as returned by listDocs.",
            "schema": {
              "type": "string"
            },
            "example": "quickstart"
          }
        ],
        "responses": {
          "200": {
            "description": "The page as markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/markdown",
                  "description": "The documentation page as a markdown document: an H1 title, the description, then the body."
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist. Served as an application/json Error object when the site is served by the TokenJam Node server (server/index.mjs); the static CDN deployment returns the same 404 status with the HTML/markdown 404 page instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "text/html",
                  "description": "The HTML 404 page, which carries a recovery map of the site."
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Error envelope returned for any request this API cannot satisfy.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "status"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "not_found",
                  "method_not_allowed",
                  "not_acceptable",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "status": {
                "type": "integer",
                "description": "HTTP status code, repeated for clients that only read the body."
              },
              "hint": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "What to try next — usually the discovery endpoint that lists valid identifiers."
              },
              "documentation_url": {
                "type": "string",
                "description": "Where this error is documented."
              }
            }
          }
        },
        "examples": [
          {
            "error": {
              "code": "not_found",
              "message": "No such resource: /api/v1/posts/nope.json",
              "status": 404,
              "hint": "List valid identifiers at https://tokenjam.dev/api/v1/posts.json",
              "documentation_url": "https://tokenjam.dev/api"
            }
          }
        ]
      },
      "ApiIndex": {
        "type": "object",
        "required": [
          "object",
          "name",
          "version",
          "endpoints"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "api_index"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "API version segment, e.g. \"v1\"."
          },
          "documentation_url": {
            "type": "string"
          },
          "openapi_url": {
            "type": "string"
          },
          "agent_instructions_url": {
            "type": "string"
          },
          "llms_txt_url": {
            "type": "string"
          },
          "sitemap_url": {
            "type": "string"
          },
          "authentication": {
            "type": "object",
            "description": "Auth requirements for this API.",
            "properties": {
              "required": {
                "type": "boolean"
              },
              "description": {
                "type": "string"
              }
            }
          },
          "rate_limit": {
            "type": "object",
            "properties": {
              "enforced": {
                "type": "boolean"
              },
              "description": {
                "type": "string"
              }
            }
          },
          "endpoints": {
            "type": "array",
            "description": "Every operation in this API.",
            "items": {
              "type": "object",
              "required": [
                "operation_id",
                "method",
                "path",
                "description"
              ],
              "properties": {
                "operation_id": {
                  "type": "string"
                },
                "method": {
                  "type": "string"
                },
                "path": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Author": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "BlogPostSummary": {
        "type": "object",
        "description": "A published blog post, without its body.",
        "required": [
          "object",
          "id",
          "title",
          "description",
          "url",
          "markdown_url",
          "published_at"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "blog_post"
          },
          "id": {
            "type": "string",
            "description": "Filename slug; use as `postId`."
          },
          "title": {
            "type": "string",
            "description": "Post title."
          },
          "description": {
            "type": "string",
            "description": "One-line summary."
          },
          "url": {
            "type": "string",
            "description": "Human-readable HTML page."
          },
          "markdown_url": {
            "type": "string",
            "description": "Same post as raw markdown."
          },
          "api_url": {
            "type": "string",
            "description": "This post as JSON, with its body."
          },
          "author": {
            "$ref": "#/components/schemas/Author"
          },
          "published_at": {
            "type": "string",
            "format": "date",
            "description": "Publication date."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Last substantive edit, if any."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Topic tags."
          },
          "pillar": {
            "type": [
              "string",
              "null"
            ],
            "description": "Editorial pillar the post belongs to."
          },
          "reading_time_minutes": {
            "type": "integer",
            "description": "Estimated reading time."
          },
          "cover_image_url": {
            "type": "string",
            "description": "Social/OG cover image."
          }
        }
      },
      "BlogPostDetail": {
        "type": "object",
        "description": "A published blog post, including its full markdown body.",
        "required": [
          "object",
          "id",
          "title",
          "description",
          "url",
          "markdown_url",
          "published_at",
          "content_markdown"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "blog_post"
          },
          "id": {
            "type": "string",
            "description": "Filename slug; use as `postId`."
          },
          "title": {
            "type": "string",
            "description": "Post title."
          },
          "description": {
            "type": "string",
            "description": "One-line summary."
          },
          "url": {
            "type": "string",
            "description": "Human-readable HTML page."
          },
          "markdown_url": {
            "type": "string",
            "description": "Same post as raw markdown."
          },
          "api_url": {
            "type": "string",
            "description": "This post as JSON, with its body."
          },
          "author": {
            "$ref": "#/components/schemas/Author"
          },
          "published_at": {
            "type": "string",
            "format": "date",
            "description": "Publication date."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Last substantive edit, if any."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Topic tags."
          },
          "pillar": {
            "type": [
              "string",
              "null"
            ],
            "description": "Editorial pillar the post belongs to."
          },
          "reading_time_minutes": {
            "type": "integer",
            "description": "Estimated reading time."
          },
          "cover_image_url": {
            "type": "string",
            "description": "Social/OG cover image."
          },
          "content_markdown": {
            "type": "string",
            "description": "Full markdown source of the post."
          }
        }
      },
      "DocSummary": {
        "type": "object",
        "description": "A documentation page, without its body.",
        "required": [
          "object",
          "id",
          "title",
          "description",
          "url",
          "markdown_url"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "doc"
          },
          "id": {
            "type": "string",
            "description": "Filename slug; use as `docId`."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-line summary."
          },
          "section": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sidebar section slug."
          },
          "order": {
            "type": "integer",
            "description": "Sort order within the section."
          },
          "url": {
            "type": "string",
            "description": "Human-readable HTML page."
          },
          "markdown_url": {
            "type": "string",
            "description": "Same page as raw markdown."
          },
          "api_url": {
            "type": "string",
            "description": "This page as JSON, with its body."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Last update, if recorded."
          }
        }
      },
      "DocDetail": {
        "type": "object",
        "description": "A documentation page, including its full markdown body.",
        "required": [
          "object",
          "id",
          "title",
          "description",
          "url",
          "markdown_url",
          "content_markdown"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "doc"
          },
          "id": {
            "type": "string",
            "description": "Filename slug; use as `docId`."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-line summary."
          },
          "section": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sidebar section slug."
          },
          "order": {
            "type": "integer",
            "description": "Sort order within the section."
          },
          "url": {
            "type": "string",
            "description": "Human-readable HTML page."
          },
          "markdown_url": {
            "type": "string",
            "description": "Same page as raw markdown."
          },
          "api_url": {
            "type": "string",
            "description": "This page as JSON, with its body."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Last update, if recorded."
          },
          "content_markdown": {
            "type": "string",
            "description": "Full markdown source of the page."
          }
        }
      },
      "ProductSummary": {
        "type": "object",
        "description": "A TokenJam optimization analyzer, catalog-level fields only.",
        "required": [
          "object",
          "slug",
          "name",
          "headline",
          "summary",
          "url"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "product"
          },
          "slug": {
            "type": "string",
            "description": "Analyzer slug; use as `productSlug`."
          },
          "name": {
            "type": "string",
            "description": "Analyzer name, e.g. Downsize."
          },
          "headline": {
            "type": "string",
            "description": "Headline claim."
          },
          "summary": {
            "type": "string",
            "description": "Card-length description."
          },
          "tagline": {
            "type": "string",
            "description": "Short nav-length description."
          },
          "url": {
            "type": "string",
            "description": "Product page, or the closest docs page."
          },
          "api_url": {
            "type": "string",
            "description": "This analyzer as JSON."
          },
          "has_product_page": {
            "type": "boolean",
            "description": "False when the analyzer ships in the CLI but has no dedicated page yet; `url` then points at documentation."
          },
          "listed": {
            "type": "boolean",
            "description": "Whether the analyzer appears in site navigation."
          }
        }
      },
      "ProductDetail": {
        "type": "object",
        "description": "A TokenJam optimization analyzer with its full narrative. Fields with no written narrative yet are null.",
        "required": [
          "object",
          "slug",
          "name",
          "headline",
          "summary",
          "url"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "product"
          },
          "slug": {
            "type": "string",
            "description": "Analyzer slug; use as `productSlug`."
          },
          "name": {
            "type": "string",
            "description": "Analyzer name, e.g. Downsize."
          },
          "headline": {
            "type": "string",
            "description": "Headline claim."
          },
          "summary": {
            "type": "string",
            "description": "Card-length description."
          },
          "tagline": {
            "type": "string",
            "description": "Short nav-length description."
          },
          "url": {
            "type": "string",
            "description": "Product page, or the closest docs page."
          },
          "api_url": {
            "type": "string",
            "description": "This analyzer as JSON."
          },
          "has_product_page": {
            "type": "boolean",
            "description": "False when the analyzer ships in the CLI but has no dedicated page yet; `url` then points at documentation."
          },
          "listed": {
            "type": "boolean",
            "description": "Whether the analyzer appears in site navigation."
          },
          "telemetry_needs": {
            "type": [
              "string",
              "null"
            ],
            "description": "What telemetry the analyzer reads."
          },
          "problem": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Paragraphs describing the problem it addresses."
          },
          "mechanism": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Paragraphs describing how it works."
          },
          "privacy_note": {
            "type": [
              "string",
              "null"
            ],
            "description": "What leaves the machine, if anything."
          },
          "confidence_levels": {
            "type": [
              "array",
              "null"
            ],
            "description": "Confidence tiers for the analyzer findings.",
            "items": {
              "type": "object",
              "properties": {
                "level": {
                  "type": "integer",
                  "enum": [
                    1,
                    2,
                    3
                  ],
                  "description": "Tier number."
                },
                "name": {
                  "type": "string",
                  "description": "Tier name, e.g. Replay-validated."
                },
                "tier": {
                  "type": "string",
                  "enum": [
                    "OSS",
                    "Pro"
                  ],
                  "description": "Which edition provides it."
                },
                "body": {
                  "type": "string",
                  "description": "What the tier means."
                }
              }
            }
          },
          "usage": {
            "type": [
              "array",
              "null"
            ],
            "description": "How to invoke the analyzer.",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "description": "Surface, e.g. CLI or MCP."
                },
                "detail": {
                  "type": "string",
                  "description": "The command or tool name."
                },
                "note": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Caveat, if any."
                }
              }
            }
          },
          "research": {
            "type": [
              "array",
              "null"
            ],
            "description": "Papers the technique draws on.",
            "items": {
              "type": "object",
              "properties": {
                "paper": {
                  "type": "string",
                  "description": "Paper title."
                },
                "attribution": {
                  "type": "string",
                  "description": "Authors, venue, year."
                },
                "contribution": {
                  "type": "string",
                  "description": "What TokenJam uses from it."
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Link to the paper."
                }
              }
            }
          }
        }
      },
      "OpenApiDocument": {
        "type": "object",
        "description": "An OpenAPI 3.1 document — this specification.",
        "required": [
          "openapi",
          "info",
          "paths"
        ],
        "properties": {
          "openapi": {
            "type": "string",
            "description": "Specification version, e.g. \"3.1.0\"."
          },
          "info": {
            "type": "object",
            "description": "Title, version, description, and contact."
          },
          "servers": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Base URLs."
          },
          "paths": {
            "type": "object",
            "description": "Operations, keyed by path."
          },
          "components": {
            "type": "object",
            "description": "Reusable schemas."
          }
        }
      },
      "BlogPostList": {
        "type": "object",
        "required": [
          "object",
          "resource",
          "count",
          "data"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always \"list\" for collection responses."
          },
          "resource": {
            "type": "string",
            "const": "blog_post",
            "description": "The kind of item in `data`."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlogPostSummary"
            }
          }
        }
      },
      "DocList": {
        "type": "object",
        "required": [
          "object",
          "resource",
          "count",
          "data"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always \"list\" for collection responses."
          },
          "resource": {
            "type": "string",
            "const": "doc",
            "description": "The kind of item in `data`."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocSummary"
            }
          }
        }
      },
      "ProductList": {
        "type": "object",
        "required": [
          "object",
          "resource",
          "count",
          "data"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always \"list\" for collection responses."
          },
          "resource": {
            "type": "string",
            "const": "product",
            "description": "The kind of item in `data`."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductSummary"
            }
          }
        }
      }
    }
  },
  "x-api-lifecycle": {
    "current_version": "v1",
    "versioning_scheme": "URL path segment, e.g. /api/v1/posts.json",
    "status": "stable",
    "policy_url": "https://tokenjam.dev/api#lifecycle",
    "notice_period_days": 90,
    "breaking_change_policy": "Breaking changes ship as a new version segment (/api/v2/), never in place. Within a version, fields may be added but existing fields are not removed, renamed, or retyped.",
    "deprecation_signals": [
      {
        "signal": "Deprecation header",
        "spec": "RFC 9745",
        "description": "Set on every response from a deprecated endpoint, carrying the date the deprecation was announced."
      },
      {
        "signal": "Sunset header",
        "spec": "RFC 8594",
        "description": "Set alongside Deprecation, carrying the date the endpoint stops responding."
      },
      {
        "signal": "deprecated: true in the OpenAPI document",
        "spec": "OpenAPI 3.1",
        "description": "Marked on the operation as soon as the deprecation is announced."
      },
      {
        "signal": "A note on the API page and in the changelog",
        "spec": null,
        "description": "Written explanation of what replaces the endpoint."
      }
    ],
    "guarantee": "A deprecated endpoint keeps responding for at least 90 days after the Deprecation header first appears. No endpoint is removed without that notice."
  },
  "x-support": {
    "email": "support@tokenjam.dev",
    "issues": "https://github.com/metabuilder-labs/tokenjam/issues"
  }
}
