{"openapi":"3.1.0","info":{"title":"Tiny Solutions public API","version":"1.0.0","summary":"Search and read the public docs and New York Early Intervention terms of Tiny Solutions, the New York Early Intervention agency system.","description":"The public API needs no key. An agency's records are not here: outside apps read them through the read-only MCP server.\n\nVersioning: the version is in the path, `/api/v1`. A breaking change ships as a new version, such as `v2`, at a new path, and `/api/v1` keeps its contract. Before a version is retired, its responses carry `Deprecation` and `Sunset` headers (RFC 9745, RFC 8594) for at least 90 days.\n\nRate limits: 60 requests a minute from one IP address, counted by each server instance. Every response carries the IETF `RateLimit-Policy` and `RateLimit` fields. Past the limit the answer is 429 with `Retry-After`.\n\nEvery page is also readable as Markdown; https://tinysolutions.app/llms.txt lists them.","contact":{"name":"Tiny Solutions","email":"hello@tinysolutions.app","url":"https://tinysolutions.app/contact"}},"externalDocs":{"description":"Tiny Solutions for outside apps","url":"https://tinysolutions.app/docs/developers/outside-apps"},"servers":[{"url":"https://tinysolutions.app"}],"tags":[{"name":"docs","description":"Public documentation."},{"name":"status","description":"Service health."},{"name":"records","description":"One agency's records, read-only."}],"paths":{"/api/v1/search":{"get":{"operationId":"searchDocs","tags":["docs"],"summary":"Search the documentation","description":"Full-text search over the product, Early Intervention, and developer docs. Returns pages, headings, and passages that match, best first. Read a match with getDocsPage.","parameters":[{"name":"query","in":"query","required":true,"description":"The words to search for, such as `referral`.","schema":{"type":"string","minLength":1,"examples":["referral"]}}],"responses":{"200":{"description":"The matches, best first. Empty when nothing matches.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}}}}},"400":{"description":"`query` is missing or empty (`missing_query`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/v1/docs":{"get":{"operationId":"getDocsPage","tags":["docs"],"summary":"Read a docs page","description":"One product or developer docs page, with its body as Markdown. Leave `page` out for the docs home.","parameters":[{"name":"page","in":"query","required":false,"description":"The page's path after `/docs/`, such as `children/referrals`. A search match's `url` gives it.","schema":{"type":"string","pattern":"^[a-z0-9-]+(/[a-z0-9-]+)*$","examples":["children/referrals","developers/outside-apps"]}}],"responses":{"200":{"description":"The page.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocsPage"}}}},"404":{"description":"No published page has this path (`unknown_document`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/v1/terms":{"get":{"operationId":"listTerms","tags":["docs"],"summary":"List the Early Intervention terms","description":"Every New York State Early Intervention term Tiny Solutions explains, with a one-paragraph summary. Read one in full with getTerm.","responses":{"200":{"description":"The terms.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TermSummary"}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/v1/terms/{slug}":{"get":{"operationId":"getTerm","tags":["docs"],"summary":"Read an Early Intervention term","description":"One New York State Early Intervention term: what it means, how it works, and its sources.","parameters":[{"name":"slug","in":"path","required":true,"description":"The term's slug, from listTerms.","schema":{"type":"string","enum":["referral","multidisciplinary-evaluation","eligibility","ifsp","service-authorization","session-note","service-log","transition","forty-five-day-clock","hipaa"]}}],"responses":{"200":{"description":"The term.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Term"}}}},"404":{"description":"No term has this slug (`unknown_document`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/v1/health":{"get":{"operationId":"getHealth","tags":["status"],"summary":"Check service health","description":"Says whether the web app is up and which commit it serves.","responses":{"200":{"description":"The web app is up.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/mcp/readonly":{"servers":[{"url":"https://colorless-mosquito-42.convex.site"}],"post":{"operationId":"callMcpServer","tags":["records"],"summary":"Call the read-only MCP server","description":"The read-only MCP server, over the streamable HTTP transport. Send one request: initialize, ping, tools/list, or tools/call. Tools read only what the signed-in staff member can open in one agency, and each call is audited. Most clients connect through an MCP client instead of calling this directly.","security":[{"tinyOAuth":["tiny:read"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"}}}},"responses":{"200":{"description":"The answer to the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"401":{"description":"No valid access token. `WWW-Authenticate` names the protected resource metadata (RFC 9728).","headers":{"WWW-Authenticate":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}}},"components":{"securitySchemes":{"tinyOAuth":{"type":"oauth2","description":"OAuth 2.1 authorization code with PKCE (S256). Clients can register themselves (RFC 7591); the authorization server's metadata is at the address the 401's `WWW-Authenticate` header names.","flows":{"authorizationCode":{"authorizationUrl":"https://tinysolutions.app/api/auth/oauth2/authorize","tokenUrl":"https://tinysolutions.app/api/auth/oauth2/token","refreshUrl":"https://tinysolutions.app/api/auth/oauth2/token","scopes":{"tiny:read":"Read the Child records the signed-in staff member can open, in the one agency they pick at consent."}}}}},"headers":{"RateLimit":{"description":"The client's remaining quota (IETF RateLimit header fields), such as `\"default\";r=59;t=42`.","schema":{"type":"string"}},"RateLimitPolicy":{"description":"The quota policy (IETF RateLimit header fields): `\"default\";q=60;w=60` is 60 requests in 60 seconds.","schema":{"type":"string"}}},"responses":{"TooManyRequests":{"description":"The client passed the rate limit (`rate_limited`). Wait `Retry-After` seconds.","headers":{"Retry-After":{"description":"Seconds to wait before the next request.","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"schemas":{"SearchResult":{"type":"object","required":["id","type","content","url"],"properties":{"id":{"type":"string","description":"The match's id."},"type":{"type":"string","enum":["page","heading","text"],"description":"Whether the match is a page title, a heading, or a passage."},"content":{"type":"string","description":"The matching text. Matched words are wrapped in `<mark>`."},"breadcrumbs":{"type":"array","items":{"type":"string"},"description":"The sections above the page."},"url":{"type":"string","description":"The page's path, with a heading's fragment."}}},"DocsPage":{"type":"object","required":["url","title","description","markdown"],"properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"description":{"type":["string","null"]},"markdown":{"type":"string","description":"The page's body as Markdown."}}},"TermSummary":{"type":"object","required":["slug","title","question","summary","url","markdownUrl"],"properties":{"slug":{"type":"string"},"title":{"type":"string"},"question":{"type":"string","description":"The question the term's page answers."},"summary":{"type":"string"},"url":{"type":"string","format":"uri"},"markdownUrl":{"type":"string","format":"uri"}}},"Term":{"type":"object","required":["slug","title","question","kind","summary","paragraphs","citations","seeAlso","url","markdownUrl"],"properties":{"slug":{"type":"string"},"title":{"type":"string"},"question":{"type":"string"},"kind":{"type":"string","enum":["glossary","lifecycle","compliance"]},"summary":{"type":"string"},"paragraphs":{"type":"array","items":{"type":"string"}},"citations":{"type":"array","items":{"type":"object","required":["label","href"],"properties":{"label":{"type":"string"},"href":{"type":["string","null"],"format":"uri"}}}},"seeAlso":{"type":"array","items":{"type":"string"},"description":"Slugs of related terms."},"url":{"type":"string","format":"uri"},"markdownUrl":{"type":"string","format":"uri"}}},"Health":{"type":"object","required":["status","commit","checkedAt"],"properties":{"status":{"type":"string","enum":["ok"]},"commit":{"type":["string","null"],"description":"The git commit the app was built from."},"checkedAt":{"type":"string","format":"date-time"}}},"Problem":{"type":"object","required":["type","title","status","detail","code","hint"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"},"code":{"type":"string","enum":["not_found","unauthenticated","missing_query","unknown_document","rate_limited"]},"hint":{"type":"string"}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["string","integer","null"]},"method":{"type":"string","enum":["initialize","ping","tools/list","tools/call"]},"params":{"type":"object"}}},"JsonRpcResponse":{"type":"object","required":["jsonrpc","id"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["string","integer","null"]},"result":{"type":"object"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer"},"message":{"type":"string"}}}}}}}}