{"openapi":"3.1.0","info":{"title":"Markdown Graphs API","summary":"Framed graphs an agent can drop next to prose. JSX in MDX, official ASCII in a README.","description":"Public read API for Markdown Graphs. Version 1 is URL-prefixed at /api/v1/. Breaking changes ship as /api/v2/ with at least six months notice. Deprecation policy: https://mdx-graphs.kshv.me/developers/deprecation. Rate limit: 1000 GET requests per hour per client; see RateLimit-* response headers. No authentication. Graph source files are copied with the shadcn CLI; this API does not install them.","version":"1.0.0","license":{"name":"MIT","url":"https://github.com/keshav-exe/markdown-graphs/blob/main/LICENSE"},"contact":{"name":"Keshav Bagaade","email":"hi@kshv.me","url":"https://mdx-graphs.kshv.me"},"x-api-version":"1","x-deprecation-policy":"https://mdx-graphs.kshv.me/developers/deprecation"},"servers":[{"url":"https://mdx-graphs.kshv.me","description":"Production"}],"tags":[{"name":"meta","description":"Health and API index."},{"name":"catalog","description":"Graph list and one graph."},{"name":"machine","description":"Skill, chooser, registry, OpenAPI."}],"paths":{"/api/v1":{"get":{"operationId":"getApiIndex","tags":["meta"],"summary":"API index","description":"Lists every public GET endpoint with operationId values for function calling.","responses":{"200":{"description":"API index.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiIndex"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/health":{"get":{"operationId":"getHealth","tags":["meta"],"summary":"Health check","description":"Returns ok when the Markdown Graphs API is reachable.","responses":{"200":{"description":"Healthy.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/components":{"get":{"operationId":"listComponents","tags":["catalog"],"summary":"List every graph","description":"Returns the catalog: slug, export name, docs URL, and when/not hints for agents picking a figure.","responses":{"200":{"description":"Catalog.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentList"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/components/{slug}":{"get":{"operationId":"getComponent","tags":["catalog"],"summary":"Get one graph","description":"One catalog row plus props. 404 if the slug is not a graph.","parameters":[{"name":"slug","in":"path","required":true,"description":"Registry slug, like graph-table.","schema":{"type":"string","enum":["graph-table","graph-sheet","graph-flow","graph-bars","graph-rank","graph-cells","graph-meter","graph-spark","graph-tree","graph-timeline","graph-check","graph-stack","graph-funnel","graph-gantt","graph-plot","graph-waffle","graph-diff","graph-invoice","graph-compare","graph-matrix","graph-stat","graph-kpi","graph-spec","graph-activity","graph-heatmap","graph-calendar","graph-waterfall","graph-uptime","graph-slope","graph-bullet","graph-timer","graph-countdown","graph-frame"]}}],"responses":{"200":{"description":"One graph.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentDetail"}}}},"404":{"description":"Unknown slug.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/llms.txt":{"get":{"operationId":"getLlmsTxt","tags":["machine"],"summary":"Chooser and ASCII twins","description":"When-to-use, host rules, chooser table, official fenced twins, and recipes. Fetch this if the skill is not installed.","responses":{"200":{"description":"Markdown.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"text/markdown":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}},"text/plain":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/agents.md":{"get":{"operationId":"getAgentsMd","tags":["machine"],"summary":"Agents page as markdown","description":"Same content as /agents in markdown for agents that prefer a .md URL.","responses":{"200":{"description":"Markdown.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"text/markdown":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}},"text/plain":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/skill.md":{"get":{"operationId":"getSkill","tags":["machine"],"summary":"SKILL.md","description":"The Agent Skill file. Copy it into .cursor/skills, .claude/skills, .agents/skills, or .opencode/skills.","responses":{"200":{"description":"The skill.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"text/markdown":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}},"text/plain":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/skill/recipes.md":{"get":{"operationId":"getSkillRecipes","tags":["machine"],"summary":"Skill recipes","description":"Worked JSX for the skill to copy.","responses":{"200":{"description":"Recipes.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"text/markdown":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}},"text/plain":{"schema":{"$ref":"#/components/schemas/MarkdownDocument"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/r/{name}.json":{"get":{"operationId":"getRegistryItem","tags":["machine"],"summary":"shadcn registry item","description":"JSON the shadcn CLI copies into the project. name is a graph slug or all.","parameters":[{"name":"name","in":"path","required":true,"description":"graph-table, all, or another registry name.","schema":{"type":"string"}}],"responses":{"200":{"description":"Registry item.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItem"}}}},"404":{"description":"Unknown registry name.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/openapi.json":{"get":{"operationId":"getOpenApi","tags":["machine"],"summary":"This OpenAPI document","description":"OpenAPI 3.1 for the public read surface.","responses":{"200":{"description":"OpenAPI 3.1.","headers":{"RateLimit-Policy":{"description":"Quota policy: limit;w=window seconds.","schema":{"type":"string","example":"1000;w=3600"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer","example":1000}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"}}}},"429":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"description":"Seconds until the client may retry.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed in the current window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"Problem":{"type":"object","required":["type","title","status","detail","code"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"},"code":{"type":"string"},"hrefs":{"type":"object","additionalProperties":{"type":"string","format":"uri"}}}},"Prop":{"type":"object","required":["name","type","description"],"properties":{"name":{"type":"string"},"type":{"type":"string"},"default":{"type":"string"},"description":{"type":"string"}}},"Component":{"type":"object","required":["slug","name","title","description","registry","docs"],"properties":{"slug":{"type":"string","example":"graph-table"},"name":{"type":"string","example":"GraphTable"},"title":{"type":"string","example":"Table"},"description":{"type":"string"},"registry":{"type":"string"},"docs":{"type":"string","format":"uri"},"when":{"type":"string"},"not":{"type":"string"}}},"ComponentDetail":{"allOf":[{"$ref":"#/components/schemas/Component"},{"type":"object","required":["dependencies","props"],"properties":{"dependencies":{"type":"array","items":{"type":"string"}},"props":{"type":"array","items":{"$ref":"#/components/schemas/Prop"}}}}]},"ComponentList":{"type":"object","required":["components"],"properties":{"components":{"type":"array","items":{"$ref":"#/components/schemas/Component"}}}},"ApiIndex":{"type":"object","required":["version","name","description","endpoints"],"properties":{"version":{"type":"string","example":"1.0.0"},"name":{"type":"string","example":"Markdown Graphs API"},"description":{"type":"string"},"deprecation":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"},"endpoints":{"type":"array","items":{"type":"object","required":["method","path","summary"],"properties":{"method":{"type":"string","enum":["GET"]},"path":{"type":"string"},"summary":{"type":"string"},"operationId":{"type":"string"}}}}}},"Health":{"type":"object","required":["ok","service","version","url"],"properties":{"ok":{"type":"boolean","example":true},"service":{"type":"string","example":"Markdown Graphs"},"version":{"type":"string","example":"1.0.0"},"url":{"type":"string","format":"uri"}}},"RegistryItem":{"type":"object","required":["name","type","files"],"properties":{"name":{"type":"string"},"type":{"type":"string","example":"registry:component"},"title":{"type":"string"},"description":{"type":"string"},"files":{"type":"array","items":{"type":"object","required":["path","content"],"properties":{"path":{"type":"string"},"type":{"type":"string"},"content":{"type":"string"}}}}}},"MarkdownDocument":{"type":"string","description":"UTF-8 markdown body."},"OpenApiDocument":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"type":"string","example":"3.1.0"},"info":{"type":"object"},"paths":{"type":"object"},"components":{"type":"object"}}}}}}