Skip to content

Agent tools

Every tool SCMotif offers an agent you have connected, with the description and inputs the agent itself reads. You do not call these yourself: your agent chooses them from what you ask.

Tools that read

Every connection is shown these.

List saved objects

list

List objects of one kind: the projects you may reach, each with a summary (oldest first; start here, a workspace grant has no implicit project), or one project's data sources, workflows, scenarios, executions or dashboards. Rows carry the ids other tools take and a url for a person. Scenarios and executions answer a page of items with total, limit and offset: scenarios oldest first, executions newest first with status, timings and finding counts per severity; the other kinds answer the whole list. Scenarios narrow by execution_id, workflow_id or name_contains, and include_profile adds each row's horizon, currency and row counts; executions narrow by workflow_id, status and since. Data sources, named sets of files, come with their latest file and unfinishedUploads, names unread uploads hold; dashboards narrow by workflow_id to those showing its results and carry tileHealth, tiles that stopped drawing.

Input Type Required Meaning
kind project or data_source or workflow or scenario or execution or dashboard yes Which kind of object this call is about.
include_counts boolean no Applies to kind project. Default: False.
content tabular or document no Narrow data sources to 'tabular' or 'document'; omit for all. Applies to kind data_source.
project_id string (uuid) no The project this call acts in. Required for every kind but kind project.
execution_id string (uuid) no Narrow to the scenarios one run published. Applies to kind scenario.
include_history boolean no Include retained historical versions alongside current scenarios. Applies to kind scenario. Default: False.
include_profile boolean no Also answer each row's horizon, currency and row counts. One scenario's are in get (kind scenario). Applies to kind scenario. Default: False.
limit integer no Page size. Applies to kinds scenario, execution. At most 25 for kind scenario; at most 500 for kind execution. Default: 25.
name_contains string or null no Narrow to names containing this text, ignoring case. Applies to kind scenario.
offset integer no Rows to skip; the next page starts at offset plus the last page's row count. Applies to kinds scenario, execution. Default: 0.
workflow_id string (uuid) or null no Narrow to one workflow: the scenarios its runs produced, its own runs, or the dashboards showing its results. Applies to kinds scenario, execution, dashboard.
since string (date-time) or null no Executions started at or after this moment, ISO 8601. Applies to kind execution.
status pending or running or completed or failed or cancelled or null no Executions in this state. Applies to kind execution.

Get saved object

get

Get one object by kind and id. project: name, brief (description, briefVersion) and counts. data_source: latest file's kind, columns, row count and sha256, never rows. workflow: nodes, edges with named ports, diagnostics and the version apply_workflow takes as baseVersion. scenario: labels, units, horizon, producing run, availableTables and provenance; for a number, inspect_scenario then query_scenario. execution: status, waiting.explanation while pending, phase while running, what it published with each url, dashboardRefresh, the failing node, firstFinding and findingCounts, and storage; list_execution_diagnostics has the rest. dashboard: selection, link, tile ids and resultSources (versions shown, their runs, newer available); include_health resolves each tile (hasData, needsRebuild, invalidReason) and names commentaryNeedsReview; do that before handing over the link. upload_session: progress, ready with the new dataSourceId, or ingestion's diagnostics.

Input Type Required Meaning
kind project or data_source or workflow or scenario or execution or dashboard or upload_session yes Which kind of object this call is about.
id string (uuid) yes The object's id, as list or the call that created it answered it.
project_id string (uuid) no The project this call acts in. Required for every kind but kind project.
include_table_counts boolean no Include tableRowCounts for browsing stored tables. Omitted by default to keep the identity summary compact. Applies to kind scenario. Default: False.
include_provenance boolean no Also answer workflowSnapshot and reproductionManifest. Both are fixed at acceptance, so ask once, not on every poll. Applies to kind execution. Default: False.
include_health boolean no Resolve every tile and report whether it answered, as hasData, needsRebuild and invalidReason beside the stored tile. Off by default because resolving runs each tile's query; on, it is the only way to learn that a tile draws nothing. It reports — it never returns the rows themselves. Applies to kind dashboard. Default: False.

Check analysis readiness

check_analysis_readiness

Readiness check for one saved scenario, selected analysis and configuration, without starting a run. ready means declared requirements passed (warnings may still need review); not_ready means fix the returned errors first; unknown means the installed analysis declares neither required tables nor a readiness check. An uninstalled analysis type is refused with the installed node types. Required tables are checked for nonempty presence, then the analysis package can return deeper pre-run findings about fields and configuration. Use it before spending solver time, not as a substitute for validate_workflow, which checks a stored graph.

Input Type Required Meaning
analysis_type string yes The installed analysis node type to assess, from list_node_types.
config object no The selected analysis configuration. Its fields are package-owned, so the core passes this object to the package unchanged.
project_id string (uuid) yes The project this call acts in.
scenario_id string (uuid) yes UUID of the saved scenario to assess.

Get storage usage

get_storage_usage

Read account storage usage, upload reservations and limit. Workspace grants only. Check before large uploads or after nearLimit and tell the user. Full storage refuses new writes, not reads or deletions. list_history_cleanup reviews unused older versions of scenarios and workflow-saved files to free space.

Preview history cleanup

list_history_cleanup

Review what cleanup could free, by kind, across every project you may reach, largest reclaimable storage first: the unused earlier versions of scenarios, or earlier files of data sources (kind data_source). Current versions, latest files and what a workflow, a saved result or an unfinished run reads stay protected. Page with cursor; confirm the selection with the person before cleanup_history.

Input Type Required Meaning
kind scenario or data_source yes Which kind of object this call is about.
limit integer no Default: 25.
cursor string no Continue from the page before: its nextCursor.

Preview data source

preview_data_source

Preview a data source's file: a table's header and a bounded sample of rows (limit), to orient before mapping columns; a Markdown or text document's complete text, headings and blank lines kept, with no columns or rows. For built scenario data, aggregate through query_scenario.

Input Type Required Meaning
data_source_id string (uuid) yes
limit integer no Default: 20.
project_id string (uuid) yes The project this call acts in.
file_id string (uuid) no Else its latest file.

List saved versions

list_versions

List an object's versions by kind and id, newest first; page on with before_version set to the last version.number. scenario: each with the exact result's id and input evidence, without changing workflows or comparisons; include_table_counts adds each version's table sizes, and unversioned results have no inferred history. data_source: its files, newest first.

Input Type Required Meaning
kind scenario or data_source yes Which kind of object this call is about.
before_version integer no The last number the page before answered.
include_table_counts boolean no Include tableRowCounts for browsing stored tables. Omitted by default to keep the identity summary compact. Applies to kind scenario. Default: False.
limit integer no Default: 20.
project_id string (uuid) yes
id string (uuid) yes The object whose versions to list; for a scenario, any version's id.

Export saved object

export

Export one object by kind and id as its portable artifact. workflow: the scmotif.workflow/1 JSON inline (graph, settings and code, no data), with references naming every data source or scenario it reads; pass artifact unchanged to import. scenario: a scmotif.scenario/1 ZIP prepared server-side and answered as a short-lived download_url plus an export id that import copies into another project without handling the file; an unchanged scenario reuses its prepared export. data_source: a short-lived link to a file, never its contents; copy_data_source moves one between projects. If fetching download_url cannot connect, your environment blocks its host: tell the person that host and guide_url, which says how to allow it.

Input Type Required Meaning
kind workflow or scenario or data_source yes Which kind of object this call is about.
project_id string (uuid) yes The project this call acts in.
id string (uuid) yes The object's id, as list or the call that created it answered it.
file_id string (uuid) no Else its latest file. Applies to kind data_source.

List node types

list_node_types

List every node type this instance can run, by category, with what each is for and the data it needs present. The catalogue is what the installed packages supply, so it is this instance's answer and not a remembered one — read it before authoring a workflow rather than assuming a node type exists. Choose from it, then call describe (kind node_type) for each type you use: its ports, parameters and documentation. detail: 'full' returns every type's whole description at once. typeCompatibility declares which port types connect; unknown is untyped and accepts every served type.

Input Type Required Meaning
detail summary or full no 'summary' (default) lists each type's name, label, category, purpose and data requirements; 'full' adds every type's ports, parameters and documentation. Default: summary.

Describe capabilities

describe

Describe what the product builds with, by kind. node_type with name: what one node type does, its input ports (an edge's target handle must match one; a Script's ports are its entry function's parameters), what it emits, its parameters, dataRequirements and its documentation page, whose headings sections lists; where documentationComplete is false ask again with section. tile_kind: every tile kind a dashboard can display, with the schema add_tile validates against and authoring guidance, read before the first tile. renderer: the map capability, basemaps, output formats, the columns a points query must supply, the point cap and the privacy posture, read once before the first render_visualization or map tile.

Input Type Required Meaning
kind node_type or tile_kind or renderer yes Which kind of object this call is about.
name string no The node type to describe, as list_node_types names it, bare or namespaced. Required for kind node_type; not taken by other kinds.
section string no A heading from sections, as written; answers only that part of the page. Applies to kind node_type.

Validate workflow

validate_workflow

Cheap pre-execution check on a stored workflow, without running anything. Returns its structural diagnostics — a scenario-producing node with no create-scenario node after it, an unbound required port, two connections into a port that takes one — and the data-dependent ones no write reports: a data_input node naming a data source this project does not hold, and each join checked against the data it joins (a key column missing from the file, key values that match nothing, an inner join with no matches). valid is false while any error stands. nodeColumns lists the columns each node hands on — a Filter's or Join's by the run's rules, a Script's from its last run, outOfDate once it changed. Use it before run_workflow, which is the expensive way to learn the same thing.

Input Type Required Meaning
project_id string (uuid) yes The project this call acts in.
workflow_id string (uuid) yes UUID of the deployed workflow to validate.

List execution diagnostics

list_execution_diagnostics

Fetch a run's persisted diagnostics in batches. Every finding says what happened, why, and what to do about it, and names the subject it is about. get (kind execution) already carries the first error and the counts per severity; this is where the rest are, a page at a time.

Input Type Required Meaning
execution_id string (uuid) yes The execution id run_workflow answered as executionId.
limit integer no Page size (default 25, max 100). Default: 25.
offset integer no Page offset for the next batch. Default: 0.
project_id string (uuid) yes The project this call acts in.
severity error or warning or info no Return only findings of this severity; omit for all.

Get scenario topology

get_scenario_topology

Read a scenario's topology: its network as nodes and links, grouped and unit-folded server-side — what it looks like, not what it cost. At most location_limit locations and link_limit links come back; when more match, the network's endpoints (demand points, places that only receive) are cut first, so what serves them stays whole: the biggest receivers kept, the rest folded into one location with groupSize. Narrowing precedes that cut, so every location is reachable: filters narrows the link rows (e.g. one product) and node_filters narrows to named locations or location types with every link touching them. isAggregated reports a cut; matchingLocations counts what the narrowing selected, totalLocations and totalLinks the whole scenario, and omittedLinkRows links naming a location the scenario lacks. Null coordinates mean unplaced locations; when coordinatesDeclared is false, the domain has no coordinate fields. Null measures with mixedUnits cannot be added across units.

Input Type Required Meaning
filters object no Optional per-axis narrowing of the link rows, applied server-side, before aggregation and before the location cap. A link is grouped by (source, target) only, so its quantity, cost and emissions are totalled across every other column; narrowing here is what keeps each surviving link at the magnitude of the values named, and the answer's locations are the ones those rows reach. Keys are the link axes the installed package declares beyond the two endpoints — to narrow to a location, use node_filters. Each value is a scalar or a list of them — {"<column>": <value>} or {"<column>": [<value>, …]}, equality and membership only. An undeclared key is refused with invalid_constraint_params, never dropped.
link_limit integer no How many links this answer may carry. When more connect the kept locations, links between two non-endpoint locations rank first, then the largest by quantity; isAggregated says it cut. A value above the most one answer carries is read as that ceiling. Default: 2000.
location_limit integer no How many locations this answer may carry, not counting the one group a cut adds. When more match, the cut takes the network's endpoints first — places the domain records demand at, and places that receive links and send none — keeping every other place in file order and the endpoints that receive the most, and groups the endpoints it did not keep into one location with groupSize; isAggregated says it cut and matchingLocations how many matched. A value above the most one answer carries is read as that ceiling. Raise it with link_limit to see a whole network. Default: 500.
node_filters object no Optional narrowing to locations, applied server-side and before the location cap, so any location of the scenario can be reached however large it is. Keys are the location identity and type columns the installed package declares; a location matching every key is kept with every link (still under filters) that has either end at it, and each link's other end. Same value shapes as filters — {"id": "C1999 Madrid"}, {"type": ["Distribution Center"]}. An undeclared key is refused with invalid_constraint_params, never dropped.
project_id string (uuid) yes The project this call acts in.
scenario_id string (uuid) yes

Inspect scenario

inspect_scenario

Inspect a scenario before querying it: by default, a compact overview of stored tables, row counts and column names/types. Select table for column meanings, units and sample rows; optionally select columns. Follow next_offset with the same selection to read more tables (overview) or columns (table detail). Then use query_scenario for read-only SQL.

Input Type Required Meaning
project_id string (uuid) yes The project this call acts in.
sample_size integer no Sample rows for a selected table (default 5, max 20); requires table. Large samples may be reduced with sample_truncated.
scenario_id string (uuid) yes UUID of the scenario to inspect.
columns list of string no Selected column names; requires table.
offset integer no Continue at next_offset from the preceding page, with the same selection.
table string no Stored table name from the overview; omit for the catalogue.

Query scenario

query_scenario

Read one or compare several scenarios after inspect_scenario. For totals or grouped aggregates over one table, use table and measures: units are handled automatically, and scope scenario_comparison returns each scenario in scenario_ids in one call. For joins, CTEs, windows, calculated expressions or raw rows, use source_sql, the same read-only DuckDB SQL as dashboard tiles; never combine it with structured query fields. Aggregate each table before joining totals: joining detail rows across tables multiplies sums. SQL tables include scenario_id; scenarios supplies names. Bind :name values with params. SQL does not infer units or convert quantities: inspect source units and make conversions explicit. limit and offset page SQL results; next_offset continues them. Use ORDER BY with unique tie-breakers for repeatable pages. profile requests the shared query plan; slow reads also report it.

Input Type Required Meaning
dimensions list of string no Stored column names to group by, taken from the selected table's inspect_scenario columns. Omit or send an empty array for one aggregate row across the whole filtered table (one per scenario in a comparison, which always groups by scenario_id and scenario_name before these; naming either here changes nothing).
filters list of object no Predicates applied before grouping, combined with AND. Each field is a stored column named by inspect_scenario; use in with an array and between with a two-value array.
filters[].field string yes Stored column to test, in the spelling returned by inspect_scenario.
filters[].op eq or ne or lt or lte or gt or gte or in or between yes Comparison to apply to the stored column. in expects an array and between expects a two-value array; the other operators compare one value.
filters[].value any value yes Value to compare with the stored column; its type should match the sampled values from inspect_scenario.
limit integer no Maximum result rows per response. SQL may return fewer to fit the reply budget; continue using next_offset. Structured aggregation reports truncated when this cap applies. Default: 200.
measures list of object no Structured-query aggregate measures, used only without source_sql.
measures[].agg sum or avg or min or max or count or count_distinct yes Aggregate applied to field within each dimension group.
measures[].as string no Optional output-column name for this measure. Without it the column is named after field, or <field>_<agg> when another output column would share that name (for example quantity_sum beside quantity_count). Output names must be unique: a collision that remains, such as the same measure twice or an as repeated or naming a dimension, is refused with invalid_constraint_params.
measures[].field string yes Stored column to aggregate, in the spelling returned by inspect_scenario.
order_by list of object no Output columns to sort by after aggregation. Name a dimension or a measure's as value, in priority order.
order_by[].dir asc or desc no Sort direction; defaults to ascending when omitted.
order_by[].field string yes Output dimension or measure column to sort by.
profile boolean no Return the shared query profile. Slow SQL reads also include it without this flag; the same timeout and diagnostics apply to dashboard SQL. Default: False.
project_id string (uuid) yes The project this call acts in.
scenario_id string (uuid) no Single-scenario shorthand; prefer scenario_ids. It is folded into scenario_ids when that is empty, and a value not among a non-empty scenario_ids is refused with invalid_constraint_params. On HTTP it is the path's {id}.
scenario_ids list of string (uuid) no Scenario UUIDs to read. For scope: scenario, name exactly one (or use the HTTP path's scenario_id); for scenario_comparison, name at least two.
scope scenario or scenario_comparison yes Required scenario scope: scenario reads one, scenario_comparison reads at least two. SQL reads exactly these scenarios and chooses grouping itself; structured comparisons group by scenario first.
table string no Exact stored table name to query, taken from inspect_scenario for every scenario in scope.
offset integer no SQL result offset; continue with next_offset. Use stable ORDER BY in source_sql. Structured queries do not accept a nonzero offset. Default: 0.
params map of text to string or number or boolean or null no Values for :name SQL parameters. Only valid with source_sql.
source_sql string no One read-only SELECT or WITH statement in the dashboard DuckDB dialect. Stored table names are SQL relations, quoted when necessary; each includes scenario_id. Join scenarios by id for names, and filter by scenario_id, never by scenario name. Only explicitly scoped scenarios exist in this read. No file/network access or mutations.

Render visualization

render_visualization

Render a map visualization from scenario results, returning its mapView and requested HTML or PNG exports. Read describe (kind renderer) for formats and category limits. points.source_sql selects longitude, latitude and encoding columns from scenario tables under scenario_scope. The core frames the map and fetches only generic basemap tiles; scenario coordinates never leave. Iterate here, then publish with add_tile using the same map intent. Creates no durable object; a map that cannot be built is refused with each reason named.

Input Type Required Meaning
basemap dark or light no The basemap the points sit on: 'dark' (default, the product's own) or 'light' (for export surfaces). Both are keyless.
bounds list of number no Optional frame as [minLon, minLat, maxLon, maxLat] (WGS84 degrees). Omit and the map frames itself to its points; set it when sibling maps tell one story (all markets beside only the changed ones) so they share a frame — take the widest map's answered bounds and pass it to the others.
color_by string no A column whose distinct values colour the points, one colour per value across facets; the legend follows the query's row order: ORDER BY to read bands in sequence. Omit for a single-colour map.
color_scale categorical or sequential no 'sequential' paints ordered bands light to dark down the brand ramp; default 'categorical'.
comparison_scenario_id string (uuid) no Optional second scenario, resolved as the 'comparison' scope; with it, 'both' runs the points query across the two — join scenarios and carry scenarios.name as a column so a point can be told apart by the run it came from.
facet_by string no A column whose distinct values split the map into small multiples — one panel each, same basemap and frame. Omit for a single panel.
dashboard_id string (uuid) no Colour categories as this dashboard does, so the export matches its tile.
formats list of html or png no Which exports to return: 'html' (interactive, to embed in an artifact) and/or 'png' (static, for decks). Defaults to both.
label_by string no A column whose value is written as each point's label; nulls are omitted.
points object yes The query that yields the points, one row per point.
points.source_sql string yes SELECT over the scenario's stored tables. Must yield longitude and latitude columns (WGS84 degrees); every other column is carried onto the point.
project_id string (uuid) yes The project this call acts in.
scenario_id string (uuid) yes The scenario whose results bind as the 'primary' scope.
scenario_scope primary or comparison or both no Which scenario(s) the points query runs against: 'primary' (default), 'comparison', or 'both'.
title string no Optional working title; a published tile's title is the intent's.

Get user preferences

get_user_preferences

Read the authenticated account number presentation preferences across projects and devices. Defaults: decimal_places 2, number_format en-US. Numerical API values remain unchanged.

Tools that write

Only a connection you gave Read and write is shown these.

Create project

create_project

Create a new project — the container a workspace grant's data sources, workflows, scenarios and dashboards all live in. Returns the same object get (kind project) returns, including the id every project-scoped call then names. Create one per question the user wants a durable, re-runnable answer to, not one per conversation. A name this user already holds — compared case-insensitively — is refused with a diagnostic naming the collision: reuse the existing project or pick a name that says what is different about this one. A blank name is refused too: a project must be called something. A connection granted only some projects reaches the one it creates: the new project joins its grant at once.

Input Type Required Meaning
description string or null no
name string yes

Update saved object

update

Can replace or delete what it acts on.

Update one object by kind and id; omitted fields stay. project: name or brief, the brief sent as description with the baseBriefVersion it was edited from (a stale one is refused); the brief is the standing context loaded each turn; record lasting decisions there. scenario: name and description of the current result; currency and horizon never change. data_source: name only; contents arrive as a new file by upload. dashboard: name, description, the selection within its fixed mode (scenario_ids, or scenario_id with comparison_scenario_id, replaces it; baseline_scenario_id or comparison_scenario_id alone moves that role), refresh_from_execution_id (moves that run's workflow outputs together; refused when one has no single replacement) and layout, every grid tile once with order and span in twelve columns, else refused naming the ids; a moved selection answers stoppedDrawing. Tiles: add_tile, replace_tile, remove_tile.

Input Type Required Meaning
kind project or scenario or data_source or dashboard yes Which kind of object this call is about.
baseBriefVersion integer no The briefVersion of the brief this description was edited from. Required with every brief: a brief changed since is refused rather than overwritten. Applies to kind project.
description string or null no The new description; for a project, the brief as markdown, replacing the current one in full. Applies to kinds project, scenario, dashboard. At most 100000 characters for kind project; at most 600 characters for kinds scenario, dashboard. Default: None.
name string or null no The new name. Default: None.
id string (uuid) yes The object's id, as list or the call that created it answered it.
project_id string (uuid) no The project this call acts in. Required for every kind but kind project.
rowCount integer or null no Not writable: read from the uploaded file on every request. Upload a corrected file with upload (kind data_source) instead. Applies to kind data_source.
sizeBytes integer or null no Not writable: read from the uploaded file on every request. Upload a corrected file with upload (kind data_source) instead. Applies to kind data_source.
type csv or xlsx or xls or md or txt or null no Not writable: read from the uploaded file on every request. Upload a corrected file with upload (kind data_source) instead. Applies to kind data_source.
baseline_scenario_id string (uuid) no The scenario every widget falls back to and deltas are measured against. Defaults to scenario_id. It must be one of the dashboard's scenarios: naming one outside scenario_ids adds it to the selection rather than binding a scenario the dashboard is not about. Applies to kind dashboard.
comparison_scenario_id string (uuid) no The other side of an 'a_vs_b' dashboard. Naming it alone moves that role and leaves the rest of the selection as it is. Applies to kind dashboard.
layout object no The whole arrangement, as get (kind dashboard) reports layout: every grid tile once, with its order and its span in twelve columns. Omit it and the core keeps what is stored, or derives one from the tiles for a dashboard nobody has arranged. Applies to kind dashboard.
layout.tiles list of object yes
layout.tiles[].i string yes
layout.tiles[].order integer yes
layout.tiles[].span integer yes How many of the row's twelve columns the tile takes: 12 is the whole row, 6 a half, 4 a third, 3 a quarter.
mode single or a_vs_b or across no The existing dashboard mode. Repeating it is accepted; changing it is refused because the mode is fixed at creation. Deploy a new dashboard to use a different mode. Applies to kind dashboard.
scenario_id string (uuid) no The single scenario this dashboard is about. Replaces the whole selection, and becomes the baseline unless baseline_scenario_id names another member. Applies to kind dashboard.
scenario_ids list of string no Every scenario this dashboard is about, in display order. Replaces the whole selection: a scenario left out stops being one of the dashboard's, and a role whose member is left out is cleared with it. Send it to reorder, to add or to remove; omit every scenario field to leave the selection untouched. Applies to kind dashboard.
refresh_from_execution_id string (uuid) no Refresh selected outputs of this run's workflow together, preserving order and roles; other workflows stay fixed. The run must be completed and contain an unambiguous replacement for every selected output of its workflow. Cannot be combined with scenario selection fields. Uses output identities, never names. The link stays the same; inspect stoppedDrawing, tileHealth and commentaryNeedsReview before handing it over. Applies to kind dashboard.

Delete saved history

cleanup_history

Can replace or delete what it acts on.

Delete reviewed unused history permanently, by kind, after the person has confirmed it: send each selection's outputId and previewToken from list_history_cleanup. The review is rechecked under locks and a changed one refuses the whole call: refresh and reconfirm. Current and protected versions remain; storage is reclaimed asynchronously.

Input Type Required Meaning
kind scenario or data_source yes Which kind of object this call is about.
selections list of object yes
selections[].outputId string (uuid) yes
selections[].previewToken string yes

Upload data source

upload

Upload a file by declaring it; its bytes never travel here. kind data_source: a .csv, .xlsx, .md or .txt file. scenario_bundle: a scmotif.scenario/1 ZIP, followed by import. Both start or resume a multipart session bound to project, name, exact size and SHA-256 and answer short-lived PUT targets: send each exact slice with the returned headers (a 403 with Cloudflare error 1010 means the User-Agent was missing), then call complete_upload and poll get until ready or rejected. The same name, size and hash resumes; a changed size or hash is refused while the name is held. If a PUT cannot reach the target host, tell the person to allow it (guideUrl) or to upload the file at url. If you cannot hash or send a file at all, start no session and never copy its rows into a workflow: hand the person the project's uploadUrl (create the project first if needed) and continue once list shows the file. Never construct or keep target URLs.

Input Type Required Meaning
kind data_source or scenario_bundle yes Which kind of object this call is about.
name string yes The filename with its extension, unused by the project's other files; a bundle's is recorded in provenance. 1 to 200 characters for kind data_source.
project_id string (uuid) yes The project this call acts in.
sha256 string yes Lowercase hex SHA-256 over the exact whole file. Required independently of storage multipart ETags; ingestion rejects the session if the stored bytes differ.
size_bytes integer yes The exact file size in bytes. It reserves account capacity and determines the fixed multipart slices before bytes travel.
data_source_id string (uuid) no Joins this data source as its latest file. Applies to kind data_source.
data_source_name string no Or starts a data source of this name. Applies to kind data_source.

Resume upload

resume_upload

Resume an upload by reconciling multipart state from object storage and returning fresh short-lived targets for missing parts. Safe to repeat after a timeout, process restart or lost response; an already stored part is not requested again. Send the returned target headers with every PUT; non-browser clients, including Python urllib, must use the supplied User-Agent. Browsers retain their own User-Agent. HTTP 403 with Cloudflare error 1010 means the object edge refused the client identity: retry with the target headers, and contact the service operator if it persists; changing file bytes will not repair that refusal. Retrying a PUT safely replaces its part. Never construct or persist target URLs. Targets are a bounded batch: resume again after sending the batch until no parts are missing.

Input Type Required Meaning
project_id string (uuid) yes The project this call acts in.
upload_session_id string (uuid) yes

Cancel work

cancel

Can replace or delete what it acts on.

Cancel something in flight by kind and id. execution: a pending or running run is asked to stop; a finished one refuses, naming its final status; whatever it persisted stays, and a cancelled run publishes no scenario, so poll get to see it take effect. upload_session: an upload that has not finished is discarded, freeing the name it holds and the storage it reserves; starting again is a new upload. An upload whose file has arrived is being read and cannot be cancelled: wait for get to report it, then delete the data source if it is not wanted.

Input Type Required Meaning
kind execution or upload_session yes Which kind of object this call is about.
id string (uuid) yes The object's id, as list or the call that created it answered it.
project_id string (uuid) yes The project this call acts in.

Complete upload

complete_upload

Complete an upload after every exact-sized part is present, finalizing the multipart object and enqueueing strict ingestion. Safe to repeat: it never creates a second DataSource or a second immutable object. Poll get (kind upload_session); only ready makes the data source visible.

Input Type Required Meaning
project_id string (uuid) yes The project this call acts in.
upload_session_id string (uuid) yes

Delete saved object

delete

Can replace or delete what it acts on.

Delete one object by kind and id, permanently. data_source: with all its files; scenarios built from it keep their rows, a workflow reading it stops being runnable; refused, naming them, while an unfinished run reads one. file: one file; the newest left becomes the latest. workflow: archived, so it leaves the overview and can no longer be edited or run, while its runs, snapshots, scenarios and results remain. scenario: every version's tables go; refused while an unfinished run or a dashboard reads it, both named in the answer, and also_delete_dashboards removes those dashboards with it. dashboard: its link stops resolving for everyone it was handed to, so confirm before deleting one you did not just create; the scenarios behind it are untouched. A project is deleted by a person in the app.

Input Type Required Meaning
kind data_source or workflow or scenario or dashboard or file yes Which kind of object this call is about.
id string (uuid) yes The object's id, as list or the call that created it answered it.
project_id string (uuid) yes The project this call acts in.
also_delete_dashboards boolean no Delete dashboards referring to any version together with the entire scenario history. Otherwise refuse and name them. Ask the user before true: it destroys their pages. Applies to kind scenario. Default: False.

Restore saved version

restore_version

Can replace or delete what it acts on.

Restore a historical version as a new current version of the same object, by kind and the version's own id; future downstream runs use it, existing results and queued runs stay pinned. scenario: data, inputs and computation provenance are preserved and nothing is recomputed; comparisons stay pinned, inactive outputs stay inactive, and restoring the current version is refused. data_source: an earlier file, by its id, is copied as the latest.

Input Type Required Meaning
kind scenario or data_source yes Which kind of object this call is about.
project_id string (uuid) yes
id string (uuid) yes The id of the version to restore, as list_versions answered it.

Copy data source

copy_data_source

Copy a data source's file into project_id as a new data source of the same name; both projects must be in your grant. Its id reconnects a workflow on import (kind workflow).

Input Type Required Meaning
data_source_id string (uuid) yes
name string no Else the original's; same file kind.
project_id string (uuid) yes The project this call acts in.
source_project_id string (uuid) yes
file_id string (uuid) no Else its latest file.

Create workflow

create_workflow

Create a named workflow from nodes and edges. Unfinished graphs are stored with diagnostics identifying missing inputs, configuration and scenario-producing connections. Malformed graphs are refused: invalid node references, unknown ports or incompatible connections. Call list_node_types and describe (kind node_type) before wiring nodes; validate_workflow checks data-dependent rules, and run_workflow refuses outstanding diagnostics. Names are unique within a project, compared case-insensitively. An existing name receives a numeric suffix such as Plan (2), shortening the base to fit the name limit; use the assigned name in the response.

Input Type Required Meaning
description string no
edges list of object yes
edges[].id string yes
edges[].source string yes
edges[].sourceHandle string or null no the output port name; binding is by name, never by edge order; null, or left out, when the source has one output
edges[].target string yes
edges[].targetHandle string no the input port name; binding is by name, never by edge order
name string yes
nodes list of object yes
nodes[].data object yes The node's configuration: the parameters describe (kind node_type) lists for this type, keyed by parameter name. Every node takes label, its name on the canvas, saying what the step does, and description, saying how and with which assumptions.
nodes[].id string yes
nodes[].position object no
nodes[].position.x number no
nodes[].position.y number no
nodes[].type string yes a node type the registry declares
project_id string (uuid) yes The project this call acts in.

Apply workflow

apply_workflow

Can replace or delete what it acts on.

Replace the whole workflow read with get (kind workflow); send its version as baseVersion. Stale copies are refused. Return all fields, including description: omitted fields become empty and omitted nodes/edges are removed. Use patch_workflow for targeted edits. The create gate applies: malformed definitions are rejected; incomplete definitions are stored with diagnostics. Names must be unique within the project, case-insensitively; retaining this workflow's name or changing its case is allowed.

Input Type Required Meaning
baseVersion integer yes The version of the get (kind workflow) copy this definition was made from. Required: if the workflow has changed since, the apply is refused with changed_since_read instead of undoing that change — read it again, redo your change on that copy and send it with the new version.
description string no
edges list of object yes
edges[].id string yes
edges[].source string yes
edges[].sourceHandle string or null no the output port name; binding is by name, never by edge order; null, or left out, when the source has one output
edges[].target string yes
edges[].targetHandle string no the input port name; binding is by name, never by edge order
name string yes
nodes list of object yes
nodes[].data object yes The node's configuration: the parameters describe (kind node_type) lists for this type, keyed by parameter name. Every node takes label, its name on the canvas, saying what the step does, and description, saying how and with which assumptions.
nodes[].id string yes
nodes[].position object no
nodes[].position.x number no
nodes[].position.y number no
nodes[].type string yes a node type the registry declares
project_id string (uuid) yes The project this call acts in.
workflow_id string (uuid) yes Id of the stored workflow this definition replaces, from list (kind workflow) or the get (kind workflow) copy you are sending back.

Patch workflow

patch_workflow

Can replace or delete what it acts on.

Edit a workflow with a merge patch. Call get (kind workflow) first; omitted nodes and fields retain their current values, including concurrent edits. patch.nodes maps node ids to fragments: null deletes a node and its edges; a new id with type and data adds one. Use apply_workflow to replace the whole definition. Malformed results are refused atomically; incomplete graphs are stored with diagnostics. Renames must be unique in the project, case-insensitively; retaining this workflow's name or changing its case is allowed.

Input Type Required Meaning
patch object yes Merge patch over the workflow document. Include ONLY what changes — everything not named is preserved exactly. Shape: {"name"?, "description"?, "nodes"?: {"": null | {...fragment}}, "edges"?: {"": null | {"source", "target", "targetHandle", "sourceHandle"?}}}. Every edge must name the input port it feeds via targetHandle — for code nodes the ports are the transform function's own parameter names; validation lists the valid ports on a mismatch. Semantics: objects merge key-by-key (including inside a node's data); null deletes a node, an edge, or a data key; arrays are replaced whole. Deleting a node also removes its connected edges. Add a node by using a new id with a full {"type", "data", "position"?}. Example — change one join: {"nodes": {"join-werks": {"data": {"join_type": "inner"}}}}. Call get (kind workflow) first so node ids and data field names are exact.
patch.description string or null no
patch.edges object no
patch.name string no
patch.nodes object no
project_id string (uuid) yes The project this call acts in.
workflow_id string (uuid) yes Id of the stored workflow to edit, from list (kind workflow) or the answer of create_workflow or import (kind workflow).

Run workflow

run_workflow

Can replace or delete what it acts on.

Execute a stored workflow asynchronously. Structural errors or no compatible live worker refuse submission without creating an execution; repair the graph or ask the operator to restore workers via /health. Poll executionId with get (kind execution) for status, current storage and outputs; read failures with list_execution_diagnostics. This answer’s storage precedes compute. Inputs use the current saved scenario and file versions at acceptance, fixed for the run, without recomputing upstream workflows. Producing steps add versions; existing dashboards retain exact results.

Input Type Required Meaning
project_id string (uuid) yes The project this call acts in.
workflow_id string (uuid) yes UUID of the deployed workflow.

Deploy dashboard

deploy_dashboard

Create a dashboard about one or more scenarios and get the link that opens it on its own; mode is fixed for its life. The core resolves every tile at view time, so numbers stay live and attributed. Add tiles with add_tile, verify with get (kind dashboard), and hand the user the link. Tiles show numbers: give the recommendation, its reasoning and open points in your answer, not on a tile.

Input Type Required Meaning
baseline_scenario_id string (uuid) no The scenario every widget falls back to and deltas are measured against. Defaults to scenario_id. It must be one of the dashboard's scenarios: naming one outside scenario_ids adds it to the selection rather than binding a scenario the dashboard is not about.
comparison_scenario_id string (uuid) no The scenario compared against the baseline in an 'a_vs_b' dashboard. It does not set the mode: send mode 'a_vs_b' with it, because a dashboard sent without a mode is 'single', and a 'single' dashboard cannot hold a comparison.
description string no Optional dashboard description.
mode single or a_vs_b or across no What the dashboard is about, fixed for its whole life: 'single' (one scenario), 'a_vs_b' (one against another, with deltas) or 'across' (many at once). Choose from the question asked, not from how many scenarios exist — two scenarios in 'across' is two of many, not a comparison, and gets no deltas. It cannot be changed afterwards; a dashboard of a different shape is a new dashboard.
name string yes Dashboard name.
project_id string (uuid) yes The project this call acts in.
scenario_id string (uuid) no The scenario this dashboard is about; it becomes the baseline unless baseline_scenario_id names another. Name the selection with this (plus comparison_scenario_id for 'a_vs_b') or with scenario_ids. A dashboard may be created before its scenario exists.
scenario_ids list of string no Every scenario a mode='across' dashboard compares, in display order. Use instead of scenario_id when the answer spans more than two scenarios.

Add tile

add_tile

Add a tile to a dashboard. Pass an intent — the kind of tile and what it should show — and the core runs the query and assembles the widget. Omit position to append, use top for the beginning, or after:<widget_id> to insert after a tile whose widgetId get (kind dashboard) reports in widgets; an id the dashboard does not carry is refused and the refusal names the ids it does. describe (kind tile_kind) gives every kind's shape and rules; read it once before authoring the first tile. Do NOT pass rows, chart JavaScript or HTML: a dashboard is a recipe the core resolves at view time, which is what keeps its numbers live. The core assigns the tile's id and answers with it; an id inside the intent is ignored, because two tiles sharing one id is a replace_tile that edits the wrong one. Check the result with get (kind dashboard) before handing anyone the link — include_health is what tells you the tile came back with something.

Input Type Required Meaning
dashboard_id string (uuid) yes UUID of the dashboard.
intent object yes Kind-discriminated tile intent — must include kind. describe (kind tile_kind) gives every kind's schema and authoring rules.
position string no Where to insert the tile. 'top' inserts at the beginning, 'after:' inserts after a specific widget. Omit to append at the end (default).
project_id string (uuid) yes The project this call acts in.
profile boolean no Also answer what the tile's slowest statement cost, step by step (profile), however quickly it ran. A statement slow enough to be worth rewriting is answered with it unasked. Default: False.

Replace tile

replace_tile

Can replace or delete what it acts on.

Overwrite one tile with a new intent, keeping its id and therefore its position. This is the repair for a tile get (kind dashboard) reports as empty or unresolvable: send the corrected intent rather than removing and re-adding, which would move it to the end. describe (kind tile_kind) gives the shape and rules of the kind you are correcting. An id this dashboard does not carry is refused — and the refusal lists the ids it does.

Input Type Required Meaning
dashboard_id string (uuid) yes UUID of the dashboard.
intent object yes Kind-discriminated tile intent — must include kind. describe (kind tile_kind) gives every kind's schema and authoring rules.
project_id string (uuid) yes The project this call acts in.
widget_id string yes The widgetId of the tile to replace, exactly as get (kind dashboard) reports it in widgets. A tile id is assigned by the core and is recipe-local (w1, w2, ...), NOT a UUID. The replacement keeps this id and therefore its position.
profile boolean no Also answer what the tile's slowest statement cost, step by step (profile), however quickly it ran. A statement slow enough to be worth rewriting is answered with it unasked. Default: False.

Remove tile

remove_tile

Can replace or delete what it acts on.

Remove one tile from a dashboard by its id, and read the dashboard back without it. The remaining tiles keep their positions and their ids. get (kind dashboard) is where a tile's id comes from, and replace_tile is what to use when the tile belongs there and its contents are wrong. An id this dashboard does not carry is refused — and the refusal lists the ids it does, so a stale id costs one call and not a redeploy.

Input Type Required Meaning
dashboard_id string (uuid) yes UUID of the dashboard.
project_id string (uuid) yes The project this call acts in.
widget_id string yes The widgetId of the tile to remove, exactly as get (kind dashboard) reports it in widgets. A tile id is assigned by the core and is recipe-local (w1, w2, ...), NOT a UUID.

Update user preferences

update_user_preferences

Can replace or delete what it acts on.

Save account number presentation preferences across projects and devices. Supply decimal_places (0 through 6), number_format (en-US or de-DE), or both. Omitted settings keep their saved values. Changes separators and precision for display only; stored values, currency placement, calculations and raw exports remain unchanged.

Input Type Required Meaning
decimal_places integer no Decimal places used for numerical display throughout the app. Defaults to 2.
number_format en-US or de-DE no Number separators for numerical display: en-US (1,234.56) or de-DE (1.234,56). Defaults to en-US; currency placement and precision are unchanged.

Import saved object

import

Import one object of a kind into this project. workflow: an artifact from export or a downloaded file, validated like create_workflow with its code parsed and not run; reconnect maps exported references to this project's data sources and scenarios, and what stays unmapped comes back as unresolved_inputs for patch_workflow. scenario: from exactly one source, the upload_session_id of a bundle sent with upload or the export_id export answered for a scenario in any project you reach. A bundle that fails any check publishes nothing; repeating an upload session's import answers the same scenario.

Input Type Required Meaning
kind workflow or scenario yes Which kind of object this call is about.
artifact object no Required for kind workflow; not taken by other kinds.
artifact.name string no
project_id string (uuid) yes The project this call acts in.
reconnect map of text to string (uuid) no Exported reference → id of a data source or scenario of this project, of the same kind. Applied before the workflow is stored; a key the artifact does not reference, or a target this project lacks, refuses the import. Applies to kind workflow.
export_id string (uuid) no A live export from export (kind scenario). The server copies its bytes. Applies to kind scenario.
upload_session_id string (uuid) no The upload (kind scenario_bundle) session the bundle was uploaded through. Applies to kind scenario.