{"openapi":"3.1.0","info":{"title":"AnalyzeData public API","version":"2.0.0","summary":"Public, unauthenticated reads: service health, aggregate product usage, and published reports.","description":"AnalyzeData is an AI data analyst: a person uploads a spreadsheet, asks a question in plain English, and the engine answers by writing and executing Python over the data, then composes a shareable report.\n\nThe endpoints below are the parts of that system open to any client without credentials. Analysis itself runs from the workspace UI at /dashboard and is not exposed as a public API; there is no API key to request today.\n\nEvery HTML page on this site also serves a Markdown representation to `Accept: text/markdown` (acceptmarkdown.com), which is usually the cheapest way for an agent to read the content.\n\n**Rate limits:** public reads are limited per IP (default 600 requests/hour, hourly sliding window). Every response carries RateLimit-Limit / RateLimit-Remaining headers; exceeding the limit returns 429 with a problem+json body.\n\n**Versioning & deprecation:** the current version is v2, carried in the URL path. Breaking changes only ever ship under a new path prefix; a deprecated version keeps working for at least 90 days and announces retirement with Deprecation and Sunset headers before removal.\n\n**Errors:** all error responses are JSON problem details (RFC 9457): { type, title, status, detail }.","contact":{"name":"AnalyzeData support","email":"contact@analyzedata.io","url":"https://analyzedata.io/contact"},"license":{"name":"Proprietary","url":"https://analyzedata.io/terms"}},"servers":[{"url":"https://analyzedata.io","description":"Production"}],"paths":{"/api/v2/health":{"get":{"operationId":"getHealth","summary":"Service health and daily usage counters","description":"Reports whether the engine and its durable store are configured and reachable, today's analysis count against the global daily cap, and per-day history for analyses, reports, and engine token usage.","parameters":[{"name":"days","in":"query","required":false,"description":"Days of history to include (1-400, default 30).","schema":{"type":"integer","minimum":1,"maximum":400,"default":30}}],"responses":{"200":{"description":"Current status and counters.","content":{"application/json":{"schema":{"type":"object","properties":{"analyzeToday":{"type":"object","properties":{"used":{"type":"integer"},"cap":{"type":"integer"}}},"reportsToday":{"type":"integer"},"history":{"type":"object","description":"Named series, each an array of { date, count }.","additionalProperties":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"count":{"type":"integer"}}}}},"env":{"type":"string"},"storagePersistent":{"type":"boolean"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v2/insights":{"get":{"operationId":"getInsights","summary":"Aggregate, anonymous product-usage distributions","description":"What the product gets used for, as counts of anonymous actions: dataset size and shape bands, question intent categories, outcome and error kinds, acquisition-source categories, and the chart and block types the engine produced. There is no per-user record behind this — no datasets, column names, or question text are recorded anywhere, so nothing here can identify anyone even in principle.","parameters":[{"name":"days","in":"query","required":false,"description":"Window in days (1-400, default 30).","schema":{"type":"integer","minimum":1,"maximum":400,"default":30}}],"responses":{"200":{"description":"Distributions over the window.","content":{"application/json":{"schema":{"type":"object","properties":{"windowDays":{"type":"integer"},"note":{"type":"string"}},"additionalProperties":{"type":"object","properties":{"total":{"type":"integer"},"buckets":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v2/reports/{slug}":{"get":{"operationId":"getReport","summary":"Fetch a published report by its share slug","description":"Returns the blocks, theme, and dataset metadata of a report someone published. The slug is the capability: it is unguessable, never listed, and excluded from search indexes, so possession of the link is what grants access. Reports can be deleted by their creator and expire automatically.","parameters":[{"name":"slug","in":"path","required":true,"description":"The report share slug, as it appears in /r/{slug}.","schema":{"type":"string"}}],"responses":{"200":{"description":"The report.","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"schemas":{"Problem":{"type":"object","description":"RFC 9457 problem details — the shape of every error this API returns.","properties":{"type":{"type":"string","format":"uri","description":"URI identifying the problem class."},"title":{"type":"string","description":"Short human-readable summary."},"status":{"type":"integer","description":"HTTP status code."},"detail":{"type":"string","description":"Explanation specific to this occurrence."}},"required":["title","status"]}},"responses":{"NotFound":{"description":"The resource does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"RateLimited":{"description":"Read limit exceeded (default 600/hour per IP). Retry after the window; RateLimit-* headers say where you stand.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}