# Data & reporting Turn business records and source files into useful answers, with a clear route back to the evidence. Source: https://docs.opser.com/capabilities/data/ ## Work with structured information Ask the agent to find, compare, summarize, or update data in the apps you can access. Identify the app and useful filters such as date range, owner, customer, or status. > In Sales, summarize confirmed orders due next month by customer and currency. Include order links and flag orders without a delivery date. For data outside an installed app, the platform’s data capability can work with structured entities and records. When you need a reusable user interface around that information, consider an [internal app](https://docs.opser.com/capabilities/internal-apps/). ## App-owned records and user-managed datasets Apps own their tables and business rules. Use their supported tools or exposed operations for those records. The platform data tool manages user-owned business datasets separately: entities, fields, relationships, records, and their access settings. The agent can inspect an existing dataset, define a structure, import records, and query it for analysis. Supported SQL reporting is read-only and scoped to the permitted business data. It is not an unrestricted query interface into private app or platform tables. ## Build a report Specify the audience, date range, grouping, and output format. Ask for source references or record links so you can check the result. Keep currencies and units explicit. 1. Confirm which records are included and excluded. 2. Check the grouping and calculation rules. 3. Inspect a sample of the underlying records. 4. Choose a useful output: a conversation summary, spreadsheet, presentation, or dashboard. Missing data should be visible in the result. Ask the agent to flag uncertainty instead of filling gaps with assumptions. ## Make changes carefully Separate exploratory analysis from bulk updates. Ask for a preview that identifies the affected records, then review it before authorizing the change. Permissions and tool-specific approval rules still apply. > Show me the contacts with missing company names. Suggest matches using their email domains, but wait for my review before saving changes. ## Repeatable reporting Use a [skill](https://docs.opser.com/agents/skills/) to keep a report format consistent, and a [schedule](https://docs.opser.com/agents/automations/) to run it regularly. For a continuously useful workspace view, see [Dashboards](https://docs.opser.com/capabilities/dashboards/). ## Discover tables and columns without truncated results The agent's `data.describe_schema` action returns a table inventory in pages of 25 (up to 50). Use `search` to narrow table names, then follow `next_input` until it is null. Specify `entityId` to inspect the exact column names in one table; those fields are paged too. This avoids guessing names such as `sort_order` when the real column is `position`. Discovery keeps the person's and agent's existing app/data access checks. Dashboard's `list_data` action has the same `limit`, `offset`, `search` and `next_input` workflow. Exact row counts require `include_record_count: true` (`includeRecordCount` on the data tool); ordinary discovery skips those counts. These are tool controls, not changes to the Settings → Data browser. ## SQL reporting boundaries `raw_sql` accepts one read-only SELECT or WITH query, including literal labels, UNION/UNION ALL, DISTINCT, aggregates and approved casts. Results are capped at 500 rows and the database query has a 15-second deadline. Only business tables the person and requesting agent may read are eligible. Reporting does not change app records or grant access to platform/private tables. Text projections include `strpos`, `position`, `regexp_matches`, `regexp_replace`, `lower`, `substring` and `split_part`. JSON inspection includes `jsonb_object_keys`, `json_object_keys`, JSON extraction and JSON array length. Use key-expansion functions in SELECT; function sources in FROM and schema-qualified calls remain unsupported. An unsupported function error lists the allowed functions. Arbitrary functions and unsafe casts remain rejected. For exact-person research, prefer parameterized word-boundary regexes over broad substring searches: for example, `regexp_matches(note, ?, 'i')` with `params: ["\\mPier\\M"]`. Inspect the schema first, select only needed columns, and use a small limit. A substring such as `mark` can also occur in `marketing`; SQL support does not automatically decide whether a mention identifies the intended person.