# API reference > This page is generated from https://kistdata.com/openapi.json, the hand-written OpenAPI 3.1 document. If this page and that document ever disagree, the document is closer to the source and this page has a bug. A demo surface with the real schema and demo numbers. It is not the Grapeworks warehouse opened up. Every byte these two endpoints return comes from static JSON checked into the website repository at build time, for `lochend-wild`, a fabricated demo tenant that is not a real business. There is no warehouse connection behind them, no gold view is read, no credential is used and no network call is made while a request is served. No figure returned here is a client result or a live measurement, and none of it should be quoted as one. Because of that, every response body on every path, success and error alike, carries `demo: true` and `data_source: "demo_fixture"`, together with the tenant and a plain-English notice. The same statement is repeated in an `x-grapeworks-data-source: demo_fixture` response header for callers that only read headers. These two endpoints are the whole public surface. No public endpoint returns live client data and there will not be one. The internal warehouse MCP server is stdio-only, has no network listener, and is not callable from the internet by any route. This document is hand-written and describes exactly the two endpoints below. It describes nothing planned and nothing internal. ## Endpoints (2) ### `GET /api/demo/catalog` What is askable on the demo surface Returns the metrics this demo surface will answer questions about: metric ids, their dimensions, their grain, the named windows they accept and the value fields they return. Read this before calling `/api/demo/query`. Demo-data caveat: the vocabulary is the real Grapeworks catalogue vocabulary, and the numbers reachable through it are fabricated demo-tenant fixtures. Nothing here reads a warehouse. The response carries `demo: true` and `data_source: "demo_fixture"`. Unknown parameters are rejected rather than ignored, and every rejection names the offending parameter and the accepted set. Parameters: - `metric` (query, optional): MetricId Responses: 200, 400, 429, 500. ### `OPTIONS /api/demo/catalog` CORS preflight Returns 204 with `Allow: GET, OPTIONS`. No body. Parameters: none. Responses: 204. ### `POST /api/demo/catalog` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `PUT /api/demo/catalog` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `PATCH /api/demo/catalog` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `DELETE /api/demo/catalog` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `GET /api/demo/query` A structured, schema-correct answer with provenance Returns rows for one metric, optionally grouped by one of its dimensions, over one of its named windows, with a provenance block. Demo-data caveat: every row is fabricated data for the demo tenant `lochend-wild`, served from static JSON vendored into the website repository. No warehouse query is executed, no gold view is read and no credential is used. `provenance.goldViews` is therefore always an empty array, and the response carries `demo: true` and `data_source: "demo_fixture"`. These numbers are not a client result. Arbitrary date ranges are not supported. Use one of the named windows the catalogue lists for the metric. There is no tenant selector: this surface serves exactly one fabricated tenant and rejects any attempt to point it elsewhere. Parameters: - `metric` (query, required): MetricId - `dimension` (query, optional): campaign_id | publisher_platform | platform_position | channel - `window` (query, optional): last_7_days | last_28_days | last_3_months | last_12_months - `limit` (query, optional): integer Responses: 200, 400, 429, 500. ### `OPTIONS /api/demo/query` CORS preflight Returns 204 with `Allow: GET, OPTIONS`. No body. Parameters: none. Responses: 204. ### `POST /api/demo/query` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `PUT /api/demo/query` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `PATCH /api/demo/query` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ### `DELETE /api/demo/query` Not allowed This surface is read-only. Any write method returns 405 with the standard error envelope, which still carries `demo: true` and `data_source: "demo_fixture"`. Parameters: none. Responses: 405. ## How to verify any of this - Raw OpenAPI document: https://kistdata.com/openapi.json - Machine-readable capability descriptor: https://kistdata.com/.well-known/grapeworks-capabilities.json - Instructions for an evaluating agent: https://kistdata.com/ai-instructions - Facts and statuses, with sourcing per row: https://kistdata.com/agents