DocsTools reference

Tools reference

Every tool Ontyx offers your assistant for your organization’s own data, with its inputs and what it answers. Your assistant reads the same descriptions and picks the tools itself; this page is for checking what a tool does, or for building on Ontyx directly.

  • Every tool acts on the organization of the person signed in, worked out on each call from their membership.
  • Who can call it. Tools that only read can be called by any member: owner, admin or reader. Tools that change anything can be called by owners and admins only. A reader’s assistant isn’t shown them, and a reader who calls one anyway is refused before anything happens.
  • Tool names are stable. The tools for datasets, metrics and views are named <resource>_<action>.
  • Answers are JSON: { "ok": true, … } on success, { "error": { "code", "message" } } on a refusal. Messages are written to be passed on in plain words. No tool takes code or returns it.
  • Versions are always named: schema_version for a structure, data_version for a load, metric_version for a metric. No answer carries a bare version.
  • Dates are ISO 8601. A date and time without an offset is read in its column’s time zone.
  • While your organization is getting started, answers carry next_step: the natural next call.
  • None of these tools is metered.

The fields every data-returning answer carries (as_of, freshness, filters, read_from and the rest) are explained in Asking questions.

Errors

CodeMeaning
INVALID_REQUESTThe request doesn’t fit: a misspelled name (with a suggestion), a value of the wrong kind, a change the rules don’t allow, or rows that don’t fit (with failed_checks naming the checks they didn’t pass).
NOT_FOUNDNo dataset, metric or view by that name in your organization. A near miss gets a suggestion.
CONFLICTThe state changed or doesn’t allow it: a change is already waiting, rows landed since a change was proposed, an uploaded file hasn’t arrived, a retired metric was asked, or a change would stop an approved metric.
FORBIDDENThe person’s role can’t do this: only an owner or admin can.
ACCOUNT_NOT_SET_UPThe person isn’t in an organization yet. They need an invitation.
TERMS_ACCEPTANCE_REQUIREDThe account hasn’t accepted the current Terms of Service.
TIMEOUTA question ran past its time limit (20 seconds) and was stopped. Ask a narrower one.
UNAVAILABLEIt couldn’t be answered just now. Try again.
UNAUTHENTICATEDThe sign-in or key is missing, invalid or revoked.
RATE_LIMITEDToo many requests in a short time. The error carries retryAfterMs.

Datasets

dataset_list

The organization’s datasets and the state of each.

Who can call it: any member.

InputRequiredWhat it is
marked_for_deletionnotrue lists only the datasets marked for deletion, soonest to go first, with deleted_after.
looking_fornoWhat the person is after, in a few words (1 to 200 characters), such as "ammo prices by caliber". The answer is then the closest datasets instead of the whole list. Can’t be combined with marked_for_deletion: true.

Answers with count and datasets, each with name, description, status (waiting_for_approval, needs_new_proposal, ready or change_waiting_for_approval), schema_version, waiting_schema_version, has_data, data_version, as_of, freshness (and freshness_note when it’s out of date), expected_cadence, its relationships with how they matched at the last load, referenced_by (the datasets that point at it), and derived and sources for a dataset built from others. An organization with no datasets gets a message saying what Ontyx is for and the first step. Past 20 datasets, a note suggests looking_for.

With looking_for, it answers with the closest datasets, at most 5, in matches, closest first. Each has name, description, status, has_data, data_version, as_of, freshness (and freshness_note), rows (how many rows it has), columns (each column’s name and type), the approved metrics that read it (name and label), the saved views that ask those metrics, matched_on (which of its name, description and columns matched) and match: strong when its name matched or two or more of the words did, otherwise possible. others says how many datasets weren’t shown, and message sums it up in a sentence. When nothing matches, matches is empty and the message names every dataset, so your assistant can pick one or ask you without a second call.

The closest datasets are found by the words they share with what you asked: the dataset’s name counts most, then its column names, then its description. Common words are ignored, plurals and word endings are matched (prices meets price), and a shortened word is enough (ammo meets ammunition, temp meets temperature). The same words always give the same order. Datasets marked for deletion are never matched. If an answer would be too large, the column lists are left out first, then the descriptions, and a note says so.

dataset_define

Proposes a new dataset: structure version 1. No data can be loaded until an owner or admin approves it.

Who can call it: owners and admins.

InputRequiredWhat it is
nameyesThe short name: lowercase letters, digits and _, starting with a letter, up to 63 characters. Unique among the organization’s datasets, metrics and views.
descriptionnoWhat the dataset is, in a sentence.
columnsyesEvery column, in order (1 to 500): name, type, and optionally scale, timezone, nullable (default true) and description.
keynoThe columns that together identify each row, in order (up to 8). Each must have nullable: false and can’t be json.
default_load_modenoreplace (default), append or upsert (needs a key).
expected_cadencenohourly, daily, weekly, monthly, quarterly or yearly.
keep_rawnoKeep a copy of each original record (default true).
relationshipsnoUp to 10, each { columns, parent }: this dataset’s columns that hold the identifiers of rows in parent (which may be this dataset), in the order of the parent’s key.
checksnoUp to 50: { kind: "not_null", column }, { kind: "unique", columns } or { kind: "accepted_values", column, values } (up to 200 values).
notenoWhere the data comes from, or why it’s shaped this way.

Column types: string (text), integer (whole number), number (measurement or coordinate), decimal (exact amount; scale 0 to 6 decimal places, default 2), boolean (yes/no), date, timestamp (date and time, stored in UTC; timezone is the IANA zone for source times with no offset), json (a list or nested value kept whole). Column names may use dots for nested fields (properties.mag) and are case-insensitive.

Answers with dataset, status, and proposal: its schema_version and a summary of the structure in plain words to show the person.

dataset_get_schema

A dataset’s structure: what’s in force, what’s waiting, and its history.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset’s name.

Answers with status, has_data, data_version, current (the approved structure in force: schema_version, columns, key, load mode, checks with each in words, relationships with their latest match), waiting_for_approval (the waiting change with its changes and warnings, or a first structure’s summary), history (the last 20 structure versions with who proposed and decided them, and any rejection_reason), last_rejected while the newest version is a rejected one, referenced_by, and derived for a dataset built from others.

dataset_propose_schema_change

Proposes a change to a dataset’s structure, as edits. It’s checked against the change rules (see Datasets) and, where data exists, against the rows already loaded. One change can wait at a time.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name.
add_columnsnoNew columns, added at the end (same shape as in dataset_define).
remove_columnsnoColumns to remove. Columns that identify a row can’t be removed.
change_columnsnoEdits to existing columns by name: a wider type, scale, timezone, nullable, description.
keynoOnly for a dataset with no key yet: the columns that will identify each row. The rows already loaded must have no blanks and no repeats in them.
default_load_modenoreplace, append or upsert.
keep_rawnoKeep a copy of each original record.
add_relationshipsnoRelationships to add, as in dataset_define. With data, the matches are counted and shown; refused only when no row matches.
remove_relationshipsnoRelationships to remove, by parent and columns.
add_checksnoChecks to add. An accepted_values check for a column that has one replaces its list.
remove_checksnoChecks to remove, by kind and column.
descriptionnoA new dataset description.
expected_cadencenoA new refresh schedule.
notenoWhy the change is being made.
retire_metricsnoOnly after a refusal because the change would stop approved metrics working: exactly the metrics it named, to retire them when the change is approved.

Answers with status and proposal: its schema_version, the changes in plain words and any warnings, relationship_checks for relationships it adds, and metrics_to_retire when it retires any.

dataset_approve_schema_change

Makes a waiting structure version (a new dataset’s first one, or a change) the one in force. Your assistant may only call it after the person says yes to that exact version in the conversation. Approval runs the data checks again, in case rows landed since the proposal. Approving a dataset built from others builds it.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name.
schema_versionyesThe structure version the person was shown.
confirmed_by_personyesMust be true: the person said yes to this exact version.

Answers with decision, decided_by, decided_at, status, schema_version_in_force, has_data, and when they apply relationship_checks, retired_metrics and built.

dataset_reject_schema_change

Discards a waiting structure version because the person said no. What’s in force stays as it is.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name.
schema_versionyesThe structure version to reject.
reasonnoWhy, in the person’s words (up to 1,000 characters). It’s kept with the rejected version.

Answers with decision, rejection_reason and schema_version_in_force.

Loading data

dataset_load_rows

Loads rows sent in the call: JSON objects or CSV text. Every row is checked first; if any doesn’t fit, nothing is loaded.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name. Its structure must be approved.
rowsone of rows or csvUp to 5,000 rows as JSON objects keyed by column name. Nested objects fill dotted columns.
csvone of rows or csvUp to 5,000 rows (2,000,000 characters) of CSV text with a header row.
modenoreplace, append or upsert. Default: the dataset’s own. For more rows than one call carries, send the first batch with the dataset’s mode and the rest with append (or upsert).
as_ofnoWhen the data is true of the world, with an offset (2026-10-01T00:00:00Z). Default: now.

Answers with data_version, mode, rows_loaded, rows_added, rows_updated (upsert), rows_already_there (append or upsert on a keyed dataset), identical_rows_combined (when some were), total_rows, as_of, fields_without_a_column (when the original record keeps them), checks (everything it verified) and a message. A refusal is INVALID_REQUEST with every problem, up to 20, and failed_checks. See Push API for each field.

dataset_begin_upload

Starts loading a file too big to send inline: up to 100 MB.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name. Its structure must be approved.
formatyescsv (with a header row), json (one list of records), jsonl (one record per line) or parquet.
modenoreplace, append or upsert. Default: the dataset’s own.
as_ofnoWhen the data is true of the world. Default: now.

Answers with upload_id, expires_at (about 30 minutes), largest_file, upload_page (a link for the person to open and choose the file), upload_command (a ready curl line, for an assistant that can run commands) and put (the address, method and exact headers for any other client).

dataset_finish_upload

Checks the uploaded file and loads it as a new data version, or refuses it. Either way the uploaded file is then discarded, so a corrected file needs a new upload. If the file hasn’t arrived yet, it says so (CONFLICT), and finishing can be tried again.

Who can call it: owners and admins.

InputRequiredWhat it is
upload_idyesThe id dataset_begin_upload returned.

Answers as dataset_load_rows does, plus file_size.

Looking and asking

dataset_preview

How many rows a dataset has, when it was loaded, whether it’s up to date, a summary of each column, and the first rows.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset’s name.
limitnoHow many rows to show from the start: 0 to 100, default 20.
include_originalnoAlso show each row’s original record, when the dataset keeps it. Default false.

Answers with the row envelope, total_rows, columns (for each: its type in words, blanks, smallest, largest and about how many distinct_values), showing and rows.

dataset_query

Answers a question from one dataset’s rows: filter, sort, group and total. See Asking questions.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset’s name.
columnsnoColumns to show, in order (up to 100). Not with group_by or aggregates.
wherenoUp to 20 filters, all of which must hold, each { column, op, value }. op is eq, ne, gt, gte, lt, lte, in (a list of up to 100), between (two values, both included), contains (text, ignoring capitals), is_blank or not_blank.
group_bynoUp to 5: a column, or { column, by } with by one of day, week, month, quarter, year for a date column. Named <column>_<by> in the answer.
aggregatesnoUp to 10, each { fn, column, as } with fn one of count, count_distinct, sum, avg, min, max.
order_bynoUp to 5, each { column, dir } with dir asc (default) or desc.
limitnoRows or groups to return: default 100, at most 1,000.
data_versionnoAn earlier data version to answer from.
includenoUp to 3 datasets this one points at through a declared relationship, each { parent, columns, via, as }. Their columns are named <parent>.<column> (or <as>.<column>) everywhere in the question.

Answers with the row envelope for rows, or the data envelope for groups and totals, plus rows_matching, groups, rows_returned, fields, rows, include (for a question across datasets), built_from (for a dataset built from others) and a message.

dataset_check_key

Checks whether some columns would identify each row of the data loaded now, without changing anything.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset’s name.
columnsyesThe columns that might identify each row, in order (1 to 8).

Answers with total_rows, blanks per column, repeated_values and rows_with_repeated_values, up to 5 examples, holds and a one-sentence verdict.

dataset_check_join

Checks whether some columns of a dataset point at rows of another (or of itself), without changing anything. The columns are matched, in order, against what identifies each row of the other dataset.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset whose rows point at the other.
columnsyesIts columns that hold the other dataset’s identifiers (1 to 8).
parentyesThe dataset they point at. It must have something that identifies each row.

Answers with the rows checked, rows with a blank (not checked), rows that match, rows that point at a row that isn’t there, match (such as "3 of 5 rows"), up to 5 examples and a one-sentence verdict.

History

dataset_row_history

One row as it stood in each of the latest 20 data versions, oldest first. See Lineage and history.

Who can call it: any member.

InputRequiredWhat it is
datasetyesThe dataset’s name. It must have something that identifies each row.
keyyesThe row’s value in each column that identifies it, named after the column: { "order_id": "A-1006" }.

Answers with the row envelope (its row_ids is the row followed), has_row, versions_shown, more_versions and versions, each with data_version, schema_version, as_of, source, loaded_by, loaded_at, load_mode, has_row, row, change (unchanged, changed, added, removed or not_there), changed_columns and changes (each { column, from, to }), and a summary.

lineage

Where a dataset’s data, a metric’s number or a saved view’s answers come from. See Lineage and history.

Who can call it: any member.

InputRequiredWhat it is
datasetone of dataset, metric or viewThe dataset to trace.
metricone of dataset, metric or viewThe metric to trace.
viewone of dataset, metric or viewThe saved view to trace. It takes none of the inputs below.
data_versionnoWith dataset: an earlier data version to trace.
metric_versionnoWith metric: an earlier or retired version to trace.
historynoHow many earlier loads to list (0 to 50). Default 5 for a dataset, 0 for each dataset a metric reads.

A name given as the wrong kind (a view’s name as metric, say) is answered with what the name actually is; a misspelled one gets a suggestion.

Answers, for a dataset, with data_version, latest_data_version, schema_version, as_of, freshness, source (inline, upload, push_api or derived), source_ref, loaded_by (a member, a push key by name, or unknown; worked_out_from: "reference" when it was worked out rather than recorded), loaded_at, load_mode, parent_data_version, total_rows, built_from for a dataset built from others, history, more_history, relationships and a summary. For a metric: metric_version, latest_metric_version, status, retired (when it is), sentence, reads (each dataset’s columns, the structure version then and now, and structure_changed), datasets (each traced as above) and a summary. For a saved view: view, description, status, metrics (each with its version in use, saved_with_metric_version, what it reads and whether it’s behind), datasets (every dataset behind them, once each, with its data version, what it points_at and what it’s built_from) and a summary.

Datasets built from others

dataset_derive

Proposes a dataset built from a saved question over other datasets, instead of loaded. Approving it with dataset_approve_schema_change builds it. It’s rebuilt when one of its sources has new data, the next time it’s asked. It holds up to 250,000 rows and is built from up to 4 datasets.

Who can call it: owners and admins.

InputRequiredWhat it is
nameyesThe new dataset’s name.
descriptionnoWhat it is, in a sentence.
questionyesdataset_query’s shape without limit or data_version: dataset, include, where, group_by, aggregates, and for rows rather than totals columns and order_by.
expected_cadencenoDefault: the most frequent of its sources’.
notenoWhy it’s being set up.
dry_runnotrue only checks it and says what it would be, setting nothing up.

Answers with status, derived, sources, question_in_words, key (its groups, when none can be blank) and proposal; when nothing would identify each row, a note with the exact not_blank filters to add. A dry run answers with status: "not_set_up" and the columns it would have.

dataset_rebuild

Builds a dataset built from others again now, from its sources’ current data. When none of them changed, nothing happens and the answer says so.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesA dataset built from others.

Answers with rebuilt, has_data, data_version, previous_data_version, total_rows, as_of, built_from and a message.

Deleting

dataset_mark_for_deletion

Hides a dataset and deletes it for good after a number of days, unless it’s restored. Refused while another dataset points at it, a dataset is built from it, or approved metrics read it; the refusal names all of them.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe dataset’s name.
keep_for_daysnoDays before it’s deleted for good: 1 to 30, default 7.
retire_metricsnoOnly after a refusal because approved metrics read it: exactly those metrics, to retire them as it’s marked.

Answers with marked_for_deletion, marked_for_deletion_at, marked_for_deletion_by, deleted_after and retired_metrics when there were any.

dataset_restore

Brings back a dataset marked for deletion exactly as it was: structure, data and versions.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe marked dataset’s name.

Answers with status, has_data and data_version.

dataset_delete_permanently

Deletes a dataset that’s already marked for deletion, right now. This can’t be undone.

Who can call it: owners and admins.

InputRequiredWhat it is
datasetyesThe marked dataset’s name.
confirmyesThe dataset’s name again, exactly.

Answers with deleted: true.


Metrics

metric_propose

Proposes a metric, or a new version of an existing one. It’s checked against the dataset’s structure and the data loaded now. See Metrics and saved views.

Who can call it: owners and admins.

InputRequiredWhat it is
nameyesThe short name, unique among the organization’s datasets, metrics and views. An existing metric’s name proposes its next version.
labelyesThe human name, up to 80 characters.
descriptionyesWhat it means in the person’s words, up to 500 characters.
datasetyesThe dataset it’s counted from.
measureyes{ fn, column } with fn one of count (no column counts rows), count_distinct, sum, avg, min, max; or { fn: "ratio", numerator, denominator }, each side a measure with its own optional filters.
filtersnoUp to 20, always applied, in dataset_query’s where shape.
timeno{ column, grains, default }: a date column, the periods it can be asked by (day, week, month, quarter, year) and the default.
dimensionsnoUp to 20 things it can be split or filtered by: a column name, or { column, bands: { edges, labels, blank_label } } to split a number column into ranges.
includenoUp to 3 datasets it points at, { parent, via, as }, whose columns it may name.
notenoWhy it’s being set up or changed.

Answers with metric_version, status, sentence (the read-back to show the person word for word), reads, how_to_ask, filter_checks (how many rows each filter matches now), warnings and definition.

metric_approve

Makes a waiting metric version the one in force, after the person says yes to its sentence in the conversation. It’s checked again first. Approving a new version of a retired metric brings it back.

Who can call it: owners and admins.

InputRequiredWhat it is
metricyesThe metric’s name.
metric_versionyesThe version the person was shown.
confirmed_by_personyesMust be true.

Answers with decision, decided_by, decided_at, metric_version_in_force, sentence and reads.

metric_reject

Discards a waiting metric version because the person said no. The version in force, if any, stays.

Who can call it: owners and admins.

InputRequiredWhat it is
metricyesThe metric’s name.
metric_versionyesThe version to reject.
reasonnoWhy, in the person’s words. It’s kept with the version.

Answers with decision and metric_version_in_force.

metric_list

The organization’s metrics.

Who can call it: any member.

InputRequiredWhat it is
include_retirednotrue also lists retired metrics, with why they were retired.

Answers with each metric’s name, label, dataset, status (waiting_for_approval, needs_new_proposal, ready, change_waiting_for_approval or retired), metric_version, waiting_metric_version and sentence.

metric_get

One metric: its sentence, definition, what it reads, how to ask it, and its versions.

Who can call it: any member.

InputRequiredWhat it is
metricyesThe metric’s name.
metric_versionnoAn earlier version to show. Default: the one in force.

Answers with sentence, definition, reads, how_to_ask (the periods, the default, what it can be split and filtered by, and every band label), retired when it is, last_rejected while the newest version is a rejected one, and history.

metric_query

Asks a metric for its number. See Asking questions.

Who can call it: any member.

InputRequiredWhat it is
metricyesThe metric’s name.
metric_versionnoAn earlier approved version. Default: the one in force.
grainnoday, week, month, quarter or year (one of the metric’s), or total for one number. Default: the metric’s default.
bynoUp to 4 of the metric’s dimensions to split by.
wherenoExtra filters, on its dimensions or its date column only.
periodno{ from, to }, both included. A date-only to includes that whole day.
data_versionnoAn earlier data version of the metric’s dataset.
limitnoRows to return: default 100, at most 1,000.

Answers with the metric envelope, plus label, sentence, grain, period, group_by, rows_matching, groups, rows_returned, truncated, fields, rows and a message.

Saved views

view_save

Saves a view over approved metrics, or replaces the view with that name. It’s checked against the metrics in force. See Metrics and saved views.

Who can call it: owners and admins.

InputRequiredWhat it is
nameyesThe view’s short name, unique among the organization’s datasets, metrics and views.
descriptionyesWhat it answers, in the person’s words (up to 500 characters).
metricsyes1 to 10 approved metrics, each at most once, each { metric, by, where } as in metric_query.
timeno{ grain, period }: the period every metric is counted by (day, week, month, quarter, year or total) and an optional fixed range.
parametersnoUp to 5 values filled in when it’s asked: { name, kind: "period" } for one period at the view’s grain, or { name, kind: "equals", binds_to: { column, metrics } } for a value a column must equal.

Answers with saved (created or replaced), sentence, metrics (each with its metric_version and sentence), parameters (each with what it means), how_to_ask and a message.

view_list

The organization’s saved views.

Who can call it: any member.

This tool takes no inputs.

Answers with each view’s name, description, status (ready, some_metrics_retired or no_metric_can_be_asked), its metrics with the version in force, its parameter names, and who saved it and when.

view_get

One saved view: what it asks, its metrics now, and how to ask it.

Who can call it: any member.

InputRequiredWhat it is
viewyesThe view’s name.

Answers with sentence, status, metrics (each with status, metric_version, saved_with_metric_version, by and where), time, parameters and how_to_ask (the exact view_query call, with an example value for each parameter).

view_query

Answers a saved view by name. Every metric is answered exactly as metric_query answers it, at the version in force now.

Who can call it: any member.

InputRequiredWhat it is
viewyesThe view’s name.
parametersif the view has anyA value for each parameter, by name: { "month": "2026-09" }. A period is written as its grain: 2026-03-15, any day of a week, 2026-03, 2026-Q1 or 2026.
limitnoRows per metric: default 100, at most 1,000.

Answers with the view envelope: view, parameters, period, metrics, answers, not_answered, read_from, plus description, sentence and a message.

view_delete

Deletes a saved view. Its metrics and their data aren’t touched, and the name becomes free.

Who can call it: owners and admins.

InputRequiredWhat it is
viewyesThe view’s name.

Answers with deleted: true and a message.


Connection check

ping

Checks that the connection works.

Who can call it: anyone connected.

InputRequiredWhat it is
messagenoText to echo back.

Answers with ok, a timestamp and echo (the message, when one was sent).