- Brand
- Datarails
- Category
- Finance
- Primary Subcategory
- Financial Planning & FP&A Analytics
Integration details
Description
Datarails FinanceOS brings structure and intelligence to your financial data. It provides a managed, organized database that keeps your numbers clean and reliable. Every change is fully traced with a built-in audit trail, so you always know who changed what and when. A robust permission mechanism ensures each user sees only the data they're authorized to access. And with built-in financial logic, the app understands your business context out of the box - no manual setup required.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Financial Planning & FP&A Analytics
- Secondary Subcategories
- None listed
- Brand
- Datarails
- Access
- Account required
- First tracked
- 2026-05-20
- Tool count
- 31
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Datarails FinanceOS
Get updates when Datarails FinanceOS’s Discoverability Score or category rank changes.
Competing in ChatGPT Financial Planning & FP&A Analytics
View Category31 tools agents can invoke
Fetch (or poll for) the result of a start_aggregation_by_alias job. Single non-blocking check. Given the handle from start_aggregation_by_alias, returns either the aggregated rows (exactly one row per requested group, plus grand totals in metadata.totals — exact even when truncated, for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE) or {"status": "running", "handle": {...}, "retry_after_seconds": N} — call again with the SAME handle after ~N seconds. Args: handle: The handle from start_aggregation_by_alias (request_token + alias). Pass it back unchanged. Unknown/expired handle returns an error — restart with start_aggregation_by_alias. Note: large results are capped to a response-size limit. If capped, the result comes back as {"data": ..., "truncated": true, "total_rows": N, "returned_rows": M, "guidance": ...} instead of the bare rows — narrow the query (fewer columns/dimensions, add filters, or use a business metric for a named KPI) and call again to get the rows you need. On aggregation tools metadata.totals, when present, is unaffected by truncation — exact for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE (see the aggregation tool descriptions).
get_aggregation_result_by_alias
Fetch (or poll for) the result of a start_aggregation_by_id job. Does a single check — it does not block. Given the handle from start_aggregation_by_id, it returns one of: * the aggregated rows (job complete) — exactly one row per requested group, plus grand totals in metadata.totals (exact even when the rows are truncated — for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE), OR * {"status": "running", "handle": {...}, "retry_after_seconds": N} — still processing; call this tool again with the SAME handle after ~N seconds. Args: handle: The handle object returned by start_aggregation_by_id (contains request_token and table_id). Pass it back unchanged. If the handle is unknown or expired, an error is returned — restart with start_aggregation_by_id. Note: large results are capped to a response-size limit. If capped, the result comes back as {"data": ..., "truncated": true, "total_rows": N, "returned_rows": M, "guidance": ...} instead of the bare rows — narrow the query (fewer columns/dimensions, add filters, or use a business metric for a named KPI) and call again to get the rows you need. On aggregation tools metadata.totals, when present, is unaffected by truncation — exact for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE (see the aggregation tool descriptions).
get_aggregation_result_by_id
Get server-computed metric time-series data. NO MANUAL AGGREGATION NEEDED. This is the preferred way to get KPI values over time. The server computes the metric (including CALC ratios like Debt to Assets) and returns time-series data — eliminating the need for Claude to manually aggregate and calculate. Args: metric_ids: List of metric IDs (from list_business_metrics). Supports multiple metrics in one call. scenario: Optional list of scenario values (e.g., ["Actuals"] or ["Budget", "Forecast"]). Omit to include all scenarios. scenario_cycle: Optional list of planning cycle (version) values within Budget/Forecast scenarios. When scenario_cycle, planning_scenario and scenario_details are all omitted, the org's default cycles apply (see get_organization_context) unless the metric itself references a cycle field; with no defaults, all cycles aggregate. Only meaningful with scenario including "Budget" or "Forecast". planning_scenario: Optional list of planning scenario values. Omit to include all planning scenarios. scenario_details: Optional list of scenario detail values. Omit to include all scenario details. aggregation_period: "day" | "month" | "quarter" | "year" (default: month). Skip grains listed in the metric's unsupported_grains — they return a per-metric error result (code INVALID_PARAMS), not data. aggregation_type: "DEFAULT" | "MTD" | "QTD" | "YTD" | "MTG" | "QTG" | "YTG" date_start: Optional start date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) date_end: Optional end date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) dimension_filters: Optional dict like {"Department": ["Sales"]}. Keys must be dimensions assigned to EVERY requested metric — use each metric's dimensions[] from list_business_metrics; a key not assigned to a metric fails the call with INVALID_PARAMS. Returns list of {date, amount} points per metric. An empty series for a metric (status:"success", data:[]) usually means an errored/unmapped source or a range that matched zero rows. Each result also carries metric_uses_dynamic_time_units and metric_unsupported_grains. Dynamic metrics resolve against the requested window — re-query for a different period/grain instead of re-slicing values you already have. For best results call list_business_metrics first and skip metrics whose status_info sets error_message or source_warning.
get_business_metric_data
Get full detail for a specific business metric including calculation config. Args: metric_id: The metric ID (from list_business_metrics) Returns: - template_id: which table the metric reads from - aggregator: how values are combined (SUM, AVG, etc.) - date_field_id, value_field_id: which fields to aggregate - base_metrics: for CALC metrics, the component metric IDs - configuration: formula details (for calculated metrics like ratios). Scenario-bound formulas are only in list_business_metrics calculations[].
get_business_metric_details
Drill into a business metric — return the source rows behind its values, with per-field metadata. Args: metric_ids: List of metric IDs (max 50) dimension_filters: Optional pre-filter ({dimension_name: [values]}). Keys must be dimensions assigned to every requested metric (dimensions[] in list_business_metrics). date_start: Optional start date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) date_end: Optional end date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) Notes: - BASE metrics: returns drill-down rows for that metric's underlying records. - CALC metrics: returns drill-downs for each component base metric (e.g. drilling into "Gross Profit" yields drill-downs for "Revenue" and "COGS"). A CALC that reads a driver also gets an entry per driver and scenario it is read in, labelled scenario / scenario_cycle / planning_scenario: two entries of one driver name differ by these. - Slow — can take 30+ seconds per metric. - The raw payload can be very large; request narrow metric_ids and date ranges. Empty data for a metric usually means it is errored (check its status_info.error_message / status_info.source_warning).
get_business_metric_drilled_down_data
Stream the source rows that back a single business metric — the underlying detail or aggregated rows used to compute it. Returns a flat array of row objects for ONE metric (not the standard success/data envelope). Narrow the rows with scenario, dimension_filters, and a date range. Args: metric_id: The metric ID (from list_business_metrics). One metric. scenario: Optional list of scenario names to filter on (e.g. ["Actuals"] or ["Budget", "Forecast"]). Omit for the default scenario. dimension_filters: Optional {dimension_name: [values]} — values are OR'd within a dimension and AND'd across dimensions; keys must match a dimension declared on the metric (dimensions[] in list_business_metrics) — an unassigned key is rejected with INVALID_PARAMS. date_start: Optional inclusive lower-bound date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) date_end: Optional inclusive upper-bound date "YYYY-MM-DD", or a Unix timestamp as a string in seconds or milliseconds ("1767225600" = 2026-01-01, UTC) aggregation_period: "day" | "month" | "quarter" | "year" (default: day). CALC metrics only — BASE metrics always return raw detail rows and ignore this. aggregation_type: "DEFAULT" | "MTD" | "QTD" | "YTD" | "MTG" | "QTG" | "YTG" (default: DEFAULT). CALC metrics only; ignored for BASE metrics. Result sets can be large — narrow with date ranges and filters. Note: large results are capped to a response-size limit. If capped, the result comes back as {"data": ..., "truncated": true, "total_rows": N, "returned_rows": M, "guidance": ...} instead of the bare rows — narrow the query (fewer columns/dimensions, add filters, or use a business metric for a named KPI) and call again to get the rows you need. On aggregation tools metadata.totals, when present, is unaffected by truncation — exact for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE (see the aggregation tool descriptions).
get_business_metric_table_rows
Get the content of company-profile sections by name. Args: section_names: The sections to fetch. Each entry may be a section id (primaryIndustry) or a section title (Primary Industry), matched case-insensitively — one entry per section, either form works. Call list_company_profile_sections first to discover the valid names. Returns the matched sections (id, category, title, question, content, updated_at) plus not_found with any names that matched nothing — on a not_found, re-check the list tool rather than retrying guessed variations. An organization without a profile yields no sections and every requested name in not_found.
get_company_profile_sections
Report whether this Datarails connector is enabled for your organization. Always available; call this if other tools are missing or a Datarails action fails with connector_not_enabled.
get_connector_status
FX rates snapshot (USD base). Single point in time, no history. Thin wrapper over `/foreign_exchange/v1/currency-rates`. The backend returns the most-recent rate set the org has loaded — there is no period/date parameter. The response includes a `date` field indicating when the snapshot was captured; the snapshot may lag wall-clock time depending on how the org keeps its rate table up to date. Currency coverage varies by org (the rate set only includes currencies the org has actually loaded — not a fixed global list). Inspect the response before assuming a given ISO code is present. For historical or period-specific FX, this endpoint is not suitable.
get_currency_rates
Get rows from an aliased table (addressed by alias) with optional column selection. KEY ADVANTAGE: Use `select` to return ONLY the columns you need. A typical table has 228 columns — selecting 5 reduces tokens by ~95%. Args: alias: Table alias (e.g., 'ap', 'bank_transactions') select: List of field aliases to return (e.g., ['amount', 'payment_status']). If None, returns all columns (not recommended). filters: Optional list of {name, values, is_excluded?} objects addressed by field alias, where values takes one of two forms: * Value list — match any of the listed values (set membership / IN). Values are strings — pass numbers/dates as strings (e.g. ["2025"], not [2025]): {"name": "payment_status", "values": ["Paid", "Pending"]} Set is_excluded: true to exclude the listed values (NOT IN). * Advanced — a condition tree for comparisons, ranges, and text matching: {"name": "amount", "values": {"type": "advanced", "val": [ {"condition": "gte", "value": "1000"}, {"condition": "lt", "value": "5000", "operator": "and"} ]}} Each val entry is {condition, value, operator?}: - condition: equals, dn_equals (does not equal), contains, dn_contains, bw (begins with), ew (ends with), gt, gte, lt, lte, in, range (exclusive between), total_range (inclusive between), is null. Use these exact tokens (e.g. lte, not less_than_or_equals). - value: a string for scalar conditions; a list of strings for in; a two-item [from, to] list of strings for range and total_range. Numbers and dates are passed as strings. A date must be Unix epoch SECONDS, never a calendar date — "1767225600", not "2026-01-01"; a calendar date is rejected on gt, gte, lt, lte, range, and total_range. For is null, set value to "" (it is ignored downstream). - operator: how this condition chains with the previous one, 'and' (default) or 'or' to start an alternative branch. Comparison and range conditions (gt, gte, lt, lte, range, total_range) require a numeric or date field — on text fields they fail. is_excluded applies to value lists only, not advanced filters. limit: Max rows (default 100, max 500) offset: Rows to skip for pagination (default 0) ALWAYS use `select` to minimize token usage. Use field aliases (from list_aliased_fields), not raw field names. Note: large results are capped to a response-size limit. If capped, the result comes back as {"data": ..., "truncated": true, "total_rows": N, "returned_rows": M, "guidance": ...} instead of the bare rows — narrow the query (fewer columns/dimensions, add filters, or use a business metric for a named KPI) and call again to get the rows you need. On aggregation tools metadata.totals, when present, is unaffected by truncation — exact for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE (see the aggregation tool descriptions).
get_data_by_alias
Get rows from a table (addressed by id) with optional column selection. Fetches raw rows — use for row-level inspection or when the user wants specific records. For totals/grouped breakdowns use get_aggregated_data_by_id (no fixed row cap); for named KPIs check list_business_metrics first. Args: table_id: The id of the table (from list_data_models). select: List of field ids to return (e.g. [101, 103], from get_fields_by_id). Raw tables are wide (~200 columns); project to the few you need. Omit to return all columns (not recommended). filters: Optional list of {field_id, values, is_excluded?} objects, addressed by numeric field id (from get_fields_by_id), where values takes one of two forms: * Value list — match any of the listed values (set membership / IN). Values are strings — pass numbers/dates as strings (e.g. ["2025"], not [2025]): {"field_id": 104, "values": ["Actuals", "Budget"]} Set is_excluded: true to exclude the listed values (NOT IN). * Advanced — a condition tree for comparisons, ranges, and text matching: {"field_id": 105, "values": {"type": "advanced", "val": [ {"condition": "gte", "value": "1000"}, {"condition": "lt", "value": "5000", "operator": "and"} ]}} Each val entry is {condition, value, operator?}: - condition: equals, dn_equals (does not equal), contains, dn_contains, bw (begins with), ew (ends with), gt, gte, lt, lte, in, range (exclusive between), total_range (inclusive between), is null. Use these exact tokens (e.g. lte, not less_than_or_equals). - value: a string for scalar conditions; a list of strings for in; a two-item [from, to] list of strings for range and total_range. Numbers and dates are passed as strings. A date must be Unix epoch SECONDS, never a calendar date — "1767225600", not "2026-01-01"; a calendar date is rejected on gt, gte, lt, lte, range, and total_range. For is null, set value to "" (it is ignored downstream). - operator: how this condition chains with the previous one, 'and' (default) or 'or' to start an alternative branch. Comparison and range conditions (gt, gte, lt, lte, range, total_range) require a numeric or date field — on text fields they fail. is_excluded applies to value lists only, not advanced filters. limit: Max rows (default 100, max 500). offset: Rows to skip for pagination (default 0). Note: large results are capped to a response-size limit. If capped, the result comes back as {"data": ..., "truncated": true, "total_rows": N, "returned_rows": M, "guidance": ...} instead of the bare rows — narrow the query (fewer columns/dimensions, add filters, or use a business metric for a named KPI) and call again to get the rows you need. On aggregation tools metadata.totals, when present, is unaffected by truncation — exact for SUM, COUNT, MIN, MAX, and UNIQUE_VALUES; NOT for AVG or COUNT_UNIQUE (see the aggregation tool descriptions).
get_data_by_id
Fetch (or poll for) the result of a start_distinct_values_by_alias job. Single non-blocking check. Given the handle from start_distinct_values_by_alias, returns either the sorted list of distinct values or {"status": "running", "handle": {...}, "retry_after_seconds": N} — call again with the SAME handle after ~N seconds. Args: handle: The handle from start_distinct_values_by_alias (request_token, alias, field_alias). Pass it back unchanged. limit: Max number of values to return (default 100).
get_distinct_values_result_by_alias
Fetch (or poll for) the result of a start_distinct_values_by_id job. Single non-blocking check. Given the handle from start_distinct_values_by_id, returns either the sorted list of distinct values or {"status": "running", "handle": {...}, "retry_after_seconds": N} — call again with the SAME handle after ~N seconds. Args: handle: The handle from start_distinct_values_by_id (request_token, table_id, field_id). Pass it back unchanged. limit: Max number of values to return (default 100).
get_distinct_values_result_by_id
Get the fields (columns) of a table, addressed by id. Args: table_id: The id of the table (from list_data_models). Returns the table's name and alias plus, for each field: id (numeric field id, used by the by-id tools), alias (business-friendly name, empty if none), name, type, and description.
get_fields_by_id
Get the user's organization settings that decide how its numbers read: name, fiscal year, default and available reporting currencies, and the default budget and forecast scenarios. Metric tools apply those defaults when you pass no scenario_cycle, planning_scenario or scenario_details filter and the metric does not itself reference a cycle field; a scenario filter alone keeps them. Call this once, before you answer a question about budget, forecast, fiscal periods or currency, unless the organization context is already in your instructions. Returns block (markdown), or null when the settings could not be read.
get_organization_context
Get users in the organization with roles and departments. Default returns ~9 KB (50 users) flattened to: - id, first_name, last_name, email, is_active - role (ADMIN, CONTRIBUTOR, VIEWER, SUPER_ADMIN) - department (FINANCE_FPA, SALES, R&D, etc.) - job_role (VP, DIRECTOR, BOARD_MEMBER, etc.) Useful for understanding org structure and tailoring responses. Args: include_full: When True, returns the raw envelope (~60 KB) including permission_groups, telemetry, badge info.
get_org_users
IMPORTANT: This tool MUST be called at the START of every new conversation, before any other tool. It returns the catalog of all available skills, agents, and workflows on this server. Use the catalog to understand what capabilities are available. When a user's request matches a skill, call `load_skills_and_md_files` with the skill's path to retrieve the full instructions for executing it. Returns JSON with: - skills: list of available skills with their paths and metadata - directory_tree: the full plugin content directory structure
get_plugin_catalog
Get guided workflows for common financial analysis tasks. Call without arguments to see all available workflows. Call with a workflow name to get step-by-step guidance. Use this tool when: - A user is new and wants to know what they can do - A user asks for help or says "what can you do?" - You need guidance on which tools to use for a specific task - A user wants a financial summary, expense analysis, revenue trends, etc. Args: workflow_name: Optional. One of: getting-started, financial-summary, expense-analysis, revenue-trends, budget-comparison, data-quality, explore-data, api-test
get_workflow_guide
List the fields of an aliased table, with aliases and descriptions. Args: alias: Table alias (e.g., 'financials', 'ap', 'trial_balance') Returns field information including: - alias: business-friendly name for the field - name: original raw field name - type: data type - description: what this field means in business context PREFER this over get_fields_by_id when an alias is available — it gives business context.
list_aliased_fields
Start here for any named-KPI question (revenue, margin, expenses, budget variance, headcount, ratios). Returns the org's defined metrics with business context, status, dimensions, and formulas — so you can pick the right metric and call `get_business_metric_data` instead of manually aggregating raw tables. Returns a flat list. Each metric contains: - id, name, description, category, kind (USER/BASE/CALC/DRIVER) - time_aggregation (how the metric rolls up over time), format - dimensions[]: which fields the metric can be sliced by - uses_dynamic_time_units: true = dynamic metric — its values depend on the window/grain they are queried with, so numbers from one query cannot be re-sliced for another period - unsupported_grains[]: aggregation periods the metric rejects (e.g. ["day"]) — avoid them as aggregation_period in get_business_metric_data - status_info: { status, source_warning?, error_message?, last_updated } - formula: the CALC formula; calculations[]: extra CALC formulas, each bound to a scenario context (scenario, scenario_cycle, cycle_year, planning_scenario) — the most specific match wins, else `formula`. cycle_year is the fiscal year of scenario_cycle: a cycle name repeats every year, and each year of it has its own calculation Use `status_info` to triage: a non-empty `error_message` flags a broken metric, and a `source_warning` flags source tables that aren't configured/mapped or only partially loaded (so get_business_metric_data may return 0 rows or incomplete data). Note: `status_info` is a triage hint, not a contract with the data endpoint. Some metrics with an `error_message` still return values from `get_business_metric_data`, and some clean ones come back empty — verify by calling `get_business_metric_data` when in doubt. Best starting point for understanding what KPIs the org tracks.
list_business_metrics
List the sections of the user's company profile — a questionnaire-built dossier on their company (industry, products and services, market, financial model, ...). Returns profile_status (notStarted, inProgress, or done) and, per section: id, category, title, and has_content. Content is NOT returned — use this for discovery, then fetch the sections you need with get_company_profile_sections. An empty list means no profile has been built for the organization yet.
list_company_profile_sections
List all data models (tables) available to the caller — with or without an alias. For named-KPI questions (revenue, margin, expenses, budget variance, headcount, ratios), prefer `list_business_metrics` first — the metric catalog typically answers them directly. Use this tool for raw-data exploration or when no metric covers the question. Each entry carries both identities: the numeric id used by the by-id (raw) endpoints and the alias used by the by-alias endpoints (empty when a table has no alias). Tables with an alias also offer human-readable field aliases and descriptions — prefer the by-alias tools for those. Args: name: Optional table name (case-insensitive exact match) for a cheap single-table lookup. Empty array if nothing matches. alias: Optional alias (e.g., "financials", "ap") — same filter, matched against the table's alias. has_alias: Optional — true returns only tables that have an alias. Without filters, returns every table. Pair with get_fields_by_id(id) or list_aliased_fields(alias) for the field list.
list_data_models
List filebox items (folders, files, templates, lookup tables) in the org. Useful for discovering org-level content structure — top-level folders like "Actuals", "Reports", "Configuration", "Analysis". Each item has a `parent` (parent id or null), so the tree can be reconstructed. Args: include_full: When True, also returns permissions[], tags_config, bucket — about 8× larger (~280 KB). Default trim returns ~36 KB (199 items: id, parent, name, is_folder, scenario, use_type, is_process_root).
list_filebox
List the XL functions visible to the calling user. XL functions are the named aggregations that Excel DR.GET formulas reference as their first argument: `=DR.GET(<FunctionName>, "[Dimension]", CellRef, ...)`. Never guess or hardcode a function name — always discover it here. **Paged.** Returns an object, not a bare list: `{total_count, page, page_size, total_pages, functions}`. `total_count` counts every function matching the filters across all pages; this page holds `len(functions)` of them, which can be fewer than `page_size` on the last page, or if an oversized page had to be trimmed to fit the response limit (then `truncated: true` and `returned_rows` are present — lower `page_size` and retry, because the dropped entries are on no other page). Follow `total_pages` to read the whole catalog. When you already know the table, prefer `template_id` over paging through everything. Each entry in `functions` carries: - `name`: the exact token to use as DR.GET's first argument - `template`: the owning table `{id, name}` — pass `template.id` to `get_fields_by_id` to learn which dimension fields are valid in the formula's `"[Dimension]"` pairs, or back into this tool as `template_id` to list only that table's functions - `vals` / `aggfun`: the value field(s) being aggregated and how - `filters`: the function's filter rows (each `{field, name, values, is_excluded, ...}`; empty when unfiltered) — the data slice the function computes over. This is what distinguishes two functions on the same table (e.g. "Total Revenue" vs "Total OPEX"), so read it before choosing between similarly shaped functions. Legacy rows may carry `values` as a raw string instead of a list. - `default_agg_datefield`: `{id, name}` of the date field used for default time aggregation (`null` when unset; older platform versions return a bare id instead) Validate dimension values with `get_distinct_values_by_id` before writing them into a workbook. Args: include_archived: Include archived functions (default False — archived functions can't be used in new formulas). include_full: Return raw records including authorship metadata (default False trims `last_edited_by`). template_id: Only list functions owned by this table template id (from an entry's `template.id`, or `list_data_models`) — the id as either a number or a string. Unset lists every table's. page: 1-based page number (default 1). A page past the end returns an empty `functions` list, not page one. page_size: Functions per page (default 20, maximum 100).
list_xl_functions
Load skill and workflow instructions by their relative paths. Call this tool immediately whenever the user's request matches a skill from the plugin catalog. Do not wait for the user to ask for it — as soon as you identify the right skill, load it and follow its instructions. The loaded content contains step-by-step execution guides that tell you which tools to call and in what order. Args: paths: List of relative paths from the plugin root directory. Example: ["skills/intelligence/SKILL.md", "agents/finance-analyst.md", "CLAUDE.md"] Returns JSON mapping each requested path to its full text content, or null if the file was not found.
load_skills_and_md_files
Distinct-value sample per categorical field. Capped at 5 fields. Thin wrapper that calls `/tables/v1/{id}/fields/by-name/{field}/distinct` in parallel for up to 5 fields. Returns `{field: {distinct_count, sample_values}}` where `sample_values` is capped at the first 10 distinct values. Does NOT compute: per-value frequency counts, null counts/percentages, uniqueness ratios. Fields beyond the 5-field cap are silently dropped — pass an explicit `fields` list if you need a specific selection. For frequency analysis, call `get_aggregated_data_by_id` with the field as a dimension and `COUNT` as the metric. Args: table_id: The ID of the table to profile fields: Optional list of specific fields. If None, the first 5 fields the backend classifies as categorical are profiled.
profile_categorical_fields
Basic numeric stats: SUM, AVG, MIN, MAX, COUNT per field. Thin wrapper over `/tables/v1/{id}/aggregate`. Returns the backend's native aggregate response shape (column-oriented `DR_Values` / `col_keys` / `row_keys` layout); aggregator names are encoded in the column keys rather than as named result fields. Does NOT compute: median, standard deviation, outliers, percentiles, null counts. For richer distributional analysis use the `datarails-financeos:profile` skill (Claude only) or call this tool and post-process the rows. Args: table_id: The ID of the table to profile fields: Optional list of specific fields to profile. If None, all fields the backend classifies as numeric are profiled.
profile_numeric_fields
Start a server-computed aggregation over an aliased table WITHOUT blocking. The by-alias twin of start_aggregation_by_id. Use instead of get_aggregated_data_by_alias for large aggregations. Kicks off the job and returns a handle immediately; it does NOT return data. Args: alias: Table alias (e.g. 'ap', 'bank_transactions', 'trial_balance'). dimensions: List of field aliases to group by. metrics: List of {field, agg} specs, e.g. [{"field": "amount", "agg": "SUM"}]. agg is one of: SUM, COUNT, COUNT_UNIQUE, UNIQUE_VALUES, AVG, MIN, MAX (exact tokens — e.g. COUNT_UNIQUE, not COUNT_DISTINCT). Multiple metrics are supported — each is returned as its own column per group. Use at most one aggregation per field per call: requesting two aggregations of the same field (e.g. SUM and COUNT of one field) is rejected — make a separate call for each. A field may not be both a dimension and a metric — listing the same field in dimensions and in metrics is rejected; group by it or aggregate it, not both. SUM and AVG are rejected on a text field (Text/BigText) — use COUNT, COUNT_UNIQUE, UNIQUE_VALUES, MIN, or MAX on text fields instead. filters: Optional list of {name, values, is_excluded?} objects addressed by field alias, where values takes one of two forms: * Value list — match any of the listed values (set membership / IN). Values are strings — pass numbers/dates as strings (e.g. ["2025"], not [2025]): {"name": "scenario", "values": ["Actuals", "Budget"]} Set is_excluded: true to exclude the listed values (NOT IN). * Advanced — a condition tree for comparisons, ranges, and text matching: {"name": "amount", "values": {"type": "advanced", "val": [ {"condition": "gte", "value": "1000"}, {"condition": "lt", "value": "5000", "operator": "and"} ]}} Each val entry is {condition, value, operator?}: - condition: equals, dn_equals (does not equal), contains, dn_contains, bw (begins with), ew (ends with), gt, gte, lt, lte, in, range (exclusive between), total_range (inclusive between), is null. Use these exact tokens (e.g. lte, not less_than_or_equals). - value: a string for scalar conditions; a list of strings for in; a two-item [from, to] list of strings for range and total_range. Numbers and dates are passed as strings. A date must be Unix epoch SECONDS, never a calendar date — "1767225600", not "2026-01-01"; a calendar date is rejected on gt, gte, lt, lte, range, and total_range. For is null, set value to "" (it is ignored downstream). - operator: how this condition chains with the previous one, 'and' (default) or 'or' to start an alternative branch. Comparison and range conditions (gt, gte, lt, lte, range, total_range) require a numeric or date field — on text fields they fail. is_excluded applies to value lists only, not advanced filters. Returns {"status": "pending", "handle": {...}, "guidance": ...}. Pass the handle unchanged to get_aggregation_result_by_alias.
start_aggregation_by_alias
Start a server-computed aggregation over a table (by id) WITHOUT blocking. Use this instead of get_aggregated_data_by_id for large aggregations that would otherwise exceed the request timeout. It kicks off the job and returns immediately with a handle; it does NOT return data. Args: table_id: The id of the table to aggregate. dimensions: List of field ids to group by (e.g. [101, 102]). metrics: List of {field_id, agg} specs, e.g. [{"field_id": 103, "agg": "SUM"}]. agg is one of: SUM, COUNT, COUNT_UNIQUE, UNIQUE_VALUES, AVG, MIN, MAX (exact tokens — e.g. COUNT_UNIQUE, not COUNT_DISTINCT). Multiple metrics are supported — each is returned as its own column per group. Use at most one aggregation per field per call: requesting two aggregations of the same field (e.g. SUM and COUNT of one field) is rejected — make a separate call for each. A field may not be both a dimension and a metric — listing the same field in dimensions and in metrics is rejected; group by it or aggregate it, not both. SUM and AVG are rejected on a text field (Text/BigText) — use COUNT, COUNT_UNIQUE, UNIQUE_VALUES, MIN, or MAX on text fields instead. filters: Optional list of {field_id, values, is_excluded?} objects, where values takes one of two forms: * Value list — match any of the listed values (set membership / IN). Values are strings — pass numbers/dates as strings (e.g. ["2025"], not [2025]): {"field_id": 104, "values": ["Actuals", "Budget"]} Set is_excluded: true to exclude the listed values (NOT IN). * Advanced — a condition tree for comparisons, ranges, and text matching: {"field_id": 105, "values": {"type": "advanced", "val": [ {"condition": "gte", "value": "1000"}, {"condition": "lt", "value": "5000", "operator": "and"} ]}} Each val entry is {condition, value, operator?}: - condition: equals, dn_equals (does not equal), contains, dn_contains, bw (begins with), ew (ends with), gt, gte, lt, lte, in, range (exclusive between), total_range (inclusive between), is null. Use these exact tokens (e.g. lte, not less_than_or_equals). - value: a string for scalar conditions; a list of strings for in; a two-item [from, to] list of strings for range and total_range. Numbers and dates are passed as strings. A date must be Unix epoch SECONDS, never a calendar date — "1767225600", not "2026-01-01"; a calendar date is rejected on gt, gte, lt, lte, range, and total_range. For is null, set value to "" (it is ignored downstream). - operator: how this condition chains with the previous one, 'and' (default) or 'or' to start an alternative branch. Comparison and range conditions (gt, gte, lt, lte, range, total_range) require a numeric or date field — on text fields they fail. is_excluded applies to value lists only, not advanced filters. Returns {"status": "pending", "handle": {...}, "guidance": ...}. Pass the handle unchanged to get_aggregation_result_by_id, then poll until it returns the result.
start_aggregation_by_id
Start a distinct-values lookup for an aliased field WITHOUT blocking. The non-blocking twin of get_distinct_values_by_alias. Returns a handle immediately. Args: alias: Table alias. field_alias: Field alias (from list_aliased_fields). Returns {"status": "pending", "handle": {...}, "guidance": ...}. Pass the handle unchanged to get_distinct_values_result_by_alias.
start_distinct_values_by_alias
Start a distinct-values lookup for a table field (by id) WITHOUT blocking. The non-blocking twin of get_distinct_values_by_id. Kicks off the job and returns a handle immediately. Args: table_id: The id of the table (from list_data_models). field_id: The numeric field id (from get_fields_by_id). Returns {"status": "pending", "handle": {...}, "guidance": ...}. Pass the handle unchanged to get_distinct_values_result_by_id.
start_distinct_values_by_id
Datarails FinanceOS ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Datarails FinanceOS's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Datarails FinanceOS alternatives on ChatGPT?
As of 2026-11-03, Datarails FinanceOS competes with Aleph, Alvore Finance, Cash Flow Frog, CashflowPot, Centry Adviser Coordination, Centry Global Cashflow, Centry Global Estate Planner, Codon Valuation and 23 more in ChatGPT Financial Planning & FP&A Analytics, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.


