Appearance
Data sources
Data sources and connections, and the data and parameters a template reads.
POST /v1/templates/{id}/data
The data a preview would use, by the render policy (for the designer).
Runs the data plan without rendering: live datasets where the caller may use live data (data: live for drafts), else the sources' samples. Datasets that use the document's own samples are left out. Agents, MCP tools and read-only callers get samples; data: live where that isn't allowed is 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
environment | string | ||
draft | boolean | ||
commit | string | ||
params | object | ||
context | object | ||
data | auto, sample, live |
Responses
| Status | Description | Body |
|---|---|---|
200 | {datasets: {name: JSON}, origins: {name: {kind, source, bytes, reason}}} | |
403 | Live data was asked for where it isn't allowed | |
404 | The template is in the trash: {error: "in-trash", message, item}. item, the trash item's id, is there only for callers with template.read. | object |
409 | A source's connection has no binding for the environment | |
413 | A source passed its cap | |
422 | The parameters or sourceParams have errors | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
502 | A data source failed |
GET /v1/sources
The source catalogue of one environment (RFML §10.4), without queries.
Each source's latest version: name, description, kind (sql or http), connection, typed params, the output schema and whether it has a sample, every version, and bound (its connection has a binding in this environment). Needs source.read. Queries are never listed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | {environment, sources: [{name, version, versions, description, kind, connection, params, schema, hasSample, bound}]} | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
503 | No source catalogue (sourceControl.driver is not git) |
POST /v1/sources
Add a source version (source.manage).
Writes sources/<name>/<version>/{source.json,schema.json,sample.json} on the environment branch. Versions are immutable: an existing one is 409. The connection must exist and be of the definition's kind. With describe: true the query is run once (needs data.live) to fill in the schema and, when none is given, the sample. Agents can't define sources.
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
environment | string | ||
definition | SourceDefinition | yes | |
schema | object | ||
sample | any | ||
describe | boolean | ||
params | object | Parameter values for describe. |
Responses
| Status | Description | Body |
|---|---|---|
201 | The stored version, with its query | |
409 | The version exists, or the branch moved | |
422 | The definition is not valid | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
GET /v1/sources/{name}
One source version (the latest, or ?version=) with its schema and sample.
The query is included only for callers with source.manage, and never through MCP tools.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | A dotted source name, e.g. billing.bill |
environment | query | string | ||
version | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | ||
404 | No such source or version in the environment | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
GET /v1/sources/{name}/versions
Every version of a source in one environment, oldest first.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | A dotted source name, e.g. billing.bill |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | {name, environment, versions: [{version, description, tree, hasSample}]} | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
POST /v1/sources/{name}/describe
Run a source once and describe its result.
Runs a stored version, or an unsaved definition, through the environment's connection and returns a JSON Schema, the SQL columns and up to 20 rows. It reads live data: it needs source.manage and data.live, and agents and MCP tools can't.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | A dotted source name, e.g. billing.bill |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
environment | string | ||
version | string | ||
definition | SourceDefinition | ||
params | object |
Responses
| Status | Description | Body |
|---|---|---|
200 | {schema, columns: [{name, databaseType, type, nullable}], sample} | |
403 | No source.manage or data.live, or an agent | |
409 | The connection has no binding for the environment | |
413 | The result passed the connection's row or byte cap | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
502 | The source failed; the message names no connection details |
POST /v1/sources/{name}/promote
Copy one source version from one environment to another.
Needs source.read in from and source.manage in to. Copying a version the target holds unchanged does nothing; one that differs is 409.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | A dotted source name, e.g. billing.bill |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
version | string | The version; empty for the latest. | |
from | string | ||
to | string | Defaults to the environment after from. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The version in the target environment, with bound | |
409 | The target holds a different copy of the version | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
GET /v1/connections
The operator's connections and their health, never their secrets.
Per environment the caller has source.read in: status unbound (no binding), unchecked, ok or error. check=true pings each binding; messages name no hosts, users or driver errors.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
environment | query | string | ||
check | query | boolean |
Responses
| Status | Description | Body |
|---|---|---|
200 | {connections: [{name, driver, kind, maxRows, maxBytes, timeoutSec, environments: [{environment, status, message, latencyMs}]}]} | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
GET /v1/templates/{id}/params
The template's parameters as prompts, with picklist choices.
Every declared parameter in order, with its bound value and its options. Computed options that read datasets are evaluated against data loaded by the render policy (samples for agents, MCP tools, read-only callers and drafts; live where the caller has data.live). X-Data-Origins says where each loaded dataset came from.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
environment | query | string | ||
draft | query | boolean | Read the draft (or the published copy when no draft is written yet). | |
commit | query | string | ||
values | query | string | Parameter values chosen so far, as a JSON object (for cascading picklists). | |
data | query | auto, sample, live |
Responses
| Status | Description | Body |
|---|---|---|
200 | {id, environment, commit, draft, params: [{name, type, label, description, required, multiple, hidden, value, options: [{value, label}], optionsData}], values, data, diagnostics} | |
403 | Live data was asked for without data.live | |
404 | The template is in the trash: {error: "in-trash", message, item}. item, the trash item's id, is there only for callers with template.read. | object |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |