# Rollstack API The API reference at , in one file. - OpenAPI 3.1.0 document: - An index of the reference: Rollstack is the AI presentation platform for business reporting. Every Rollstack report is a slide deck built from your data, in your own template, and kept current. The API lets your own code, scripts and AI clients do what you do in the app: - Find and create reports, import your PowerPoint and Google Slides decks, and ask the slides agent to build and change slides, on brand. - Add data from any data source: - Data warehouses and lakehouses: Snowflake, Databricks, Google BigQuery, Amazon Redshift, Microsoft Fabric, Azure Synapse Analytics, Oracle Autonomous Data Warehouse, Teradata, ClickHouse, DuckDB and more - Semantic layers: dbt Semantic Layer, LookML, Snowflake semantic views, Databricks metric views, Cube, AtScale and more - BI tools: Power BI, Tableau, Qlik Sense, Looker, ThoughtSpot, Domo, Sigma, Metabase, Amazon QuickSight, Mode, Omni, Hex, Lightdash and more - CRMs and business applications: Salesforce, Dynamics 365, HubSpot, SAP, NetSuite, Workday, Zendesk, Gainsight, Google Analytics and more - Spreadsheets and files: Excel, Google Sheets, CSV, PDFs, Word, Google Docs, SharePoint, OneDrive, Google Drive, JSON and more - Any other application or database through its API - Refresh reports from their sources. A refresh reruns the same deterministic queries instead of regenerating the report, and uses AI only to repair the calculations and slides the new data broke. - Create a version of a report for each client, region, team or product line with Bursts. - Export reports to PowerPoint or PDF. - Share and schedule reports on any schedule, hourly to yearly or a cron, and email each stakeholder their own version. - Owners and admins can also manage the organization, its members and its data source connections. AI assistants such as Claude and ChatGPT can also use Rollstack through its MCP server, included on every plan. ## Getting started 1. In Rollstack, open **Settings → Connected apps → API keys** and create a key with the scopes you need. Copy it: it starts with `rsk_` and is shown only once. 2. Send it as a bearer token in the `Authorization` header of every request. 3. Call `GET /me` to check the key: it answers the user and organization it belongs to and the scopes it carries. ```bash curl https://api.rollstack.com/public/v1/me \ -H "Authorization: Bearer rsk_..." ``` ## Authentication An API key acts as the user who created it, in the one organization it was created in, and sees only what that user sees in the app. It never acts with more than the role its user had when they created it, and a key whose user is now a member loses the scopes only owners and admins may grant. Keys expire on the date set when they were created, if any. A user can revoke their keys in the app at any time, and deactivating a user revokes all of theirs. A missing, unknown, revoked or expired key answers 401. ## Scopes Most endpoints need one scope, shown on their pages, and answer 403 with `api-key-missing-scope` when the key doesn't carry it; `GET /me` works with any valid key. Give a key only the scopes it needs. Some endpoints are also limited to owners and admins whatever the scope. | Scope | Allows | Owners and admins only | | --- | --- | --- | | `organization:read` | Read the organization's settings and its LLM provider | | | `organization:write` | Change the organization's settings and its LLM provider | Yes | | `users:read` | List members and pending invites | Yes | | `users:write` | Change members' roles, deactivate and reactivate them, invite users and delete invites | Yes | | `connections:read` | List connections and their users, search their dashboards and the user's spreadsheets | | | `connections:write` | Create, update and delete connections, and manage their users and admins | | | `credentials:write` | Replace a connection's credentials | | | `smtp:read` | List SMTP connections | | | `smtp:write` | Add and delete SMTP connections | | | `slide_decks:read` | List folders and reports, read their content, datasheets, schedules, email settings, messages and runs, and export them | | | `slide_decks:write` | Create, update, delete, share and schedule reports, add their sources and upload files | | | `slide_decks:run` | Message the slides agent, and start and cancel runs | | | `slide_decks:email` | Set up and send report emails | | ## Requests and responses - Bodies are JSON, except the workbook, document or PowerPoint file a file upload can take as `multipart/form-data`. Fields an endpoint doesn't accept are rejected rather than ignored. - Dates are ISO 8601 strings in UTC. Ids are strings, except users', which are numbers. - `GET /reports` answers pages of up to `limit` reports: pass the `nextCursor` it answers as `cursor` for the next page, until it is null. Other lists answer every item at once. - Work that takes a while answers `202 Accepted` with an id right away: a message to the slides agent, a run, or a batch of variants added to a burst. Follow it with its `GET`, and the runs a burst starts with `GET /bursts/{id}/runs`: each waits up to `waitSeconds` (20 by default, 30 at most) for the work to finish and answers as soon as it does, so call it again while the status is `queued` or `running`. ## Errors Every error answers a JSON body with a stable, machine-readable `code` and a `message` for people, such as `{ "code": "api-key-missing-scope", "message": "This call needs the slide_decks:write scope, which this API key doesn't have. Use a key with it, or connect your AI client to Rollstack again and allow it." }`. | Status | Means | | --- | --- | | 400 | The request is invalid. `data-validation-error` says which fields failed and why | | 401 | The key is missing, unknown, revoked (`api-key-invalid`) or expired (`api-key-expired`), or its user left the organization (`api-key-organization-left`). The `WWW-Authenticate` header says where to sign in with OAuth | | 403 | The key lacks the endpoint's scope (`api-key-missing-scope`, with the scope in the `WWW-Authenticate` header), or the user isn't an owner or admin (`require-admin-permission`) | | 404 | The resource or path doesn't exist | | 409 | A request with the same `Idempotency-Key` is still running (`idempotency-key-in-progress`) | | 422 | The `Idempotency-Key` was already used for a different request (`idempotency-key-reused`) | | 428 | A call that emails people or deletes reports (`approveReportMessageProposal`, `startReportRun`, `sendReportEmail`, `startBurstRun`, `sendBurstEmailConfig`, `sendBurstVariantEmails`, `deleteBurst`, `removeBurstVariants`), made with an OAuth token or over MCP, waits for the user to confirm it in Rollstack (`confirmation-required`), at the link in the message | | 429 | Too many requests (`rate-limit-exceeded`): wait the seconds in the `Retry-After` header. A data query, datasheet change preview or save, or a slide render with datasheet changes, sent while another of yours still runs (`query-already-running`): they run one at a time, so wait the seconds in the `Retry-After` header, or until that one answers, then send it again | | 5xx | Something failed on our side: retry later | ## Idempotency A request that times out may have run or not. To retry a write safely, send an `Idempotency-Key` header with a unique value, such as a UUID, on any `POST`, `PUT`, `PATCH` or `DELETE`, and send the same value when you retry it. MCP write tools take the same value as their `idempotencyKey` argument. ```bash curl -X POST https://api.rollstack.com/public/v1/reports \ -H "Authorization: Bearer rsk_..." \ -H "Idempotency-Key: 6f1c2a4e-9b7d-4e2f-8a3c-1d5e7f9b0a2c" \ -H "Content-Type: application/json" \ -d '{"name": "Weekly sales"}' ``` - The first request with a key runs, and its response is kept for 24 hours. A retry with the same key and the same request answers that response, with its status, and runs nothing. - Keys belong to the API key and the endpoint, so another key or endpoint never sees them. A tool call and a REST request to the same endpoint share them. - A retry with the same key but a different body, path or query answers 422 `idempotency-key-reused`. Use a new key for a new request. - A retry while the first request is still running answers 409 `idempotency-key-in-progress`: retry it later with the same key. A request that stopped before it answered keeps answering 409 until its key expires, so check whether it took effect before you send it again with a new key. - A request that fails, such as with a 4xx or 5xx, keeps nothing, so retry it with the same key. - When keys can't be checked, a request with one answers 503 `idempotency-unavailable` and runs nothing. - Without the header, a request runs every time it is sent. `GET` requests ignore it. ## Rate limits Each API key may make 120 requests a minute. Calls that cost far more than a read have lower limits of their own, counted per user across all their keys and AI clients: | Calls | Limit | | --- | --- | | Messages to the slides agent | 6 a minute | | Exports and slide images | 10 a minute | | Imports of a deck from a link or a file, and conversions of older reports | 10 a minute | | Datasheet data reads | 30 a minute | | Report viewer slide and template cover loads (MCP) | 60 a minute | | Email sends, test sends included | 5 a minute | | LLM provider saves | 10 a minute for the organization | Responses report how much of the key's per-minute limit is left, so a client can slow down before it gets a 429: `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` (seconds until the minute resets) and `RateLimit-Policy`. The lower limits above aren't in these headers. Past any limit, calls answer 429 with a `Retry-After` header: wait that long before calling again, whatever `RateLimit-Remaining` says. An MCP tool call past any of these limits returns an error result instead, with the `rate-limit-exceeded` code and a message that says how long to wait. ## Versioning The version is in the path: `/public/v1`. Changes within v1 only add: new endpoints, new optional request fields, new response fields and new values in fields such as a status or an error `code`, so ignore fields you don't know and handle values you don't know. An endpoint or field that gets replaced keeps working, and its page says it is deprecated and what replaces it. A change that would break existing calls comes as a new version under a new path, with v1 still running alongside it. ### Deprecation and sunset A deprecated endpoint or field is marked `deprecated` in the OpenAPI document and on its page, and keeps working for as long as v1 does. When a new version replaces v1, v1 keeps running for at least 12 months after it ships. Through that time, v1 responses carry a `Deprecation` header with the date v1 was deprecated (RFC 9745) and a `Sunset` header with the date it stops answering (RFC 8594), and both dates are announced in the [product updates](https://docs.rollstack.com/changelog). ## MCP server AI clients such as Claude can also use this API as an MCP server: POST JSON-RPC to `/public/v1/mcp` over Streamable HTTP with the same bearer API key, or sign in with OAuth from a client that supports it. Its tools, named by operationId, find, build, edit, run, export, share, schedule and email reports, upload files and message the slides agent. It lists only the tools the key can call. Everything else, such as deleting reports or managing members or connections, is REST-only. ### Connect an AI assistant Use Rollstack when someone wants a slide deck or report built or kept up to date from their company's data, such as warehouses, BI dashboards and spreadsheets, in their own template, refreshed on a schedule or emailed. Add the MCP server, `https://api.rollstack.com/public/v1/mcp`, to the assistant and sign in with Rollstack: - **Claude** (claude.ai and the desktop app): in Connectors, add a custom connector with this URL, then Connect. On Team and Enterprise plans an owner adds it in the organization's settings first. - **ChatGPT**: Settings → Plugins → MCPs → Add → Add MCP server, with Streamable HTTP and this URL. Save, then Authenticate. On Business and Enterprise plans an admin allows custom servers first. - **Claude Code**: `claude mcp add --transport http rollstack https://api.rollstack.com/public/v1/mcp`, then `/mcp` to sign in. - **Cursor**: add `{ "mcpServers": { "rollstack": { "url": "https://api.rollstack.com/public/v1/mcp" } } }` to `~/.cursor/mcp.json`, then sign in when it asks. - **Other clients**: send an API key as a bearer token. Signing in asks the user to approve the scopes the assistant asked for. The assistant can then do what they approved, within their role: a member can't grant the scopes only owners and admins have. Each sign-in creates a key that lasts 90 days and that the assistant refreshes on its own, listed in [Settings → Connected apps](https://app.rollstack.com/settings/connected-apps) as a Connected app, where the user can revoke it. Things to ask it: - "Build a quarterly business review deck from our Tableau dashboards" - "Refresh the data in my weekly sales report and email it to the team" - "Create one deck per region from this template" - "Schedule the board report to update every Monday" | Tool | Scope | Owners and admins only | | --- | --- | --- | | `listReports` | `slide_decks:read` | | | `getReport` | `slide_decks:read` | | | `convertReport` | `slide_decks:write` | | | `createReport` | `slide_decks:write` | | | `duplicateReport` | `slide_decks:write` | | | `updateReport` | `slide_decks:write` | | | `listTemplates` | `slide_decks:read` | | | `showTemplates` | `slide_decks:read` | | | `getTemplatePickerCovers` | `slide_decks:read` | | | `createTemplate` | `slide_decks:write` | | | `updateTemplate` | `slide_decks:write` | | | `deleteTemplate` | `slide_decks:write` | | | `applyReportTemplate` | `slide_decks:write` | | | `listReportVersions` | `slide_decks:read` | | | `saveReportVersion` | `slide_decks:write` | | | `restoreReportVersion` | `slide_decks:write` | | | `getReportMessage` | `slide_decks:read` | | | `sendReportMessage` | `slide_decks:run` | | | `approveReportMessageProposal` | `slide_decks:run` | | | `cancelReportMessage` | `slide_decks:run` | | | `rejectReportMessageProposal` | `slide_decks:run` | | | `listMemories` | `slide_decks:read` | | | `createMemory` | `slide_decks:write` | | | `updateMemory` | `slide_decks:write` | | | `deleteMemory` | `slide_decks:write` | | | `listReportRuns` | `slide_decks:read` | | | `getReportRun` | `slide_decks:read` | | | `listReportSyncs` | `slide_decks:read` | | | `listRuns` | `slide_decks:read` | | | `startReportRun` | `slide_decks:run` | | | `cancelReportRun` | `slide_decks:run` | | | `getReportCloudExport` | `slide_decks:read` | | | `updateReportCloudExport` | `slide_decks:write` | | | `exportReport` | `slide_decks:read` | | | `getReportContent` | `slide_decks:read` | | | `getReportDesign` | `slide_decks:read` | | | `getReportSlideHtml` | `slide_decks:read` | | | `getReportSlideImages` | `slide_decks:read` | | | `showReport` | `slide_decks:read` | | | `getReportViewerSlideImages` | `slide_decks:read` | | | `arrangeReportSlides` | `slide_decks:write` | | | `updateReportTheme` | `slide_decks:write` | | | `renderReportSlides` | `slide_decks:write` | | | `saveReportSlides` | `slide_decks:write` | | | `getDataset` | `slide_decks:read` | | | `createDatasetUpload` | `slide_decks:write` | | | `createDocument` | `slide_decks:write` | | | `createDataset` | `slide_decks:write` | | | `replaceDataset` | `slide_decks:write` | | | `deleteDataset` | `slide_decks:write` | | | `getReportDataGuide` | `slide_decks:read` | | | `listReportDatasheets` | `slide_decks:read` | | | `getReportDatasheet` | `slide_decks:read` | | | `getReportDatasheetData` | `slide_decks:read` | | | `addReportDatasheets` | `slide_decks:write` | | | `removeReportDatasheet` | `slide_decks:write` | | | `addReportDashboardElements` | `slide_decks:write` | | | `previewReportDatasheetChanges` | `slide_decks:write` | | | `queryReportData` | `slide_decks:write` | | | `saveReportDatasheetChanges` | `slide_decks:write` | | | `getReportParameters` | `slide_decks:read` | | | `createReportParameter` | `slide_decks:write` | | | `updateReportParameter` | `slide_decks:write` | | | `deleteReportParameter` | `slide_decks:write` | | | `getReportViews` | `slide_decks:read` | | | `shareReport` | `slide_decks:write` | | | `unshareReport` | `slide_decks:write` | | | `listReportComments` | `slide_decks:read` | | | `createReportComment` | `slide_decks:write` | | | `resolveReportComment` | `slide_decks:write` | | | `getReportSchedules` | `slide_decks:read` | | | `updateReportSchedules` | `slide_decks:write` | | | `listEmails` | `slide_decks:read` | | | `getReportEmailConfig` | `slide_decks:read` | | | `listReportEmails` | `slide_decks:read` | | | `updateReportEmailConfig` | `slide_decks:email` | | | `sendReportEmail` | `slide_decks:email` | | | `sendReportTestEmail` | `slide_decks:email` | | | `listBursts` | `slide_decks:read` | | | `listBurstEmailConfigs` | `slide_decks:read` | | | `getBurstRun` | `slide_decks:read` | | | `getBurstSettings` | `slide_decks:read` | | | `listBurstVariants` | `slide_decks:read` | | | `getBurstVariantBatch` | `slide_decks:read` | | | `listReportSyncFilters` | `slide_decks:read` | | | `addBurstVariants` | `slide_decks:write` | | | `createBurst` | `slide_decks:write` | | | `createBurstEmailConfig` | `slide_decks:email` | | | `startBurstRun` | `slide_decks:run` | | | `sendBurstEmailConfig` | `slide_decks:email` | | | `sendBurstVariantEmails` | `slide_decks:email` | | | `renameBurst` | `slide_decks:write` | | | `updateBurstVariantEmailSettings` | `slide_decks:email` | | | `updateBurstEmailConfig` | `slide_decks:email` | | | `updateBurstSettings` | `slide_decks:write` | | | `updateBurstVariantRecipients` | `slide_decks:email` | | | `updateBurstFilters` | `slide_decks:write` | | | `deleteBurst` | `slide_decks:write` | | | `deleteBurstEmailConfig` | `slide_decks:email` | | | `reapplyBurstFilters` | `slide_decks:write` | | | `removeBurstVariants` | `slide_decks:write` | | | `sendBurstEmailConfigTest` | `slide_decks:email` | | | `listConnections` | `connections:read` | | | `searchDashboards` | `connections:read` | | | `getDashboard` | `connections:read` | | | `searchModels` | `connections:read` | | | `searchTables` | `connections:read` | | | `searchSpreadsheets` | `connections:read` | | | `getSpreadsheet` | `connections:read` | | | `listSmtpConnections` | `smtp:read` | | | `listFolders` | `slide_decks:read` | | | `getFolder` | `slide_decks:read` | | | `createFolder` | `slide_decks:write` | | | `updateFolder` | `slide_decks:write` | | | `shareFolder` | `slide_decks:write` | | | `unshareFolder` | `slide_decks:write` | | | `submitFeedback` | Any valid key | | | `listMembers` | `users:read` | Yes | ## Reports Find, create and manage reports. A report lives in a folder, has one owner, and is shared with other members who can view or edit it. Each report answers the permission the user has on it and a link that opens it in Rollstack. Most reports are slide decks built in Rollstack, whose `type` is `SlideDeck`. Older reports update a file in Google Drive or OneDrive, such as a Google Slides presentation, or send an email. Every report can be listed, read, renamed, moved, deleted, shared, scheduled, run and emailed, and the syncs of an older report listed. An older report that updates a Google Slides presentation or a PowerPoint file converts into a slide deck with `convertReport`. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400` for other types. To fill a new report, add its data in Datasheets, then ask the slides agent in Chat. To bring in an existing PowerPoint or Google Slides deck with its slides, pass its link to `createReport`. To refresh an existing report, start a run. ### List reports `GET https://api.rollstack.com/public/v1/reports` The reports the user can see, of every type, newest first. Each report's type tells which endpoints work on it: the slides agent, exports, content, datasheets, parameters, templates, duplicating and ownership transfer take SlideDeck reports only, and syncs take the other types only. You can filter by folderId, name and type; when several are set, all must match, and name matching ignores case. Answers up to limit reports, 50 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listReports`. #### Query parameters - `folderId` (string): Only return reports directly in this folder, by its `id` from `listFolders`. Reports in its subfolders aren't included. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. - `name` (string): Only return reports whose name contains this text, ignoring case: `review` matches `Q3 Business Review`. Example: `business review`. - `type` (string): Only return reports of this `type`, such as `SlideDeck` for the reports that the slides agent, exports and datasheets work on. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. Example: `SlideDeck`. - `limit` (integer): Maximum number of reports to return on this page, from 1 to 200. Defaults to `50`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The reports on this page, of every `type`, most recently created first. - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of reports. `null` when there are no more. ### Create report `POST https://api.rollstack.com/public/v1/reports` Creates a report of type SlideDeck, in a folder the user can see when folderId is set. It starts empty, in the look of a saved template from listTemplates when templateId is set, or of another report when templateDeckId is set: its theme, masters and layouts, without its slides. Ask the user which template to use when the organization has company templates. With link, it imports an existing deck instead, with its slides: a PowerPoint file in OneDrive or SharePoint, or a Google Slides presentation, read with the user's own Microsoft or Google account. Rollstack can open only the Google Slides presentations the user picked in Rollstack before, so a link to one they never did answers 422. Over REST, it also imports a PowerPoint (.pptx) file sent as multipart/form-data in the file field, with name and folderId as fields beside it; a report imported from a file is named after it unless name is set. An import answers once the deck is in, which can take a minute for a large one: send an Idempotency-Key (MCP: idempotencyKey) so a retry doesn't import it twice. At most 10 imports a minute per user. Requires the `slide_decks:write` scope. Operation ID: `createReport`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): Name for the report, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. If omitted, a report imported with `link` takes its file's name, and an empty report is named Untitled report until the slides agent names it as it builds the deck, as in the app. Example: `Q3 business review`. - `folderId` (string): The folder to create the report in, by its `id` from `listFolders`; it must be one you can see. Members with access to the folder can then open the report too, with the access the folder gives them. If omitted, the report is created at the top level, outside any folder. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. - `templateDeckId` (string): An existing report whose design the new report starts with, by its `id` from `listReports`: its theme, slide masters, layouts and slide size, but none of its slides or data. Its `type` must be `SlideDeck`, and you need at least view access to it. If neither this, `templateId` nor `link` is set, the report starts with no slides and Rollstack's default theme and layouts. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. - `templateId` (string): A saved template the new report starts with, by its `id` from `listTemplates`: a company template or Rollstack's own. The report gets its theme, slide masters, layouts and slide size, with no slides. Leave out `templateDeckId` when you set it. Example: `rollstack-signature`. - `link` (string): A link to an existing deck to import, as its Share or Copy link button gives it: a PowerPoint (.pptx) file in OneDrive or SharePoint, or a Google Slides presentation. The report starts with its slides and look: a PowerPoint file's charts come in as charts with their data, and a Google Slides presentation's as pictures. The file stays as it is. It is read with the user's own Microsoft or Google account, connected in the app, so they must be able to open it, and Rollstack can open only the Google Slides presentations the user picked in Rollstack before. The report keeps the deck's look, so leave out `templateId` and `templateDeckId`. Example: `https://contoso.sharepoint.com/:p:/s/Finance/EbXqT9kLmNpQrStUvWxYz`. `multipart/form-data` - `file` (string (binary), required): The PowerPoint file, a `.pptx` of at most 100 MB. The endpoint says what it takes from the file and how it names what it makes. - `name` (string): Name for the report, as members will see it in Rollstack. If omitted, it takes the file's name without `.pptx`. Example: `Q3 business review`. - `folderId` (string): The folder to create the report in, by its `id` from `listFolders`; it must be one you can see. Members with access to the folder can then open the report too, with the access the folder gives them. If omitted, the report is created at the top level, outside any folder. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `notificationMailingList` (array of string, required): Email addresses Rollstack copies when it emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. Change the list with `updateReport`. - `schedules` (array of object, required): The report's schedules: when Rollstack runs the report on its own to update it with fresh data. Empty if it has none, in which case the report only runs when someone starts a run. Replace them with `updateReportSchedules`. - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. - `sharedWith` (array of object, required): Members the report is shared with directly, with their access. Members who can open it through its folder aren't listed. Change this list with `shareReport` and `unshareReport`. - `userId` (number, required): The member's user id. Pass it as `userId` to `shareReport` to change their access, or to `unshareReport` to remove it. - `email` (string, required): The member's email address, as shown in Rollstack. - `name` (string, required): The member's name, as shown in Rollstack. - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. One of `view`, `comment`, `edit`. ### Get report `GET https://api.rollstack.com/public/v1/reports/{id}` A report of any type with its schedules, who it is shared with and who is emailed when a run fails. lastRunStatus and running tell how its latest run went and whether one is going, and appUrl opens it in Rollstack. type tells which other endpoints work on it. Requires the `slide_decks:read` scope. Operation ID: `getReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `notificationMailingList` (array of string, required): Email addresses Rollstack copies when it emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. Change the list with `updateReport`. - `schedules` (array of object, required): The report's schedules: when Rollstack runs the report on its own to update it with fresh data. Empty if it has none, in which case the report only runs when someone starts a run. Replace them with `updateReportSchedules`. - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. - `sharedWith` (array of object, required): Members the report is shared with directly, with their access. Members who can open it through its folder aren't listed. Change this list with `shareReport` and `unshareReport`. - `userId` (number, required): The member's user id. Pass it as `userId` to `shareReport` to change their access, or to `unshareReport` to remove it. - `email` (string, required): The member's email address, as shown in Rollstack. - `name` (string, required): The member's name, as shown in Rollstack. - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. One of `view`, `comment`, `edit`. ### Update report `PATCH https://api.rollstack.com/public/v1/reports/{id}` Renames a report of any type, moves it, or changes its timezone or failure notifications. Renaming a report that updates a file, such as a Google Slides presentation, also renames the file, as the app does. Only its editors may. Requires the `slide_decks:write` scope. Operation ID: `updateReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): New name for the report, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. Example: `Q3 business review`. - `folderId` (string or null): The folder to move the report to, by its `id` from `listFolders`; it must be one you can see. Pass `null` to move it to the top level, outside any folder. Members then get access to the report through the new folder, and the folders it's in, instead of the old one. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. - `timezone` (string): The report's new timezone. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. It doesn't change the report's schedules, which each have their own `timezone`: change those with `updateReportSchedules`. An IANA timezone name, such as `America/New_York`. Example: `America/New_York`. - `notifyOnFailure` (boolean): Whether Rollstack should email the report's owner when a scheduled run fails or some of its datasheets fail to refresh, copying everyone in `notificationMailingList`. Set it to `false` to stop these emails. Runs started in the app or with `startReportRun` never send them. - `notificationMailingList` (array of string (email)): Email addresses to copy when Rollstack emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. The list you send replaces the current one; send `[]` to clear it. Each address must belong to an active member of the organization, ignoring case. Up to 100 addresses, with no duplicates. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `notificationMailingList` (array of string, required): Email addresses Rollstack copies when it emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. Change the list with `updateReport`. - `schedules` (array of object, required): The report's schedules: when Rollstack runs the report on its own to update it with fresh data. Empty if it has none, in which case the report only runs when someone starts a run. Replace them with `updateReportSchedules`. - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. - `sharedWith` (array of object, required): Members the report is shared with directly, with their access. Members who can open it through its folder aren't listed. Change this list with `shareReport` and `unshareReport`. - `userId` (number, required): The member's user id. Pass it as `userId` to `shareReport` to change their access, or to `unshareReport` to remove it. - `email` (string, required): The member's email address, as shown in Rollstack. - `name` (string, required): The member's name, as shown in Rollstack. - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. One of `view`, `comment`, `edit`. ### Delete report `DELETE https://api.rollstack.com/public/v1/reports/{id}` Deletes a report of any type. A report that updates a file, such as a Google Slides presentation, leaves its file where it is. Only its owner may. Requires the `slide_decks:write` scope. Operation ID: `deleteReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Convert report to slide deck `POST https://api.rollstack.com/public/v1/reports/{id}/conversions` Turns an older report of type GoogleSlides or MicrosoftPowerPoint, which updates a Google Slides presentation or a PowerPoint file in OneDrive or SharePoint, into a new report of type SlideDeck, as Convert to Rollstack slides in the app does. The new report gets the file's slides, and each sync that can be converted becomes a datasheet reading the same source, drawn by a tile where the sync's chart, table or picture was. The older report and its file stay as they are. The file is read with the older report's owner's account. Answers the new report and what became of each sync, with the reason for one not converted, such as a burst variant's or one of a source with no datasheets: a converted chart with needsRun stays empty until the new report's first run, so start one with startReportRun. Only the older report's editors may. It answers once the conversion ends, which can take a few minutes for a large report: send an Idempotency-Key (MCP: idempotencyKey) so a retry doesn't convert it twice. Counts against the 10 imports a minute per user. Requires the `slide_decks:write` scope. Operation ID: `convertReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `name` (string): Name for the new report, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. If omitted, it takes the older report's name. Example: `Q4 business review`. - `folderId` (string): The folder to put the new report in, by its `id` from `listFolders`; it must be one you can add reports to. If omitted, it goes at the top level, as in the app. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. #### Response `201` Success `application/json` - `report` (object, required): The new report, of type `SlideDeck`. - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `notificationMailingList` (array of string, required): Email addresses Rollstack copies when it emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. Change the list with `updateReport`. - `schedules` (array of object, required): The report's schedules: when Rollstack runs the report on its own to update it with fresh data. Empty if it has none, in which case the report only runs when someone starts a run. Replace them with `updateReportSchedules`. - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. - `sharedWith` (array of object, required): Members the report is shared with directly, with their access. Members who can open it through its folder aren't listed. Change this list with `shareReport` and `unshareReport`. - `userId` (number, required): The member's user id. Pass it as `userId` to `shareReport` to change their access, or to `unshareReport` to remove it. - `email` (string, required): The member's email address, as shown in Rollstack. - `name` (string, required): The member's name, as shown in Rollstack. - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. One of `view`, `comment`, `edit`. - `conversion` (object or null, required): What became of the older report's syncs, or null when converting them failed. - `converted` (array of object, required): The syncs that are now tiles on the slides, each drawn from a datasheet. - `syncId` (string, required): The sync of the older report, as `listReportSyncs` lists it. - `name` (string, required): The sync's name. - `datasheetId` (string, required): The datasheet that now reads its source. - `slideId` (string, required): The slide whose tile now shows it. - `needsRun` (boolean, required): Whether its chart stays empty until the new report's first run reads the datasheet's data. - `notPlaced` (array of object, required): The syncs that got a datasheet, but no tile: the slides agent can build one from the datasheet. - `syncId` (string, required): The sync of the older report, as `listReportSyncs` lists it. - `name` (string, required): The sync's name. - `datasheetId` (string, required): The datasheet that now reads its source. - `reason` (string, required): Why no element of the slides could show it. - `notConverted` (array of object, required): The syncs left as they were in the new report's slides, such as a burst variant's. - `syncId` (string, required): The sync of the older report, as `listReportSyncs` lists it. - `name` (string, required): The sync's name. - `reason` (string, required): Why it was not converted. - `conversionError` (string or null, required): Why the syncs could not be converted, when they couldn't. The new report still exists with the file's slides, so don't convert the report again. ### Duplicate report `POST https://api.rollstack.com/public/v1/reports/{id}/duplicates` Copies a report of type SlideDeck with its slides, datasheets and email setup, as Duplicate in the app does, and answers the copy, which you own. Its schedules and direct shares are copied only when asked. Only members who may duplicate the report may: view access is enough. Each call makes another copy. Requires the `slide_decks:write` scope. Operation ID: `duplicateReport`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): Name for the copy, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. Example: `Q4 business review`. - `folderId` (string): The folder to put the copy in, by its `id` from `listFolders`; it must be one you can add reports to. If omitted, the copy goes in the report's own folder, or for a burst's variant, in the burst's folder. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. - `copySchedules` (boolean): Also give the copy the report's schedules, so it updates on its own at the same times. Defaults to `false`. - `inheritSharing` (boolean): Also share the copy with everyone the report is shared with directly, at the same permission. Defaults to `false`, so only you can open it until you share it. Defaults to `false`. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `notificationMailingList` (array of string, required): Email addresses Rollstack copies when it emails the owner about a failed scheduled run, while `notifyOnFailure` is `true`. Change the list with `updateReport`. - `schedules` (array of object, required): The report's schedules: when Rollstack runs the report on its own to update it with fresh data. Empty if it has none, in which case the report only runs when someone starts a run. Replace them with `updateReportSchedules`. - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. - `sharedWith` (array of object, required): Members the report is shared with directly, with their access. Members who can open it through its folder aren't listed. Change this list with `shareReport` and `unshareReport`. - `userId` (number, required): The member's user id. Pass it as `userId` to `shareReport` to change their access, or to `unshareReport` to remove it. - `email` (string, required): The member's email address, as shown in Rollstack. - `name` (string, required): The member's name, as shown in Rollstack. - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. One of `view`, `comment`, `edit`. ### Transfer ownership `POST https://api.rollstack.com/public/v1/reports/{id}/transfer-ownership` Makes a member of the organization the owner of a report. Only its owner may, and keeps edit access. Requires the `slide_decks:write` scope. Operation ID: `transferReportOwnership`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `newOwnerId` (integer, required): The member who becomes the report's owner, by user id: their `id` in `listMembers`, or their `userId` in the report's `sharedWith`. They must be an active member of the organization other than you. The previous owner keeps `edit` access to the report, and the new owner is notified. Example: `1042`. #### Response `204` Success, no content ## Templates The look a slide deck is built in: its theme, slide masters, layouts and slide size. Members import their company's templates from PowerPoint or Google Slides in the app, keep them to themselves or share them with the organization, and every organization also has Rollstack's own. List the ones the user can use with `listTemplates`, start a new report in one with `templateId` in `createReport`, or switch an existing report to one with `applyReportTemplate`. Import a company template from a Google Slides presentation or a PowerPoint file with `createTemplate`, rename it or share it with the organization with `updateTemplate`, and delete it with `deleteTemplate`. ### List templates `GET https://api.rollstack.com/public/v1/templates` The templates the user can build a slide deck in: their company's, with who imported each and whether it is shared with the organization, then Rollstack's own. Pass a template's id as templateId to createReport or applyReportTemplate. Requires the `slide_decks:read` scope. Operation ID: `listTemplates`. #### Response `200` Success `application/json` - `data` (array of object, required): The templates the user can use: the company templates they imported or that are shared with the organization, newest first, then Rollstack's own. Members import and share them in Rollstack, in the Templates drawer of a report. - `id` (string, required): The template, by its `id` from `listTemplates`. Rollstack's own template has the fixed id `rollstack-signature`. Example: `rollstack-signature`. - `name` (string, required): The template's name, as members see it in Rollstack. - `builtIn` (boolean, required): `true` for Rollstack's own template, which every organization has; `false` for a company template. - `source` (string, required): Where the template comes from, as Rollstack shows it: `Made by Rollstack`, `Shared by ` or `Only visible to you`. Name it to tell templates with the same name apart. - `sharedWithOrganization` (boolean or null, required): Whether everyone in the organization can use the company template. `false` when only its creator can. `null` for Rollstack's own template. - `createdBy` (object or null, required): The member who imported the company template. `null` for Rollstack's own, or when their account was deleted. - `id` (number, required) - `name` (string, required) - `createdAt` (string (date-time) or null, required): When the company template was imported. `null` for Rollstack's own. ### Import template `POST https://api.rollstack.com/public/v1/templates` Imports a company template from a Google Slides presentation, as the app's Templates drawer does: its theme, slide masters, layouts and slide size, not its slides. The presentation is read with the user's Google account connected to Rollstack. Over REST, you can instead send a PowerPoint file as multipart/form-data in the file field: a .pptx of at most 100 MB, named after the file and kept to the user until shared with updateTemplate. Answers the template as listTemplates lists it, to pass as templateId to createReport or applyReportTemplate. Requires the `slide_decks:write` scope. Operation ID: `createTemplate`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): The template's name, as members will see it in Rollstack. Example: `Acme 2026`. - `googleSlidesId` (string, required): The Google Slides presentation to import the look of, by its link or its id: the part after `/presentation/d/` in the link. It's read with your Google account connected to Rollstack, so you must be able to open it. - `sharedWithOrganization` (boolean): Whether everyone in the organization can use the template, or only you. Only admins can share a template with the organization; a template's creator can stop sharing it. Defaults to `false`. `multipart/form-data` - `file` (string (binary), required): The PowerPoint file, a `.pptx` of at most 100 MB. The endpoint says what it takes from the file and how it names what it makes. #### Response `201` Success `application/json` - `id` (string, required): The template, by its `id` from `listTemplates`. Rollstack's own template has the fixed id `rollstack-signature`. Example: `rollstack-signature`. - `name` (string, required): The template's name, as members see it in Rollstack. - `builtIn` (boolean, required): `true` for Rollstack's own template, which every organization has; `false` for a company template. - `source` (string, required): Where the template comes from, as Rollstack shows it: `Made by Rollstack`, `Shared by ` or `Only visible to you`. Name it to tell templates with the same name apart. - `sharedWithOrganization` (boolean or null, required): Whether everyone in the organization can use the company template. `false` when only its creator can. `null` for Rollstack's own template. - `createdBy` (object or null, required): The member who imported the company template. `null` for Rollstack's own, or when their account was deleted. - `id` (number, required) - `name` (string, required) - `createdAt` (string (date-time) or null, required): When the company template was imported. `null` for Rollstack's own. ### Update template `PATCH https://api.rollstack.com/public/v1/templates/{templateId}` Renames a company template, or shares it with the organization or stops sharing it, as the app's Templates drawer does. Its creator can rename it and stop sharing it, only an admin can share their own template with the organization, and admins can also rename any shared one. Reports already built in it keep their look. Answers the template as listTemplates lists it. Requires the `slide_decks:write` scope. Operation ID: `updateTemplate`. #### Path parameters - `templateId` (string (uuid), required): The company template to act on, by its `id` from `listTemplates`. Rollstack's own template can't be changed. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): The template's new name, as members see it in Rollstack. - `sharedWithOrganization` (boolean): Whether everyone in the organization can use the template, or only you. Only admins can share a template with the organization; a template's creator can stop sharing it. #### Response `200` Success `application/json` - `id` (string, required): The template, by its `id` from `listTemplates`. Rollstack's own template has the fixed id `rollstack-signature`. Example: `rollstack-signature`. - `name` (string, required): The template's name, as members see it in Rollstack. - `builtIn` (boolean, required): `true` for Rollstack's own template, which every organization has; `false` for a company template. - `source` (string, required): Where the template comes from, as Rollstack shows it: `Made by Rollstack`, `Shared by ` or `Only visible to you`. Name it to tell templates with the same name apart. - `sharedWithOrganization` (boolean or null, required): Whether everyone in the organization can use the company template. `false` when only its creator can. `null` for Rollstack's own template. - `createdBy` (object or null, required): The member who imported the company template. `null` for Rollstack's own, or when their account was deleted. - `id` (number, required) - `name` (string, required) - `createdAt` (string (date-time) or null, required): When the company template was imported. `null` for Rollstack's own. ### Delete template `DELETE https://api.rollstack.com/public/v1/templates/{templateId}` Deletes a company template, as the app's Templates drawer does. Reports already built in it keep their look; new ones can no longer start in it. Its creator, or an admin for a shared one, may. Requires the `slide_decks:write` scope. Operation ID: `deleteTemplate`. #### Path parameters - `templateId` (string (uuid), required): The company template to act on, by its `id` from `listTemplates`. Rollstack's own template can't be changed. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Apply template `POST https://api.rollstack.com/public/v1/reports/{id}/template` Switches a report of type SlideDeck to a template's theme, slide masters, layouts and slide size, as the Templates drawer in the app does. Its slides keep their content and move to the template's matching layouts; the answer names the slides that had no match, and the version saved just before as versionBeforeId: restore it with restoreReportVersion to undo the change. Only its editors may, and not while the report is running or the slides agent is working on it. Requires the `slide_decks:write` scope. Operation ID: `applyReportTemplate`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `templateId` (string, required): The template, by its `id` from `listTemplates`. Rollstack's own template has the fixed id `rollstack-signature`. Example: `rollstack-signature`. #### Response `200` Success `application/json` - `templateName` (string, required): The name of the template the report now uses. - `versionName` (string, required): The name of the version of the report saved just before, in its Version history. - `versionBeforeId` (string, required): The version saved just before. Restore it with `restoreReportVersion` to undo the change. - `closestLayoutSlides` (array of integer, required): The slides, by number from 1, whose layout the template has no match for: they moved to the template's closest layout, so tell the user to check them. - `noLayoutSlides` (array of integer, required): The slides, by number from 1, with no layout, such as ones pasted from PowerPoint: they only got the template's colors and fonts. ## Versions A slide deck's Version history, as in the app: Rollstack saves a version while the report is edited, around each run, before and after each change of the slides agent, and before a template is applied or a version restored. Take a report back to a version with `restoreReportVersion`: to undo what the slides agent did, pass its reply's `versionBeforeId`. Find others with `listReportVersions`, and save one yourself with `saveReportVersion` before a change the user may want to take back. A restore saves the report as it was first, so it can be undone too. ### List report versions `GET https://api.rollstack.com/public/v1/reports/{id}/versions` The Version history of a report of type SlideDeck, newest first, as the app lists it: the versions Rollstack saved while it was edited, run or changed by the slides agent, and those saved with saveReportVersion, each with what saved it. Answers up to limit versions, 20 by default and 100 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Pass a version's id to restoreReportVersion to take the report back to it. Requires the `slide_decks:read` scope. Operation ID: `listReportVersions`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Query parameters - `limit` (integer): Maximum number of versions to return on this page, from 1 to 100. Defaults to `20`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The report's Version history, newest first: the versions it can be restored to. - `id` (string, required): Identifies the version. Pass it as `versionId` to `restoreReportVersion`. - `name` (string or null, required): The name the version was saved with, such as `Before applying Acme` for the one a template apply saves. `null` when it has none: the app then names it after its `kind` or the time it was saved. - `kind` (string, required): What saved the version. - `autoSaved`: Rollstack, while the report was edited, and just before a version was restored or a template applied. - `saved`: a member, with `saveReportVersion`. - `beforeRun`, `afterRun`: a run, just before and after it updated the report. - `beforeSlidesAgent`, `afterSlidesAgent`: the slides agent, just before and after it changed the report. A reply's `versionBeforeId` names the one before it. - `slidesAgent`: an earlier version of the slides agent. One of `autoSaved`, `saved`, `beforeRun`, `afterRun`, `beforeSlidesAgent`, `afterSlidesAgent`, `slidesAgent`. - `savedBy` (object or null, required): The member whose edit, run, message or call saved it. `null` if their account was deleted. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `createdAt` (string (date-time), required): When the version was saved. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of versions. `null` when there are no more. ### Save report version `POST https://api.rollstack.com/public/v1/reports/{id}/versions` Saves a report of type SlideDeck as it is now in its Version history, with an optional name, so it can be restored later with restoreReportVersion, for example before a change the user may want to take back. Rollstack already saves one before each change of the slides agent, each run and each template apply. Only its editors may. Each call saves another version. Requires the `slide_decks:write` scope. Operation ID: `saveReportVersion`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): A name for the version, as members will see it in the report's Version history, from 1 to 100 characters. Without one, the app names it after the time it was saved. Example: `Before the Q3 restyle`. #### Response `201` Success `application/json` - `id` (string, required): Identifies the version. Pass it as `versionId` to `restoreReportVersion`. - `name` (string or null, required): The name the version was saved with, such as `Before applying Acme` for the one a template apply saves. `null` when it has none: the app then names it after its `kind` or the time it was saved. - `kind` (string, required): What saved the version. - `autoSaved`: Rollstack, while the report was edited, and just before a version was restored or a template applied. - `saved`: a member, with `saveReportVersion`. - `beforeRun`, `afterRun`: a run, just before and after it updated the report. - `beforeSlidesAgent`, `afterSlidesAgent`: the slides agent, just before and after it changed the report. A reply's `versionBeforeId` names the one before it. - `slidesAgent`: an earlier version of the slides agent. One of `autoSaved`, `saved`, `beforeRun`, `afterRun`, `beforeSlidesAgent`, `afterSlidesAgent`, `slidesAgent`. - `savedBy` (object or null, required): The member whose edit, run, message or call saved it. `null` if their account was deleted. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `createdAt` (string (date-time), required): When the version was saved. ### Restore report version `POST https://api.rollstack.com/public/v1/reports/{id}/versions/{versionId}/restore` Takes a report of type SlideDeck back to one of its versions, as Restore in the app's Version history does: its slides, and the datasheets when the version saved them, become the version's, replacing every change made since, and members with the report open see it at once. Find the version with listReportVersions, or take a slides agent reply's versionBeforeId to undo that reply. The report as it was is saved first, and the answer names that version as versionBeforeId. Only its editors may, and not while the report is running or the slides agent is working on it. Requires the `slide_decks:write` scope. Operation ID: `restoreReportVersion`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `versionId` (string, required): The version to restore: an `id` from `listReportVersions`, or a reply's `versionBeforeId`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `versionBeforeId` (string, required): The version of the report saved just before the restore, with the slides and datasheets it replaced. Restore it to undo the restore. - `skippedDatasheetIds` (array of string, required): Datasheets the version had that stayed as they are now, because they read a source deleted since. Usually empty. A version saved before Rollstack kept datasheets in versions brings back only its slides. ## Chat Ask the slides agent to build or change a report, or to answer a question about it, as in the chat of the app. 1. Send a message with `sendReportMessage`. It answers at once with the message id. 2. Call `getReportMessage` until its status is `completed` or `failed`. Each call waits up to `waitSeconds` for the agent to finish. 3. Check the slides it changed with `getReportSlideImages` or `getReportContent`, passing the replies' `changedSlideIds`. 4. A reply can propose a change to the report's schedules, email or parameters, or to send it by email, instead of making it. Show the user its `proposal`, then decide it as they say with `approveReportMessageProposal` or `rejectReportMessageProposal`. Continue the conversation by sending the next message with the same `chatId`. Every chat also shows in the app, with a link in `appUrl`. ### Get slides agent message `GET https://api.rollstack.com/public/v1/reports/{id}/messages/{messageId}` A message to the slides agent and its replies. Waits up to waitSeconds for the message to finish and answers as soon as it does, so call it again while the status is queued or running. A clarification reply asks questions: ask the user, then send the options they pick as answers in a new message on the same chat. A proposal reply changes nothing until it is approved: show the user what its proposal changes, then approve or reject it as they decide. Only the user who sent the message may read it, while they can edit the report. Requires the `slide_decks:read` scope. Operation ID: `getReportMessage`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `messageId` (string, required): The message to the slides agent: the `messageId` that `sendReportMessage` returned. Only the user who sent the message can read, cancel or decide its proposals, and only while they can edit the report. #### Query parameters - `waitSeconds` (integer): How long this call waits for the work to finish, in seconds: the message to the slides agent on `getReportMessage`, the run on `getReportRun`, the batch of variants being added on `getBurstVariantBatch`, the runs of a burst's variants on `getBurstRun`. It returns as soon as the work is done, or as things stand once the time is up, so call it again while `status` is still `queued` or `running`. `0` returns at once. Defaults to `20`; at most `30`. Defaults to `20`. #### Response `200` Success `application/json` - `chatId` (string, required): Identifies the chat the message is in, which also shows in your chat history on the report in the app. Pass it as `chatId` to `sendReportMessage` to continue the conversation, for example to answer a `clarification` reply. - `messageId` (string, required): Identifies your message to the slides agent. Pass it as `messageId` to `getReportMessage` to follow its progress and read the agent's replies, or to `cancelReportMessage` to stop it. - `status` (string, required): Where the message stands. `sendReportMessage` always returns `queued` or `running`. - `queued`: the agent is still replying to an earlier message of the same chat; this one starts once that reply is finished. - `running`: the slides agent is working on it. While other chats keep the agent busy on this report, it can first wait here for its turn. - `completed`: every reply is finished; `getReportMessage` lists them in `replies`. - `failed`: at least one of its replies failed. - `cancelled`: it was stopped while running, for example with `cancelReportMessage` or the stop button in the app. Cancelling a `queued` message removes it from the chat instead, so it is no longer found. One of `queued`, `running`, `completed`, `failed`, `cancelled`. - `appUrl` (string (uri), required): Link to the report in Rollstack, with this chat open, where you can follow the conversation and review the changes the agent made. - `stage` (string or null, required): What the slides agent is doing right now, in the words the chat in the app shows, such as `Understanding your request`, `Refreshing data`, `Design` or `Finishing up`. Use it to show progress while `status` is `running`. `null` when no step is under way: while the message is `queued`, before the agent's first step, and once the message is finished. - `createdAt` (string (date-time), required): When you sent the message to the slides agent. - `updatedAt` (string (date-time), required): When the message or any of its replies last changed, for example as the agent reports progress or finishes a reply. - `replies` (array of object, required): The slides agent's replies to this message, in order. The first one is listed, `running`, as soon as the message is sent. The agent can split a message that asks for several things into parts, each with its own reply; the message is finished only once every part is. - `id` (string, required): Identifies the reply. It stays the same from `running` until the reply is finished, so you can follow each reply across calls. - `status` (string, required): Where this reply stands. `running` while the agent works on it or it waits its turn; on a `datasheet_filters_proposal`, until Rollstack has applied the filters. `completed` once the reply is finished: `type` says what it is. `failed` when the agent couldn't finish it, never got to it because an earlier part failed or was stopped, or the filters couldn't be applied. `cancelled` when it was stopped, for example with `cancelReportMessage` or the stop button in the app. One of `running`, `completed`, `failed`, `cancelled`. - `type` (string or null, required): What the reply is, which tells you what to do next. `null` while the agent is still working on it, and when it failed or was stopped. - `result`: the agent changed the report, and the changes are already saved. `changedSlideIds` lists the slides it added or changed; `versionBeforeId` undoes them with `restoreReportVersion`, and they can also be reviewed or reverted in the app. - `partial_result`: the same as `result`, on replies written by an earlier version of the slides agent. - `clarification`: the agent needs more from you before it goes on. Answer its `questions`, or the question in `content` when there are none, in the next message on the same chat. - `answer`: the agent replied in `content` without changing the report, for example to a question about the report or about how Rollstack works. - `datasheet_filters_proposal`: the agent changes the values of filters that some of the report's datasheets apply when they read their source. For a message sent through the API, Rollstack applies them right away, without approval in the app. If your request needed more than that, it then goes on by itself as a new message in the same chat, unless you send one there first; that message isn't in these `replies`, so follow it in the app. - `settings_proposal`, `email_send_proposal`: a change to the report's update schedules, email settings, email template or parameters, or sending the report by email. Nothing changes until it is approved: show the user what `proposal` changes, then approve it with `approveReportMessageProposal` or reject it with `rejectReportMessageProposal`, as they decide. It can also be decided in the app. The agent makes one for a message sent through the API only when your API key has the scope the change needs. - `report_proposal`: a change elsewhere in Rollstack, such as to reports, folders or members. The agent doesn't make them for messages sent through the API. - `proposal_applied`: a note the chat in the app adds once a proposal is decided. It is never listed in `replies`. One of `result`, `partial_result`, `clarification`, `answer`, `settings_proposal`, `proposal_applied`, `email_send_proposal`, `datasheet_filters_proposal`, `report_proposal`. - `content` (string, required): The reply's text, as the chat in the app shows it: what the agent did, its answer, or its questions. Empty until the agent has written it. When the reply failed or was stopped, it says so. Can contain Markdown. - `questions` (array of object): On a `clarification` reply: the multiple-choice questions the agent needs answered before it goes on. Send the options picked as `answers` in the next message on the same chat, or answer in your own words in `content`. Absent on other replies, and on a clarification that asks its question only in `content`. - `question` (string, required): The question the agent is asking, as the chat in the app shows it. - `header` (string, required): A short label for the question, such as `Chart type`, shown before it in the app. Send it back unchanged, with `question`, when you answer. - `multiSelect` (boolean, required): Whether more than one option can be picked. When `true`, the app shows the options as checkboxes; when `false`, as a single choice, so answer with one option. - `options` (array of object, required): The options to choose from. Answer with the `label` of each one picked. - `label` (string, required): The option's text, as shown in the app. Send it back in `answers` to pick this option. The agent may mark the option it recommends with `(Recommended)`, which you can keep or drop. - `description` (string): What picking this option means, shown under its label in the app. - `value` (string): Set when the option offers data the agent found: a connection for the agent to search next, or a dashboard, table or spreadsheet that Rollstack adds to the report as a datasheet when you pick the option. It isn't shown in the app, and you don't send it back: picking the option by its `label` in the next message on the same chat is enough. - `templateId` (string): Set when the option offers a saved template, by its `id` in `listTemplates`: the app shows the template's look. You don't send it back: picking the option by its `label` is enough. - `changedSlideIds` (array of string): On a `result` or `partial_result` reply: the slides the agent added or changed, in report order. Slides it deleted aren't listed. Pass them as `slideIds` to `getReportSlideImages` to check how they look, or to `getReportContent` to read them. - `versionBeforeId` (string): On a `result` or `partial_result` reply: the report's version saved just before the agent changed it. Restore it with `restoreReportVersion` to undo the reply, which also undoes any change made to the report since. - `proposal` (object): On a `settings_proposal` or `email_send_proposal` reply: what the proposal changes, or the email it sends, and where it stands. Absent on other replies. - Option 1 - `status` (string, required): `proposed` while it waits for the user to decide. `applied` once approved and applied, `rejected` once rejected. `superseded` when a later proposal in the chat replaced it. `conflict` when the report changed after it was proposed, so approving it applied nothing, and `failed` when applying it failed. One of `proposed`, `applying`, `applied`, `rejected`, `superseded`, `conflict`, `failed`. - `changes` (array of object, required): What approving it changes, as the approval card in the app shows it: one entry per change, with the setting before and after it. `warnings` point out what the user should know before approving, such as a schedule that never runs. - When `type` is `parameters.create` - `type` (`parameters.create`, required) - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `warnings` (array of object, required) - When `type` is `parameters.update` - `type` (`parameters.update`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `warnings` (array of object, required) - When `type` is `parameters.delete` - `type` (`parameters.delete`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `warnings` (array of object, required) - When `type` is `parameters.setDatasheetLinked` - `type` (`parameters.setDatasheetLinked`, required) - `parameterName` (string, required) - `filterName` (string, required) - `datasheetName` (string, required) - `isLinked` (boolean, required) - `warnings` (array of object, required) - When `type` is `email.template.create` - `type` (`email.template.create`, required) - `before` (object or null, required) - `after` (object or null, required) - `impact` (object or null, required) - `warnings` (array of object, required) - When `type` is `email.template.update` - `type` (`email.template.update`, required) - `before` (object or null, required) - `after` (object or null, required) - `impact` (object or null, required) - `warnings` (array of object, required) - When `type` is `email.template.select` - `type` (`email.template.select`, required) - `before` (object or null, required) - `after` (object or null, required) - `impact` (object or null, required) - `warnings` (array of object, required) - When `type` is `email.template.reset` - `type` (`email.template.reset`, required) - `before` (object or null, required) - `after` (object or null, required) - `impact` (object or null, required) - `warnings` (array of object, required) - When `type` is `schedule.add` - `type` (`schedule.add`, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - When `type` is `schedule.remove` - `type` (`schedule.remove`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - When `type` is `schedule.modify` - `type` (`schedule.modify`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - When `type` is `email.config.update` - `type` (`email.config.update`, required) - `before` (object or null, required) - `after` (object, required) - `trigger` (string, required): One of `all`, `none`, `scheduled`. - `sharingFormat` (string, required): One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required) - `sender` (object or null, required) - `warnings` (array of object, required) - When `type` is `email.recipients.update` - `type` (`email.recipients.update`, required) - `before` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `warnings` (array of object, required) - When `type` is `email.recipients.createGroup` - `type` (`email.recipients.createGroup`, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `warnings` (array of object, required) - Option 2 - `status` (string, required): `awaiting_confirmation` while it waits for the user to decide, `cancelled` once rejected, and `superseded` when a later proposal in the chat replaced it. Once approved: `queued` and `sending` until every email is handed to the email provider, then `sent`, `partially_sent` or `failed`. `unconfirmed` when Rollstack lost track of the send, so some emails may have gone out. One of `awaiting_confirmation`, `cancelled`, `superseded`, `queued`, `sending`, `sent`, `partially_sent`, `failed`, `unconfirmed`. - `recipients` (array of object, required): Who receives the report: one email per group, each with its own addresses. - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `sharingFormat` (string, required): The file sent: the report's visible slides as a PDF (`pdf`) or PowerPoint file (`ppt`). One of `pdf`, `ppt`. - `sendAttachmentAsLink` (boolean, required): Whether the file is behind a download button in the email instead of attached. - `counts` (object or null, required): How many emails were handed to the email provider, failed, or ended unknown. `null` until the send starts. - `total` (integer, required) - `sent` (integer, required) - `failed` (integer, required) - `unknown` (integer, required) ### Send message to slides agent `POST https://api.rollstack.com/public/v1/reports/{id}/messages` Asks the slides agent to build or change a report, or to answer a question about it, as the app's chat does. Answers the message's id at once: follow it with getReportMessage. Without chatId the message starts a new chat, which shows in the user's chat history in the app. With it, the message continues that chat and waits its turn while a reply is still generating. Several chats on a report can generate at once; an agent working on a part of the report another chat is editing works on something else or says so. For slides built from your own data, a connected dashboard, a warehouse table or a spreadsheet, upload the data with createDataset, find the dashboard or Salesforce report with searchDashboards, the Snowflake or Databricks table with searchTables or the spreadsheet with searchSpreadsheets, add any of them with addReportDatasheets and pass the datasheet ids as datasheetIds. For a brief, a report or notes to build from, upload it with createDocument and pass its id in documentIds. Only its editors may. At most 6 messages a minute per user. To write the slides yourself instead, start with getReportDesign. Requires the `slide_decks:run` scope. Operation ID: `sendReportMessage`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `content` (string): Your message to the slides agent, as you would write it in the chat in the app: for example, slides to build or change, or a question about the report. On a report with no slides yet, the agent takes it as a request to build the report. A link to a picture in the message, such as a logo or a photo to place, is downloaded and given to the agent. Required unless you send `answers`; with them, it's sent after your answers as a note. At most 10,000 characters: send a longer text, such as a brief, as a document with `createDocument`. Defaults to ``. Example: `Add a slide comparing revenue by region`. - `chatId` (string): The chat to continue: the `chatId` returned for an earlier message. The agent reads the chat's earlier messages as context, and if it's still replying in that chat, your message waits its turn (`queued`). If omitted, the message starts a new chat, which shows in your chat history on the report in the app. Must be one of your own chats on this report. Example: `0e4c2b7a-9d1f-4a3b-8c5e-6f7a8b9c0d1e`. - `slideIds` (array of string): The slides your message is about, as when you select slides in the app before writing in the chat. The agent knows you selected them and uses the datasheets on them for your request. Slide ids come from `getReportContent`. 1 to 100 slides of this report. - `datasheetIds` (array of string (uuid)): Datasheets of this report for the agent to work from, on top of those on the slides in `slideIds`, as when you pick data in the chat in the app. To have the agent build slides from data you just added, pass the ids `addReportDatasheets` returned; for data already on the report, take them from `listReportDatasheets`. 1 to 100 datasheets of this report. - `documentIds` (array of string): Documents for the agent to read, as when you attach documents in the chat in the app: the ids `createDocument` returned. The agent reads their text and looks at their pages, for example to build slides from a brief or to rebuild a report as slides. 1 to 5 documents your organization can read. - `answers` (array of object): Your answers to the questions of a `clarification` reply, as when you pick options in the chat in the app: one entry per question you answer. Send them as the next message on the same chat, by passing its `chatId`. When a picked option offers a dashboard, table or spreadsheet, Rollstack adds it to the report as a datasheet before the agent goes on. To add a note, send it in `content` with the answers. - `header` (string, required): The `header` of the question you're answering, copied unchanged from the `clarification` reply's `questions`. Example: `Chart type`. - `question` (string, required): The question you're answering, copied unchanged from the `clarification` reply's `questions`. With `header`, it tells Rollstack which question your picks are for. Example: `Which chart should show revenue by region?`. - `answers` (array of string, required): The `label` of each option picked: one for a question whose `multiSelect` is `false`, one or more when it's `true`. #### Response `202` Success `application/json` - `chatId` (string, required): Identifies the chat the message is in, which also shows in your chat history on the report in the app. Pass it as `chatId` to `sendReportMessage` to continue the conversation, for example to answer a `clarification` reply. - `messageId` (string, required): Identifies your message to the slides agent. Pass it as `messageId` to `getReportMessage` to follow its progress and read the agent's replies, or to `cancelReportMessage` to stop it. - `status` (string, required): Where the message stands. `sendReportMessage` always returns `queued` or `running`. - `queued`: the agent is still replying to an earlier message of the same chat; this one starts once that reply is finished. - `running`: the slides agent is working on it. While other chats keep the agent busy on this report, it can first wait here for its turn. - `completed`: every reply is finished; `getReportMessage` lists them in `replies`. - `failed`: at least one of its replies failed. - `cancelled`: it was stopped while running, for example with `cancelReportMessage` or the stop button in the app. Cancelling a `queued` message removes it from the chat instead, so it is no longer found. One of `queued`, `running`, `completed`, `failed`, `cancelled`. - `appUrl` (string (uri), required): Link to the report in Rollstack, with this chat open, where you can follow the conversation and review the changes the agent made. ### Approve slides agent proposal `POST https://api.rollstack.com/public/v1/reports/{id}/messages/{messageId}/replies/{replyId}/approve` Approves the proposal of a settings_proposal or email_send_proposal reply, as its Approve button in the app's chat does: Rollstack makes the change, or sends the email. Only approve what the user approved after seeing the reply's proposal. Answers the reply with the proposal's status: applied once the change is made, and queued for a send, which getReportMessage then follows through sending to sent, partially_sent, failed or unconfirmed, with its counts. Needs also slide_decks:email for an email change or send, and slide_decks:write for the rest. Approving a send answers 409 while the report is updating, such as after a filter change the same message asked for, and counts against the 5 email sends a minute, as sendReportEmail does. Only the user who sent the message may, while they can edit the report. A proposal already decided answers 409. From an AI client, approving a send only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:run` scope. Operation ID: `approveReportMessageProposal`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `messageId` (string, required): The message to the slides agent: the `messageId` that `sendReportMessage` returned. Only the user who sent the message can read, cancel or decide its proposals, and only while they can edit the report. - `replyId` (string, required): The reply that makes the proposal: the `id` of a `settings_proposal` or `email_send_proposal` reply that `getReportMessage` lists for the message. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `id` (string, required): Identifies the reply. It stays the same from `running` until the reply is finished, so you can follow each reply across calls. - `status` (string, required): Where this reply stands. `running` while the agent works on it or it waits its turn; on a `datasheet_filters_proposal`, until Rollstack has applied the filters. `completed` once the reply is finished: `type` says what it is. `failed` when the agent couldn't finish it, never got to it because an earlier part failed or was stopped, or the filters couldn't be applied. `cancelled` when it was stopped, for example with `cancelReportMessage` or the stop button in the app. One of `running`, `completed`, `failed`, `cancelled`. - `type` (string or null, required): What the reply is, which tells you what to do next. `null` while the agent is still working on it, and when it failed or was stopped. - `result`: the agent changed the report, and the changes are already saved. `changedSlideIds` lists the slides it added or changed; `versionBeforeId` undoes them with `restoreReportVersion`, and they can also be reviewed or reverted in the app. - `partial_result`: the same as `result`, on replies written by an earlier version of the slides agent. - `clarification`: the agent needs more from you before it goes on. Answer its `questions`, or the question in `content` when there are none, in the next message on the same chat. - `answer`: the agent replied in `content` without changing the report, for example to a question about the report or about how Rollstack works. - `datasheet_filters_proposal`: the agent changes the values of filters that some of the report's datasheets apply when they read their source. For a message sent through the API, Rollstack applies them right away, without approval in the app. If your request needed more than that, it then goes on by itself as a new message in the same chat, unless you send one there first; that message isn't in these `replies`, so follow it in the app. - `settings_proposal`, `email_send_proposal`: a change to the report's update schedules, email settings, email template or parameters, or sending the report by email. Nothing changes until it is approved: show the user what `proposal` changes, then approve it with `approveReportMessageProposal` or reject it with `rejectReportMessageProposal`, as they decide. It can also be decided in the app. The agent makes one for a message sent through the API only when your API key has the scope the change needs. - `report_proposal`: a change elsewhere in Rollstack, such as to reports, folders or members. The agent doesn't make them for messages sent through the API. - `proposal_applied`: a note the chat in the app adds once a proposal is decided. It is never listed in `replies`. One of `result`, `partial_result`, `clarification`, `answer`, `settings_proposal`, `proposal_applied`, `email_send_proposal`, `datasheet_filters_proposal`, `report_proposal`. - `content` (string, required): The reply's text, as the chat in the app shows it: what the agent did, its answer, or its questions. Empty until the agent has written it. When the reply failed or was stopped, it says so. Can contain Markdown. - `questions` (array of object): On a `clarification` reply: the multiple-choice questions the agent needs answered before it goes on. Send the options picked as `answers` in the next message on the same chat, or answer in your own words in `content`. Absent on other replies, and on a clarification that asks its question only in `content`. - `question` (string, required): The question the agent is asking, as the chat in the app shows it. - `header` (string, required): A short label for the question, such as `Chart type`, shown before it in the app. Send it back unchanged, with `question`, when you answer. - `multiSelect` (boolean, required): Whether more than one option can be picked. When `true`, the app shows the options as checkboxes; when `false`, as a single choice, so answer with one option. - `options` (array of object, required): The options to choose from. Answer with the `label` of each one picked. - `label` (string, required): The option's text, as shown in the app. Send it back in `answers` to pick this option. The agent may mark the option it recommends with `(Recommended)`, which you can keep or drop. - `description` (string): What picking this option means, shown under its label in the app. - `value` (string): Set when the option offers data the agent found: a connection for the agent to search next, or a dashboard, table or spreadsheet that Rollstack adds to the report as a datasheet when you pick the option. It isn't shown in the app, and you don't send it back: picking the option by its `label` in the next message on the same chat is enough. - `templateId` (string): Set when the option offers a saved template, by its `id` in `listTemplates`: the app shows the template's look. You don't send it back: picking the option by its `label` is enough. - `changedSlideIds` (array of string): On a `result` or `partial_result` reply: the slides the agent added or changed, in report order. Slides it deleted aren't listed. Pass them as `slideIds` to `getReportSlideImages` to check how they look, or to `getReportContent` to read them. - `versionBeforeId` (string): On a `result` or `partial_result` reply: the report's version saved just before the agent changed it. Restore it with `restoreReportVersion` to undo the reply, which also undoes any change made to the report since. - `proposal` (object): On a `settings_proposal` or `email_send_proposal` reply: what the proposal changes, or the email it sends, and where it stands. Absent on other replies. - Option 1 - `status` (string, required): `proposed` while it waits for the user to decide. `applied` once approved and applied, `rejected` once rejected. `superseded` when a later proposal in the chat replaced it. `conflict` when the report changed after it was proposed, so approving it applied nothing, and `failed` when applying it failed. One of `proposed`, `applying`, `applied`, `rejected`, `superseded`, `conflict`, `failed`. - `changes` (array of object, required): What approving it changes, as the approval card in the app shows it: one entry per change, with the setting before and after it. `warnings` point out what the user should know before approving, such as a schedule that never runs. - When `type` is `parameters.create` - `type` (`parameters.create`, required) - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.update` - `type` (`parameters.update`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.delete` - `type` (`parameters.delete`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.setDatasheetLinked` - `type` (`parameters.setDatasheetLinked`, required) - `parameterName` (string, required) - `filterName` (string, required) - `datasheetName` (string, required) - `isLinked` (boolean, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.create` - `type` (`email.template.create`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.update` - `type` (`email.template.update`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.select` - `type` (`email.template.select`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.reset` - `type` (`email.template.reset`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.add` - `type` (`schedule.add`, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.remove` - `type` (`schedule.remove`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.modify` - `type` (`schedule.modify`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.config.update` - `type` (`email.config.update`, required) - `before` (object or null, required) - `trigger` (string, required): One of `all`, `none`, `scheduled`. - `sharingFormat` (string, required): One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required) - `sender` (object or null, required) - `after` (object, required) - `trigger` (string, required): One of `all`, `none`, `scheduled`. - `sharingFormat` (string, required): One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required) - `sender` (object or null, required) - `id` (string, required) - `label` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.recipients.update` - `type` (`email.recipients.update`, required) - `before` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.recipients.createGroup` - `type` (`email.recipients.createGroup`, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - Option 2 - `status` (string, required): `awaiting_confirmation` while it waits for the user to decide, `cancelled` once rejected, and `superseded` when a later proposal in the chat replaced it. Once approved: `queued` and `sending` until every email is handed to the email provider, then `sent`, `partially_sent` or `failed`. `unconfirmed` when Rollstack lost track of the send, so some emails may have gone out. One of `awaiting_confirmation`, `cancelled`, `superseded`, `queued`, `sending`, `sent`, `partially_sent`, `failed`, `unconfirmed`. - `recipients` (array of object, required): Who receives the report: one email per group, each with its own addresses. - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `sharingFormat` (string, required): The file sent: the report's visible slides as a PDF (`pdf`) or PowerPoint file (`ppt`). One of `pdf`, `ppt`. - `sendAttachmentAsLink` (boolean, required): Whether the file is behind a download button in the email instead of attached. - `counts` (object or null, required): How many emails were handed to the email provider, failed, or ended unknown. `null` until the send starts. - `total` (integer, required) - `sent` (integer, required) - `failed` (integer, required) - `unknown` (integer, required) ### Cancel slides agent message `POST https://api.rollstack.com/public/v1/reports/{id}/messages/{messageId}/cancel` Stops a message to the slides agent: a queued one leaves the queue, and a running one stops. A finished one stays as it is. Only the user who sent it may. Requires the `slide_decks:run` scope. Operation ID: `cancelReportMessage`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `messageId` (string, required): The message to the slides agent: the `messageId` that `sendReportMessage` returned. Only the user who sent the message can read, cancel or decide its proposals, and only while they can edit the report. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Reject slides agent proposal `POST https://api.rollstack.com/public/v1/reports/{id}/messages/{messageId}/replies/{replyId}/reject` Rejects the proposal of a settings_proposal or email_send_proposal reply, as its Reject button in the app's chat does: nothing changes. Answers the reply with the proposal's status, rejected for a change and cancelled for an email send. Only the user who sent the message may, while they can edit the report. A proposal already decided answers 409. Requires the `slide_decks:run` scope. Operation ID: `rejectReportMessageProposal`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `messageId` (string, required): The message to the slides agent: the `messageId` that `sendReportMessage` returned. Only the user who sent the message can read, cancel or decide its proposals, and only while they can edit the report. - `replyId` (string, required): The reply that makes the proposal: the `id` of a `settings_proposal` or `email_send_proposal` reply that `getReportMessage` lists for the message. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `id` (string, required): Identifies the reply. It stays the same from `running` until the reply is finished, so you can follow each reply across calls. - `status` (string, required): Where this reply stands. `running` while the agent works on it or it waits its turn; on a `datasheet_filters_proposal`, until Rollstack has applied the filters. `completed` once the reply is finished: `type` says what it is. `failed` when the agent couldn't finish it, never got to it because an earlier part failed or was stopped, or the filters couldn't be applied. `cancelled` when it was stopped, for example with `cancelReportMessage` or the stop button in the app. One of `running`, `completed`, `failed`, `cancelled`. - `type` (string or null, required): What the reply is, which tells you what to do next. `null` while the agent is still working on it, and when it failed or was stopped. - `result`: the agent changed the report, and the changes are already saved. `changedSlideIds` lists the slides it added or changed; `versionBeforeId` undoes them with `restoreReportVersion`, and they can also be reviewed or reverted in the app. - `partial_result`: the same as `result`, on replies written by an earlier version of the slides agent. - `clarification`: the agent needs more from you before it goes on. Answer its `questions`, or the question in `content` when there are none, in the next message on the same chat. - `answer`: the agent replied in `content` without changing the report, for example to a question about the report or about how Rollstack works. - `datasheet_filters_proposal`: the agent changes the values of filters that some of the report's datasheets apply when they read their source. For a message sent through the API, Rollstack applies them right away, without approval in the app. If your request needed more than that, it then goes on by itself as a new message in the same chat, unless you send one there first; that message isn't in these `replies`, so follow it in the app. - `settings_proposal`, `email_send_proposal`: a change to the report's update schedules, email settings, email template or parameters, or sending the report by email. Nothing changes until it is approved: show the user what `proposal` changes, then approve it with `approveReportMessageProposal` or reject it with `rejectReportMessageProposal`, as they decide. It can also be decided in the app. The agent makes one for a message sent through the API only when your API key has the scope the change needs. - `report_proposal`: a change elsewhere in Rollstack, such as to reports, folders or members. The agent doesn't make them for messages sent through the API. - `proposal_applied`: a note the chat in the app adds once a proposal is decided. It is never listed in `replies`. One of `result`, `partial_result`, `clarification`, `answer`, `settings_proposal`, `proposal_applied`, `email_send_proposal`, `datasheet_filters_proposal`, `report_proposal`. - `content` (string, required): The reply's text, as the chat in the app shows it: what the agent did, its answer, or its questions. Empty until the agent has written it. When the reply failed or was stopped, it says so. Can contain Markdown. - `questions` (array of object): On a `clarification` reply: the multiple-choice questions the agent needs answered before it goes on. Send the options picked as `answers` in the next message on the same chat, or answer in your own words in `content`. Absent on other replies, and on a clarification that asks its question only in `content`. - `question` (string, required): The question the agent is asking, as the chat in the app shows it. - `header` (string, required): A short label for the question, such as `Chart type`, shown before it in the app. Send it back unchanged, with `question`, when you answer. - `multiSelect` (boolean, required): Whether more than one option can be picked. When `true`, the app shows the options as checkboxes; when `false`, as a single choice, so answer with one option. - `options` (array of object, required): The options to choose from. Answer with the `label` of each one picked. - `label` (string, required): The option's text, as shown in the app. Send it back in `answers` to pick this option. The agent may mark the option it recommends with `(Recommended)`, which you can keep or drop. - `description` (string): What picking this option means, shown under its label in the app. - `value` (string): Set when the option offers data the agent found: a connection for the agent to search next, or a dashboard, table or spreadsheet that Rollstack adds to the report as a datasheet when you pick the option. It isn't shown in the app, and you don't send it back: picking the option by its `label` in the next message on the same chat is enough. - `templateId` (string): Set when the option offers a saved template, by its `id` in `listTemplates`: the app shows the template's look. You don't send it back: picking the option by its `label` is enough. - `changedSlideIds` (array of string): On a `result` or `partial_result` reply: the slides the agent added or changed, in report order. Slides it deleted aren't listed. Pass them as `slideIds` to `getReportSlideImages` to check how they look, or to `getReportContent` to read them. - `versionBeforeId` (string): On a `result` or `partial_result` reply: the report's version saved just before the agent changed it. Restore it with `restoreReportVersion` to undo the reply, which also undoes any change made to the report since. - `proposal` (object): On a `settings_proposal` or `email_send_proposal` reply: what the proposal changes, or the email it sends, and where it stands. Absent on other replies. - Option 1 - `status` (string, required): `proposed` while it waits for the user to decide. `applied` once approved and applied, `rejected` once rejected. `superseded` when a later proposal in the chat replaced it. `conflict` when the report changed after it was proposed, so approving it applied nothing, and `failed` when applying it failed. One of `proposed`, `applying`, `applied`, `rejected`, `superseded`, `conflict`, `failed`. - `changes` (array of object, required): What approving it changes, as the approval card in the app shows it: one entry per change, with the setting before and after it. `warnings` point out what the user should know before approving, such as a schedule that never runs. - When `type` is `parameters.create` - `type` (`parameters.create`, required) - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.update` - `type` (`parameters.update`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `after` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.delete` - `type` (`parameters.delete`, required) - `before` (object, required) - `name` (string, required) - `value` (string, required) - `filters` (array of object, required) - `name` (string, required) - `dashboardName` (string, required) - `datasheets` (array of string, required): Defaults to `[]`. - `datasheetCount` (integer, required) - `unlinkedDatasheets` (array of string, required) - `columns` (array of object, required): Defaults to `[]`. - `datasheetName` (string, required) - `column` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `parameters.setDatasheetLinked` - `type` (`parameters.setDatasheetLinked`, required) - `parameterName` (string, required) - `filterName` (string, required) - `datasheetName` (string, required) - `isLinked` (boolean, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.create` - `type` (`email.template.create`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.update` - `type` (`email.template.update`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.select` - `type` (`email.template.select`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.template.reset` - `type` (`email.template.reset`, required) - `before` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `after` (object or null, required) - `id` (string or null, required) - `name` (string or null, required) - `subject` (string, required) - `content` (string, required) - `button` (object, required) - `textColor` (string, required) - `bgColor` (string, required) - `editable` (boolean, required) - `impact` (object or null, required) - `consumers` (array of string, required) - `anonymousCount` (integer, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.add` - `type` (`schedule.add`, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.remove` - `type` (`schedule.remove`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `schedule.modify` - `type` (`schedule.modify`, required) - `before` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `after` (object, required) - `frequency` (string, required) - `recurrence` (string, required) - `timezone` (string, required) - `startDate` (string, required) - `endDate` (string or null, required) - `syncNames` (array of string or null, required) - `nextRunAt` (string or null, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.config.update` - `type` (`email.config.update`, required) - `before` (object or null, required) - `trigger` (string, required): One of `all`, `none`, `scheduled`. - `sharingFormat` (string, required): One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required) - `sender` (object or null, required) - `after` (object, required) - `trigger` (string, required): One of `all`, `none`, `scheduled`. - `sharingFormat` (string, required): One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required) - `sender` (object or null, required) - `id` (string, required) - `label` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.recipients.update` - `type` (`email.recipients.update`, required) - `before` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - When `type` is `email.recipients.createGroup` - `type` (`email.recipients.createGroup`, required) - `after` (object, required) - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `warnings` (array of object, required) - `code` (string, required): One of `duplicate-schedule`, `never-runs`, `distant-next-run`, `skips-short-months`, `scheduled-email-stops`, `scheduled-delivery-without-schedule`, `no-recipients`, `template-shared`, `template-sends-pending`, `overwrites-datasheet-values`, `datasheets-keep-last-value`. - `message` (string, required) - Option 2 - `status` (string, required): `awaiting_confirmation` while it waits for the user to decide, `cancelled` once rejected, and `superseded` when a later proposal in the chat replaced it. Once approved: `queued` and `sending` until every email is handed to the email provider, then `sent`, `partially_sent` or `failed`. `unconfirmed` when Rollstack lost track of the send, so some emails may have gone out. One of `awaiting_confirmation`, `cancelled`, `superseded`, `queued`, `sending`, `sent`, `partially_sent`, `failed`, `unconfirmed`. - `recipients` (array of object, required): Who receives the report: one email per group, each with its own addresses. - `to` (array of string, required) - `cc` (array of string, required) - `bcc` (array of string, required) - `replyTo` (array of string, required) - `id` (string, required) - `label` (string, required) - `sharingFormat` (string, required): The file sent: the report's visible slides as a PDF (`pdf`) or PowerPoint file (`ppt`). One of `pdf`, `ppt`. - `sendAttachmentAsLink` (boolean, required): Whether the file is behind a download button in the email instead of attached. - `counts` (object or null, required): How many emails were handed to the email provider, failed, or ended unknown. `null` until the send starts. - `total` (integer, required) - `sent` (integer, required) - `failed` (integer, required) - `unknown` (integer, required) ## Memories What the slides agent remembers of how you like your decks, such as your fiscal year or how you name regions, as in the Slides settings of the app. It learns them in your chats and reads them while your organization has slide memories on and you have it remember your preferences. They are yours alone: another member has their own. See them with `listMemories`, add one with `createMemory`, for all your reports or one of them, change one with `updateMemory` and forget one with `deleteMemory`. ### List memories `GET https://api.rollstack.com/public/v1/memories` What the slides agent remembers of how the user likes their decks, as the app's Slides settings list it: each memory, the part of a deck it is about, and the report it holds for, if only one. Read them before adding one, so as not to repeat one. Requires the `slide_decks:read` scope. Operation ID: `listMemories`. #### Response `200` Success `application/json` - `data` (array of object, required): What the slides agent remembers of how you like your decks, newest first: what it learned in your chats and what you added. They are yours alone, and the agent reads them while your organization has slide memories on and you have it remember your preferences, in the app. - `id` (string, required): Identifies the memory. Pass it as `memoryId` to `updateMemory` or `deleteMemory`. - `text` (string, required): What the slides agent remembers, such as `Our fiscal year starts in February`. - `category` (string, required): The part of a deck it is about, so each agent reads the ones it acts on. One you add is `text`. One of `structure`, `titles`, `text`, `numbers`, `charts`, `design`, `workflow`. - `report` (object or null, required): The report it holds for. `null` when it holds for all your reports. - `id` (string, required): The report's `id`. - `name` (string, required): The report's name. - `updatedAt` (string, required): When it was last learned or changed, as an ISO 8601 date and time. ### Add memory `POST https://api.rollstack.com/public/v1/memories` Has the slides agent remember something of how the user likes their decks, for all their reports or one of them, as adding a preference in the app's Slides settings does. Only add what the user asked to be remembered. Answers the memory. Requires the `slide_decks:write` scope. Operation ID: `createMemory`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `text` (string, required): What the slides agent should remember, as one plain sentence, at most 300 characters. Example: `Our fiscal year starts in February`. - `reportId` (string or null): The report the memory holds for, by its `id` from `listReports`, which you must be able to edit. `null` for all your reports. Defaults to `null`. #### Response `201` Success `application/json` - `id` (string, required): Identifies the memory. Pass it as `memoryId` to `updateMemory` or `deleteMemory`. - `text` (string, required): What the slides agent remembers, such as `Our fiscal year starts in February`. - `category` (string, required): The part of a deck it is about, so each agent reads the ones it acts on. One you add is `text`. One of `structure`, `titles`, `text`, `numbers`, `charts`, `design`, `workflow`. - `report` (object or null, required): The report it holds for. `null` when it holds for all your reports. - `id` (string, required): The report's `id`. - `name` (string, required): The report's name. - `updatedAt` (string, required): When it was last learned or changed, as an ISO 8601 date and time. ### Update memory `PATCH https://api.rollstack.com/public/v1/memories/{memoryId}` Rewords a memory of the slides agent, or moves it to one report or all of them. What you send changes and the rest stays. Answers the memory. Requires the `slide_decks:write` scope. Operation ID: `updateMemory`. #### Path parameters - `memoryId` (string, required): The memory to act on, by its `id` from `listMemories`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `text` (string): What the slides agent should remember, as one plain sentence, at most 300 characters. Example: `Our fiscal year starts in February`. - `reportId` (string or null): The report the memory holds for, by its `id` from `listReports`, which you must be able to edit. `null` for all your reports. If omitted, it stays. #### Response `200` Success `application/json` - `id` (string, required): Identifies the memory. Pass it as `memoryId` to `updateMemory` or `deleteMemory`. - `text` (string, required): What the slides agent remembers, such as `Our fiscal year starts in February`. - `category` (string, required): The part of a deck it is about, so each agent reads the ones it acts on. One you add is `text`. One of `structure`, `titles`, `text`, `numbers`, `charts`, `design`, `workflow`. - `report` (object or null, required): The report it holds for. `null` when it holds for all your reports. - `id` (string, required): The report's `id`. - `name` (string, required): The report's name. - `updatedAt` (string, required): When it was last learned or changed, as an ISO 8601 date and time. ### Forget memory `DELETE https://api.rollstack.com/public/v1/memories/{memoryId}` Has the slides agent forget a memory: its runs stop reading it, as forgetting it in the app's Slides settings does. Requires the `slide_decks:write` scope. Operation ID: `deleteMemory`. #### Path parameters - `memoryId` (string, required): The memory to act on, by its `id` from `listMemories`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Runs Update a report from its sources. A run reads every datasheet again, or only the ones you pass, recalculates the report's numbers, and repairs with AI the calculations and slides the new data broke. Schedules start the same run. On a report whose `type` isn't `SlideDeck`, a run refreshes every visualization instead, as Update in the app does. It updates the report's file, such as a Google Slides presentation; an `Email` report has no file. Recipients get the report by email when its email trigger is `all`. Its `errors` then name the visualizations it could not refresh. Start a run, then follow it with `getReportRun` until it ends. A report runs once at a time: starting a run while one is going answers that run instead. ### List report runs `GET https://api.rollstack.com/public/v1/reports/{id}/runs` The runs of a report of any type that ended, newest first, with how each ended, what started it and why it failed, for questions such as why last night's update failed. Answers up to limit runs, 20 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listReportRuns`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Query parameters - `limit` (integer): Maximum number of runs to return on this page, from 1 to 200. Defaults to `20`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The report's runs that ended, newest first, whoever started them: in the app, through the API or on a schedule. A run still going isn't listed until it ends: `running` in `getReport` says whether one is, and `getReportRun` follows the one `startReportRun` started. - `id` (string, required): Identifies the run in the history. - `status` (string, required): How the run ended. - `succeeded`: it refreshed everything. - `partiallySucceeded`: it refreshed some of the report and failed the rest, which kept its previous data. - `failed`: nothing could be refreshed, or the run stopped on an error. `error` says why. - `cancelled`: it was stopped before it finished. - `skipped`: it had nothing to refresh, such as a report with no datasheets, or a variant no longer valid for its burst. - `inactive`: nothing it could refresh was active. One of `succeeded`, `partiallySucceeded`, `failed`, `cancelled`, `inactive`, `skipped`. - `trigger` (string, required): `scheduled` when one of the report's schedules started it; `manual` when someone started it, in the app, with `startReportRun`, or by approving an update the slides agent proposed. One of `manual`, `scheduled`. - `startedBy` (object or null, required): The member whose run it was. `null` if their account was deleted. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `startedAt` (string (date-time), required): When the run started. - `finishedAt` (string (date-time), required): When the run ended. - `error` (string or null, required): Why the run failed or stopped, as shown in the app. `null` when the run recorded no error. - `failedVisualizations` (array of object, required): On a report whose `type` isn't `SlideDeck`, up to 20 visualizations the run could not refresh, with the reason; they kept their previous data. Always empty on a `SlideDeck` report, whose runs don't record their datasheets: `listReportDatasheets` gives each datasheet's `error` from its latest update. - `name` (string, required) - `message` (string, required) - `updatedSlidesCount` (number or null, required): How many slides the run changed. `null` when the run did not count them. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of runs. `null` when there are no more. ### Start report run `POST https://api.rollstack.com/public/v1/reports/{id}/runs` Refreshes a report's data, or only some of its datasheets, then repairs failed calculations and the slides with AI. On a report of another type than SlideDeck, such as a Google Slides presentation, refreshes every sync, or only the `syncIds` given, instead, as Update in the app does, updating its file when it has one (an Email report has none). A run of the whole report then emails it when its email trigger is `all`; a run of only some `syncIds` never does. Answers the run's id at once; while a run of the report is already going, from the API, the app or its schedule, it answers that run's id with started false and starts nothing. Pass repairSlides false to leave the slides as they are, when you wrote them yourself and will check and fix them. From an AI client, a run that emails the report only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:run` scope. Operation ID: `startReportRun`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `datasheetIds` (array of string (uuid)): The datasheets to update, from `listReportDatasheets`, instead of the whole report. Each must be a datasheet of this report. Unlike a run of the whole report, which reads every source again, a run of only some datasheets reuses the data last read from their sources: it reads a source again only if that data is missing or expired, or what the datasheet reads has changed, such as its source, its filters or the connection it reads with, as when you replace an uploaded file with `replaceDataset`. If omitted, the run updates the whole report. 1 to 500 ids. Only on reports whose `type` is `SlideDeck`: a report of another type has syncs instead, so passing it returns `400`. - `syncIds` (array of string (uuid)): The syncs to update, from `listReportSyncs`, instead of the whole report, such as the ones whose `status` is `failed`. Each must be a sync of this report. A `paused` sync is skipped, as in the app. A run of only some syncs never emails the report. If omitted, the run updates the whole report. 1 to 500 ids. Only on reports other than `SlideDeck`, which has datasheets instead, so passing it on a slide deck returns `400`. - `repairSlides` (boolean): Whether Rollstack repairs the slides with AI once the data is in: failed calculations, and text the new data made wrong. Pass `false` to read the data only, when you check and fix the slides yourself. If omitted, the slides are repaired. Only on reports whose `type` is `SlideDeck`. #### Response `202` Success `application/json` - `runId` (string, required): Identifies the run. Pass it as `runId` to `getReportRun` to follow the run until it ends, or to `cancelReportRun` to stop it. - `started` (boolean, required): Whether this request started a new run. `false` when a run of the report was already in progress, whoever started it: through the API, in the app or on one of its schedules. In that case nothing new starts, `datasheetIds` and `syncIds` are ignored, and `runId` is that run's id. To run the report with your request, wait for that run to end with `getReportRun`, then call `startReportRun` again. ### Get report run `GET https://api.rollstack.com/public/v1/reports/{id}/runs/{runId}` A run's status and the datasheets, or visualizations on a report of another type than SlideDeck, it could not refresh. Waits up to waitSeconds for the run to end and answers as soon as it does, so call it again while the status is running. A user's later run of the report reuses the id, so this describes the latest one. Requires the `slide_decks:read` scope. Operation ID: `getReportRun`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. - `runId` (string, required): The run, by the `runId` that `startReportRun` returned. Runs of a report started by the same member share one id, so it always refers to that member's latest run of the report. #### Query parameters - `waitSeconds` (integer): How long this call waits for the work to finish, in seconds: the message to the slides agent on `getReportMessage`, the run on `getReportRun`, the batch of variants being added on `getBurstVariantBatch`, the runs of a burst's variants on `getBurstRun`. It returns as soon as the work is done, or as things stand once the time is up, so call it again while `status` is still `queued` or `running`. `0` returns at once. Defaults to `20`; at most `30`. Defaults to `20`. #### Response `200` Success `application/json` - `runId` (string, required): Identifies the run, as returned by `startReportRun`. - `status` (string, required): Where the run stands. It stays `running` until the run ends, then says how it ended. - `running`: the run is still updating the report. Call `getReportRun` again to keep waiting. - `completed`: the run finished. Datasheets, or visualizations on a report of another type than `SlideDeck`, it could not refresh, if any, keep their previous data and are listed in `errors`. - `failed`: nothing could be refreshed, or the run stopped on an error. `errors` lists the datasheets or visualizations it could not refresh. - `cancelled`: the run was stopped before it finished, for example with `cancelReportRun` or "Cancel update" in the app. Datasheets and visualizations it had already refreshed keep their new data. - `timed_out`: the run went past its time limit and was stopped. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `startedAt` (string (date-time), required): When the run started. - `finishedAt` (string (date-time) or null, required): When the run ended, whatever its outcome. `null` while it is `running`. - `errors` (array of object, required): The datasheets, or visualizations on a report of another type than `SlideDeck`, the run could not refresh, each with the reason. While the run is `running`, those that have failed so far; on a `SlideDeck` report, once the run has `failed`, also those it had not finished. Empty when nothing failed. To run only these datasheets again, pass their ids as `datasheetIds` to `startReportRun`. - `datasheetId` (string or null, required): The datasheet that could not be refreshed, as `id` in `listReportDatasheets`. `null` on a report of another type than `SlideDeck`, whose runs refresh visualizations instead: `name` then names the visualization. - `name` (string, required): The datasheet's or visualization's name, as shown in the app. The report's own name when a run of a report of another type than `SlideDeck` failed as a whole, with no visualization to blame. - `message` (string, required): Why it could not be refreshed, for example an error reading its source or computing its data. Empty when no reason was recorded. ### List report syncs `GET https://api.rollstack.com/public/v1/reports/{id}/syncs` The syncs of a report other than a SlideDeck, such as a Google Slides presentation or an email report: each chart, table or text it pulls from a source, with how it did the last time it updated and why it failed. Pass the failed ones' ids as `syncIds` to `startReportRun` to update only those. A SlideDeck report has datasheets instead and returns `400`. Requires the `slide_decks:read` scope. Operation ID: `listReportSyncs`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the sync. Pass it in `syncIds` to `startReportRun` to update only some syncs, or to `updateReportSchedules` for a schedule that updates only some. - `name` (string, required): The sync's name, as shown in the report's Syncs tab in Rollstack. - `sourceType` (string, required): Where the sync gets its data, such as `Tableau`, `Looker` or `GoogleSheets`. One of `GoogleSheet`, `GoogleExcel`, `MicrosoftExcel`, `Tableau`, `Salesforce`, `Metabase`, `PowerBI`, `Looker`, `RollstackVariable`, `Lightdash`, `Omni`, `Sigma`, `Snowflake`, `Databricks`, `BigQuery`, `CsvUpload`, `XlsxUpload`, `ManualTable`, `Dbt`. - `status` (string, required): How the sync did the last time it updated: `succeeded`, `partiallySucceeded` or `failed`. `draft` for a sync that hasn't updated yet, `active` while it updates, and `inactive` when a check before the run stopped it, such as a source the owner can no longer reach. One of `active`, `draft`, `succeeded`, `partiallySucceeded`, `failed`, `inactive`. - `error` (object or null, required): Why the last update failed or was stopped. `null` when the sync succeeded or never updated. - `code` (string or null, required): Why the sync failed, such as `dashboard_not_found`. One of `tableau_view_not_found`, `dashboard_not_found`, `dashboard_tab_not_found`, `dashboard_not_ready`, `dashboard_has_errors`, `dashboard_invalid_layout`, `metabase_element_not_found`, `looker_element_not_found`, `element_not_found`, `google_slide_not_found`, `slide_not_found`, `file_not_found`, `sheet_not_found`, `sheet_hidden`, `range_not_found`, `duplicate_file_failed`, `merged_range_on_filter_range`, `insufficient_permissions`, `image_cropping_failed`, `visualization_not_found`, `visualization_not_ready`, `visualization_has_errors`, `visualization_empty`, `invalid_credentials`, `missing_credentials`, `instance_unavailable`, `column_not_found`, `empty_data`, `fetch_summary_data_error`, `fetch_visual_specification_error`, `incorrect_data_structure`, `missing_data`, `missing_formatted_value`, `malformed_data`, `viz_not_ready`, `worksheet_not_found`, `sync_not_found`, `file_update_failed`, `internal_server_error`. - `details` (string or null, required): More about the failure, as the app shows it. - `slideIndex` (number or null, required): Where the sync is in the file, as the 0-based index of its slide or page. `null` when it has no fixed place, such as an email report. - `paused` (boolean, required): Whether the sync is turned off, so runs skip it until it is turned on again in the app. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the sync last updated successfully. `null` if it never has. ### List runs of all reports `GET https://api.rollstack.com/public/v1/runs` The runs that ended of every report the user can see, of any type, newest first, each with its report, for questions such as what failed overnight: pass status failed and since. Same fields as listReportRuns. Answers up to limit runs, 20 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listRuns`. #### Query parameters - `limit` (integer): Maximum number of runs to return on this page, from 1 to 200. Defaults to `20`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. - `status` (string): Only the runs that ended this way, such as `failed`, as `status` in the runs. If omitted, every run. One of `succeeded`, `partiallySucceeded`, `failed`, `cancelled`, `inactive`, `skipped`. - `since` (string (date-time)): Only what happened at or after this time, as an ISO 8601 date and time in UTC, such as `2026-11-08T18:00:00Z`. If omitted, from the start. Example: `2026-11-08T18:00:00Z`. #### Response `200` Success `application/json` - `data` (array of object, required): The runs that ended of every report you can see, of any type, newest first, whoever started them. To find what failed overnight, pass `status` `failed` and `since`. A run still going isn't listed until it ends. - `id` (string, required): Identifies the run in the history. - `status` (string, required): How the run ended. - `succeeded`: it refreshed everything. - `partiallySucceeded`: it refreshed some of the report and failed the rest, which kept its previous data. - `failed`: nothing could be refreshed, or the run stopped on an error. `error` says why. - `cancelled`: it was stopped before it finished. - `skipped`: it had nothing to refresh, such as a report with no datasheets, or a variant no longer valid for its burst. - `inactive`: nothing it could refresh was active. One of `succeeded`, `partiallySucceeded`, `failed`, `cancelled`, `inactive`, `skipped`. - `trigger` (string, required): `scheduled` when one of the report's schedules started it; `manual` when someone started it, in the app, with `startReportRun`, or by approving an update the slides agent proposed. One of `manual`, `scheduled`. - `startedBy` (object or null, required): The member whose run it was. `null` if their account was deleted. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `startedAt` (string (date-time), required): When the run started. - `finishedAt` (string (date-time), required): When the run ended. - `error` (string or null, required): Why the run failed or stopped, as shown in the app. `null` when the run recorded no error. - `failedVisualizations` (array of object, required): On a report whose `type` isn't `SlideDeck`, up to 20 visualizations the run could not refresh, with the reason; they kept their previous data. Always empty on a `SlideDeck` report, whose runs don't record their datasheets: `listReportDatasheets` gives each datasheet's `error` from its latest update. - `name` (string, required) - `message` (string, required) - `updatedSlidesCount` (number or null, required): How many slides the run changed. `null` when the run did not count them. - `report` (object, required): The report the run updated. - `id` (string, required): The report's `id`, to pass to the `/reports/{id}` endpoints, such as `getReport`. - `name` (string or null, required): The report's name. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of runs. `null` when there are no more. ### Cancel report run `POST https://api.rollstack.com/public/v1/reports/{id}/runs/{runId}/cancel` Cancels a run of a report, whoever started it. Only its editors may. A run that already ended stays as it is. Requires the `slide_decks:run` scope. Operation ID: `cancelReportRun`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. - `runId` (string, required): The run, by the `runId` that `startReportRun` returned. Runs of a report started by the same member share one id, so it always refers to that member's latest run of the report. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Exports Download a report as a PDF or a PowerPoint file, as viewers see it. The export answers a link to the file, valid for 15 minutes, so download it right away. Exports render the whole report, so they have a lower rate limit than other calls. To keep a copy in Google Drive, OneDrive or SharePoint that stays up to date, set the report's cloud save with `updateReportCloudExport`: its runs then save it to the folder you choose, and `getReportCloudExport` tells how the last save went. ### Get cloud save `GET https://api.rollstack.com/public/v1/reports/{id}/cloud-export` Where a report is saved after its runs, in Google Drive, OneDrive or SharePoint, and how its last save went, with a link to the saved file. Answers 404 until it is set up with updateReportCloudExport or in the app's scheduling panel. Requires the `slide_decks:read` scope. Operation ID: `getReportCloudExport`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Response `200` Success `application/json` - `provider` (string, required): Where the report is saved: `google` saves it to Google Drive as a Google Slides presentation, with its charts as linked Google Sheets charts, and `microsoft` saves it to OneDrive or SharePoint as a PowerPoint file with native charts. One of `google`, `microsoft`. - `folder` (object, required): The folder the report is saved in. - `id` (string, required): The folder's id in Google Drive, OneDrive or SharePoint. - `name` (string, required): The folder's name. - `fileName` (string, required): The saved file's name. - `trigger` (string, required): Which runs save it: `all` after every run that doesn't fail, `scheduled` only after the report's scheduled runs, and `none` never, which stops saving it and keeps the setting. One of `all`, `scheduled`, `none`. - `updateMethod` (string, required): `update` replaces the saved file with the new version. `archive` first copies the saved file, named with the date of its last save in `datestampSuffix`, then replaces it. One of `update`, `archive`, `updateVisualizations`. - `datestampSuffix` (string, required): How `archive` dates the copies it keeps, as a moment.js format such as `MM/DD/YYYY` or `YYYY-MM-DD`. - `ignoreFailuresOnArchive` (boolean, required): With `archive`, whether a copy that fails still lets the save go on. - `fileUrl` (string or null, required): A link to the saved file, which its sharing in Google Drive, OneDrive or SharePoint lets people open. `null` until it is first saved. - `runsAsUserId` (number, required): The member whose Google or Microsoft account saves it, as `id` in `listMembers`: the one who last chose its folder. - `lastStatus` (string or null, required): Whether the last save worked. `null` until it is first saved. A failed one emails the member it runs as. One of `success`, `failed`. - `lastStatusMessage` (string or null, required): Why the last save failed. `null` when it worked. - `lastExportedAt` (string (date-time) or null, required): When the report was last saved. `null` until it is first saved. ### Set cloud save `PUT https://api.rollstack.com/public/v1/reports/{id}/cloud-export` Saves a report to a Google Drive, OneDrive or SharePoint folder after its runs, as the app's scheduling panel does, replacing the setting it had. Each save replaces the same file, or archives a dated copy first with `archive`. The folder is opened with the user's own Google or Microsoft account, which saves the report from then on. To save it now, start a run with startReportRun: a run that doesn't fail then tries to save it when `trigger` is `all`, and getReportCloudExport tells whether the save worked, since a failed save doesn't fail the run. Set `trigger` to `none` to stop saving it. Only its editors may. Requires the `slide_decks:write` scope. Operation ID: `updateReportCloudExport`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `provider` (string, required): Where the report is saved: `google` saves it to Google Drive as a Google Slides presentation, with its charts as linked Google Sheets charts, and `microsoft` saves it to OneDrive or SharePoint as a PowerPoint file with native charts. One of `google`, `microsoft`. - `folderUrl` (string, required): The folder to save the report in, by its link: a Google Drive folder's link (or its id) with `google`, or a OneDrive or SharePoint folder's link with `microsoft`. It's opened with your own Google or Microsoft account connected to Rollstack, which then saves the report, so you must be able to add files to it. Example: `https://drive.google.com/drive/folders/1AbCdEfGh`. - `fileName` (string): The saved file's name. If omitted, the report's name. - `trigger` (string, required): Which runs save it: `all` after every run that doesn't fail, `scheduled` only after the report's scheduled runs, and `none` never, which stops saving it and keeps the setting. One of `all`, `scheduled`, `none`. - `updateMethod` (string): `update` replaces the saved file with the new version. `archive` first copies the saved file, named with the date of its last save in `datestampSuffix`, then replaces it. Defaults to `update`. One of `update`, `archive`. - `datestampSuffix` (string): How `archive` dates the copies it keeps, as a moment.js format such as `MM/DD/YYYY` or `YYYY-MM-DD`. Defaults to `MM/DD/YYYY`. - `ignoreFailuresOnArchive` (boolean): With `archive`, whether a copy that fails still lets the save go on. Defaults to `false`. #### Response `200` Success `application/json` - `provider` (string, required): Where the report is saved: `google` saves it to Google Drive as a Google Slides presentation, with its charts as linked Google Sheets charts, and `microsoft` saves it to OneDrive or SharePoint as a PowerPoint file with native charts. One of `google`, `microsoft`. - `folder` (object, required): The folder the report is saved in. - `id` (string, required): The folder's id in Google Drive, OneDrive or SharePoint. - `name` (string, required): The folder's name. - `fileName` (string, required): The saved file's name. - `trigger` (string, required): Which runs save it: `all` after every run that doesn't fail, `scheduled` only after the report's scheduled runs, and `none` never, which stops saving it and keeps the setting. One of `all`, `scheduled`, `none`. - `updateMethod` (string, required): `update` replaces the saved file with the new version. `archive` first copies the saved file, named with the date of its last save in `datestampSuffix`, then replaces it. One of `update`, `archive`, `updateVisualizations`. - `datestampSuffix` (string, required): How `archive` dates the copies it keeps, as a moment.js format such as `MM/DD/YYYY` or `YYYY-MM-DD`. - `ignoreFailuresOnArchive` (boolean, required): With `archive`, whether a copy that fails still lets the save go on. - `fileUrl` (string or null, required): A link to the saved file, which its sharing in Google Drive, OneDrive or SharePoint lets people open. `null` until it is first saved. - `runsAsUserId` (number, required): The member whose Google or Microsoft account saves it, as `id` in `listMembers`: the one who last chose its folder. - `lastStatus` (string or null, required): Whether the last save worked. `null` until it is first saved. A failed one emails the member it runs as. One of `success`, `failed`. - `lastStatusMessage` (string or null, required): Why the last save failed. `null` when it worked. - `lastExportedAt` (string (date-time) or null, required): When the report was last saved. `null` until it is first saved. ### Export report `POST https://api.rollstack.com/public/v1/reports/{id}/exports` Exports a report as PDF or PowerPoint and answers a download link valid for 15 minutes. At most 10 exports a minute per user. Requires the `slide_decks:read` scope. Operation ID: `exportReport`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `format` (string, required): The kind of file to create. `pdf` is a PDF of the report's visible slides; hidden slides are left out. `pptx` is a PowerPoint file in which hidden slides are included but stay hidden, speaker notes are kept, and charts are images rather than editable charts. One of `pdf`, `pptx`. - `slideIds` (array of string): The slides to export, from `getReportContent` or a reply's `changedSlideIds`. The file keeps the report's slide order whatever order you list them in. Ids that are not slides of the report are ignored, and so are hidden slides in a PDF. If omitted, the whole report is exported. #### Response `200` Success `application/json` - `url` (string, required): A link that downloads the exported file, named after the report. Anyone who has the link can download the file, without an API key, until `expiresAt`. - `expiresAt` (string (date-time), required): When `url` stops working, 15 minutes after the export. Export the report again to get a new link. ## Content What viewers see on a report, for reading or checking it without downloading a file. `getReportContent` answers the text of each visible slide and the values in its charts and tables. `getReportSlideImages` renders slides as images, to check their layout. Both take slide ids, so after a message to the slides agent you can look at only the slides it changed. ### Get report content `GET https://api.rollstack.com/public/v1/reports/{id}/content` What a viewer sees on a report's visible slides: titles, text, and each chart's and table's values. On a long report, pass slideIds for only the slides you need, such as a reply's changedSlideIds. Requires the `slide_decks:read` scope. Operation ID: `getReportContent`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Query parameters - `slideIds` (string or array of string): The slides to return, from a reply's `changedSlideIds` or an earlier `getReportContent` call. If omitted, every visible slide is returned. Hidden slides and ids that are not slides of the report are ignored. Up to 20 ids: repeat the parameter for each one, as in `?slideIds=a&slideIds=b`. Example: `f1e2d3c4-b5a6-4978-8a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `slides` (array of object, required): The report's visible slides in report order, or only those in `slideIds`. Hidden slides are never included. - `index` (number, required): The slide's position in the report as viewers see it, counting only visible slides and starting at `0`. It stays the same when `slideIds` narrows the list. - `id` (string, required): Identifies the slide. Pass it in `slideIds` to `getReportSlideImages` or `exportReport`, or to `sendReportMessage` to tell the slides agent which slides your message is about. - `title` (string or null, required): The slide's title: the text in its title box. `null` when the slide has no title box, or the box is empty. - `texts` (array of string, required): The text of each text box and shape on the slide, title included. Text from the slide's master and layout is left out, and so are empty boxes. - `charts` (array of object, required): The charts on the slide, with the data each one shows. - `title` (string or null, required): The chart title shown on the slide. `null` when the chart has no title, and always for a table. - `type` (string, required): What kind of chart it is: `bar`, `line` or `pie`. A chart that combines kinds, such as bars with a line, takes the kind of its first series, and a chart with no series is `chart`. Always `table` for a table. - `values` (object, required): The data the chart or table shows, as `columns` and `rows`. - `columns` (array of string, required): The column headers: for a chart, the names of the data columns it draws; for a table, the text of its first row. - `rows` (array of array of string or number or null, required): The data, one array per row, with its values in the order of `columns`. A chart's numbers are raw values, before the chart's number format is applied; a table's cells are text. At most 200 rows; `truncated` says whether there were more. - `truncated` (boolean, required): Whether the chart or table has more than 200 rows, in which case `rows` contains only the first 200. - `tables` (array of object, required): The tables on the slide, with the text of their cells. A table's first row is returned as its `columns`, and the other rows as its `rows`. - `title` (string or null, required): The chart title shown on the slide. `null` when the chart has no title, and always for a table. - `type` (string, required): What kind of chart it is: `bar`, `line` or `pie`. A chart that combines kinds, such as bars with a line, takes the kind of its first series, and a chart with no series is `chart`. Always `table` for a table. - `values` (object, required): The data the chart or table shows, as `columns` and `rows`. - `columns` (array of string, required): The column headers: for a chart, the names of the data columns it draws; for a table, the text of its first row. - `rows` (array of array of string or number or null, required): The data, one array per row, with its values in the order of `columns`. A chart's numbers are raw values, before the chart's number format is applied; a table's cells are text. At most 200 rows; `truncated` says whether there were more. - `truncated` (boolean, required): Whether the chart or table has more than 200 rows, in which case `rows` contains only the first 200. ### Get report design `GET https://api.rollstack.com/public/v1/reports/{id}/design` Start here to design a slide deck's slides yourself, as HTML. A call without layoutIds answers the guide to writing a slide for this report, which you follow, and what a slide is drawn on: the canvas size, the theme colours and, when the report has a template, its layouts by name. Call it again with layoutIds for the layouts you will use, to get the box each one's title goes in and the areas to keep clear. Requires the `slide_decks:read` scope. Operation ID: `getReportDesign`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Query parameters - `layoutIds` (string or array of string): The layouts to describe in full, by their `id` from a first call without it. At most 10: repeat the parameter for each one, as in `?layoutIds=a&layoutIds=b`. Left out, only the template's style is described. #### Response `200` Success `application/json` - `canvas` (object, required): The report's slide size in CSS pixels. A slide's `
` is exactly this large. - `width` (number, required) - `height` (number, required) - `theme` (array of object, required): The report's theme colours. A slide uses these and no others. - `variable` (string, required): The CSS variable a slide names the colour by, as in `var(--accent1)`. - `hex` (string, required): The colour it stands for in this report. - `layouts` (array of object, required): The layouts of the report's template. Empty when the report has no template of its own: lay slides out freely then. - `id` (string, required): The id a slide names the layout by, as `data-layout-id` on its `
`. - `name` (string, required): The layout's name in the template. - `type` (string or null, required): The layout's kind in the template, such as `title` or `obj`, when it has one. - `layoutDetails` (string or null, required): How to write on the template, as Markdown: the type and colours its slides are set in, and for each layout named in `layoutIds` the box its title goes in, its other placeholders with their ids and boxes, and the areas to keep clear. Null when the report has no template of its own. - `guide` (string): How to write a slide for this report, as Markdown: the HTML a slide is made of, the styles that are kept, how to place charts, tables and figures from its datasheets, and how to check and save it. Read it before writing any slide. Only on a call without `layoutIds`. ### Get slide drafts `GET https://api.rollstack.com/public/v1/reports/{id}/slides/html` The HTML drafts slides of a slide deck were made from, to change them and save them again with saveReportSlides under the same ids. A slide changed in Rollstack since its draft was saved, by a person in the editor or by Rollstack's agent, answers the draft as it was saved with changedInRollstack, the list of what was changed since: make every one of those changes in the draft first, so the work done there is kept, then make your own. A slide made by hand in the editor has no draft (html is null): a draft sent under its id rewrites the whole slide, dropping what was done there, so look at it with getReportSlideImages and ask the user first. At most 10 slides a call. Requires the `slide_decks:read` scope. Operation ID: `getReportSlideHtml`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Query parameters - `slideIds` (string or array of string, required): The slides whose drafts to read, by their `id` from `getReportContent` or a reply's `changedSlideIds`, hidden ones included. Ids that are not slides of the report are ignored. 1 to 10 ids: repeat the parameter for each one, as in `?slideIds=a&slideIds=b`. Example: `f1e2d3c4-b5a6-4978-8a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `slides` (array of object, required): The slides asked for, in report order. Ids that are not slides of the report are left out. - `id` (string, required): The slide. - `html` (string or null, required): The draft the slide was made from, as one `
` of HTML. Null for a slide made by hand in the editor, which has none: a draft sent under its id rewrites the whole slide and drops what was done there. With `changedInRollstack`, the draft as it was saved, before those changes. - `changedInRollstack` (array of object): Only on a slide changed in Rollstack since its draft was saved, by a person in the editor or by Rollstack's agent: an entry per element changed, with `was` the element as the draft drew it and `now` as it stands. `reworded`: its text now reads `now.text`. `moved`: it sits in `now`'s box. `restyled`: its font, colour, fill or grouping changed, so look at it with `getReportSlideImages`. `removed` has no `now` and `added` no `was`. `html` is the draft as saved, so it has none of them: make each in the draft before saving it, or saving drops it. Empty when the slide shows what the draft says again. - `changes` (array of string, required) - `was` (object or null, required) - `kind` (string, required): What it is, such as `text`, `chart`, `table`, `data text`, `picture` or `shape`. - `text` (string, required): Its words, or the template of a data text. Empty for an element without words. - `left` (number or null, required): Its box in canvas px, as far as a draft sets it: null where a data update does. - `top` (number or null, required) - `width` (number or null, required) - `height` (number or null, required) - `rotation` (number or null, required): In degrees. - `now` (object or null, required) - `kind` (string, required): What it is, such as `text`, `chart`, `table`, `data text`, `picture` or `shape`. - `text` (string, required): Its words, or the template of a data text. Empty for an element without words. - `left` (number or null, required): Its box in canvas px, as far as a draft sets it: null where a data update does. - `top` (number or null, required) - `width` (number or null, required) - `height` (number or null, required) - `rotation` (number or null, required): In degrees. ### Get slide images `GET https://api.rollstack.com/public/v1/reports/{id}/slides/images` Renders slides of a report as images, as viewers see them, so you can check how they look: text that overflows or overlaps, or a chart too small to read. After a message's turn, pass its replies' changedSlideIds. At most 10 slides a call; hidden slides are left out. Counts against the 10 exports a minute per user. Requires the `slide_decks:read` scope. Operation ID: `getReportSlideImages`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Query parameters - `slideIds` (string or array of string, required): The slides to render, from `getReportContent` or a reply's `changedSlideIds`. Hidden slides and ids that are not slides of the report are ignored. 1 to 10 ids: repeat the parameter for each one, as in `?slideIds=a&slideIds=b`. Example: `f1e2d3c4-b5a6-4978-8a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `slides` (array of object, required): The rendered slides, in report order, whatever order `slideIds` lists them in. Hidden slides, and any slide that could not be rendered, are left out. - `id` (string, required): The slide the image shows, as passed in `slideIds`. - `mimeType` (`image/jpeg`, required): The format of the image. Always `image/jpeg`. - `data` (string (base64), required): The slide as viewers see it, as a JPEG image encoded in base64. ### Arrange slides `PATCH https://api.rollstack.com/public/v1/reports/{id}/slides` Moves, removes, hides or shows slides of a slide deck, with nothing on them changed. Read the slides' ids with getReportContent. order puts the slides in a new order and names every slide that stays, once each; remove takes slides out of the report; hide keeps a slide in the report but out of what is presented and exported, and show brings it back. Take the change back by restoring versionBeforeId with restoreReportVersion. Called with nothing to change, it answers every slide in order with whether it is hidden: getReportContent leaves hidden slides out. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `arrangeReportSlides`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `order` (array of string): The report's slides in their new order, by their `id` from `getReportContent`: every slide that stays, once each. Leave it out to keep the order. - `remove` (array of string): The slides to remove from the report, by their ids. - `hide` (array of string): The slides to hide, by their ids: they stay in the report and are left out when it is presented or exported. - `show` (array of string): The hidden slides to show again, by their ids. #### Response `200` Success `application/json` - `versionBeforeId` (string): The version saved just before the change: restore it with `restoreReportVersion` to take the change back. Absent when nothing changed. - `slides` (array of object, required): The report's slides after the change, in order. - `id` (string, required): The slide. - `hidden` (boolean, required): Whether the slide is hidden. ### Save draft slides `POST https://api.rollstack.com/public/v1/reports/{id}/slides` Writes slides you wrote as HTML into a slide deck, as the slides agent's are: a draft sent under the id of a slide of the report replaces that slide where it is, any other is added right after the slide named in afterSlideId, or at the end without one, and every other slide stays. To move, remove or hide slides, use arrangeReportSlides. Render them with renderReportSlides first: nothing is saved while a draft still has an issue, and the issues come back instead. A chart or table a draft places is filled with its datasheet's data as part of the save, with no change to the slides. Take the save back by restoring versionBeforeId with restoreReportVersion. Only the report's editors may. At most 10 drafts a call, and 20 renders and saves a minute per user. Requires the `slide_decks:write` scope. Operation ID: `saveReportSlides`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `slides` (array of object, required): The draft slides to save, 1 to 10 a call, each under an id of its own. - `id` (string, required): The id you give the slide: letters, digits, `_` and `-`, at most 64 characters. Pass an existing slide's id to redraw that slide. - `html` (string, required): The slide as one `
` of HTML, as large as the report's canvas. No scripts, embedded pages, event attributes or anything loaded from outside it. - `afterSlideId` (string): The slide of the report the new slides go right after, by its `id` from `getReportContent`. Without it they are added at the end. A draft sent under the id of a slide of the report replaces that slide where it is. #### Response `200` Success `application/json` - `saved` (boolean, required): Whether the drafts were written into the report. False while any of them still has an issue: nothing is written then. - `versionBeforeId` (string): The version of the report saved before this change. Restore it with `restoreReportVersion` to take the change back. - `conversionError` (string): Why the drafts could not be turned into slides, when one could not. Fix it and save again. - `slides` (array of object, required): The drafts, in the order they were sent. - `id` (string, required): The draft, by the id it was sent with. - `slideId` (string or null, required): The slide of the report the draft became: a new id for a new slide, the same id for a slide it replaced. Send a later draft under this id to change the slide. Null when nothing was saved. - `issues` (array of string, required): What to fix before the draft can be saved. - `notes` (array of string, required): What to check by eye. These block nothing. - `datasheets` (array of object, required): The datasheets whose charts and tables the save placed. Their data is read as part of the save, so the slides show it at once, unless the source is slow: then the save answers first and the data follows. - `id` (string, required): The datasheet. - `error` (string or null, required): Why its data is not on the slide: the read failed, or it is still running and the slide shows the data once it ends. Null when the data was read. ### Change theme `PATCH https://api.rollstack.com/public/v1/reports/{id}/theme` Changes a slide deck's theme: its colours, its heading font and its body font. This is how a deck takes a brand's colours, such as the ones the user names or the ones of a presentation they gave you: read the colours yourself and send each in the slot whose job it does. Every slide follows wherever it uses the theme's colours, and so do the template's layouts and the slides you write next, which keep using the theme variables that getReportDesign lists. Call it before you write slides, then call getReportDesign again for the colours as they are now. A slot sent with a colour another slot already has is saved one step of blue away from it (#2D6A4F and #2D6A50), which looks the same: saved slides tell theme colours apart by their value, so the answer can differ from what you sent by that step. A change that would leave text unreadable on its background changes nothing and answers the pair to fix, and so does a font the editor does not have. A new font sets text wider or narrower than the old one: on a deck that already has slides, look at each with getReportSlideImages afterwards and save again the ones whose text no longer fits. It changes colours and fonts only: for a presentation's layouts and logo, the user imports it as a template in Rollstack, which answers in listTemplates. Only the report's editors may. Answers the theme after the change and the version saved before it. Requires the `slide_decks:write` scope. Operation ID: `updateReportTheme`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `colors` (object): The theme colours to change, each as `#RRGGBB`. The ones left out stay as they are. Each has a job on the slides, so put a brand's colours where they belong: its dark text colour in `dark1`, its background in `light1`, its main brand colour in `accent1`. - `dark1` (string): Main text: titles and body text on the slide background. - `dark2` (string): Secondary text: captions, sources and muted labels, quieter than dark1 but readable. - `light1` (string): The slide background. - `light2` (string): The second surface: cards, panels and table header rows. Close to light1 but visibly different from it. - `accent1` (string): The main highlight: key numbers, accent bars and rules, the first chart series. - `accent2` (string): The second chart series and highlight. - `accent3` (string): The third chart series and highlight. - `accent4` (string): The fourth chart series and highlight. - `accent5` (string): The fifth chart series and highlight. - `accent6` (string): The sixth chart series and highlight. - `hyperlink` (string): Link text, readable on light1. - `followedHyperlink` (string): Visited link text, readable on light1. - `headingFont` (string): The font family for titles and headings, by its published name, such as `Inter`. A font the editor does not have is refused. - `bodyFont` (string): The font family for all other text, by its published name. #### Response `200` Success `application/json` - When `changed` is `true` - `changed` (`true`, required) - `versionBeforeId` (string, required): The version saved just before the change: restore it with `restoreReportVersion` to take the change back. - `colors` (object, required): The report's theme colours after the change, by slot, as `getReportDesign` lists them in `theme`. - `headingFont` (string, required): The font of titles and headings after the change. - `bodyFont` (string, required): The font of all other text after the change. - When `changed` is `false` - `changed` (`false`, required) - `refused` (string, required): `invalid`: fix what `reason` names and send the change again. `needs-agent`: only Rollstack's agent can make this change, so ask the user whether to hand it over with `sendReportMessage`. One of `invalid`, `needs-agent`. - `reason` (string, required): Why nothing changed: the pairs of colours the change would leave unreadable, a font the editor lacks, or a background picture that could not be read. ### Render draft slides `POST https://api.rollstack.com/public/v1/reports/{id}/slides/render` Renders slides you wrote as HTML on a slide deck's template, so you can design slides yourself instead of asking the slides agent. It saves nothing. Each draft answers its image, the issues to fix and notes to check by eye: fix the issues and render again until none are left. Call getReportDesign first and follow the guide it answers. A chart or table a draft places is drawn with its datasheet's data, or with the data of datasheetChanges you tried with previewReportDatasheetChanges and have not saved yet: save them with saveReportDatasheetChanges before you save the slides. A render that carries datasheetChanges runs one at a time with your queryReportData, previewReportDatasheetChanges and saveReportDatasheetChanges calls: send it only once those have answered. Only the report's editors may. At most 10 drafts a call, and 20 renders and saves a minute per user. Requires the `slide_decks:write` scope. Operation ID: `renderReportSlides`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `slides` (array of object, required): The draft slides to render, 1 to 10 a call, each under an id of its own. - `id` (string, required): The id you give the slide: letters, digits, `_` and `-`, at most 64 characters. Pass an existing slide's id to redraw that slide. - `html` (string, required): The slide as one `
` of HTML, as large as the report's canvas. No scripts, embedded pages, event attributes or anything loaded from outside it. - `datasheetChanges` (array of object): Changes to the report's datasheets that aren't saved yet, the ones you tried with `previewReportDatasheetChanges`: the drafts draw their charts and tables with the data they give, and a new datasheet is placed by the id the preview answered. Save them with `saveReportDatasheetChanges` before you save the slides. - When `type` is `create` - `type` (`create`, required) - `temporaryId` (string, required): A stable id for the new datasheet, which later changes in this patch reference it by - `name` (string, required): The datasheet's name - `reads` (array of object, required): The elements it reads, each once: the one a query reads, or those a join reads - `alias` (string, required): The name SQL reads this element by in FROM/JOIN, and ops name it by as a ref - `datasheetRef` (string (uuid), required): An existing datasheet that reads one element: the new datasheet reads that element, with its filters - `readType` (string or null): Omit to read it as that datasheet does One of `aggregated`, `raw`. - `parameters` (array of object, required): User-controlled periods, limits, thresholds and selections: SQL reads them as columns of the params input, a step as {"type":"parameter","key":""} - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object or null): The data as the Edit data editor builds it, over the one read; give query, or ops over several reads - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `ops` (array of object or null): Only over several reads: a join step over every read first, naming each read in its inputs (from op, ref the read alias), then steps - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): With ops; a query has its own formats - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `sql` (string or null): In place of a query or ops: one DuckDB SELECT over the reads, each a table named by its alias, with its formats in formats. Only for what a query can't do, such as a date stored as text (`CAST("Month" AS DATE) AS "Month"`) or a figure from two datasheets that read one row each (`SELECT won."Revenue" / goal."Goal" AS "Share of goal" FROM won, goal`) - When `type` is `set-query` - `type` (`set-query`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object, required): The data as the Edit data editor builds it, replacing all the datasheet's ops but its read: getReportDatasheet gives its current query to start from - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - When `type` is `set-ops` - `type` (`set-ops`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `ops` (array of object, required): The complete op list after the reads, in run order: an op whose ref is an existing op id keeps that op, and existing ops left out are removed. Only on a datasheet with a join step: keep the join first with steps after it; on any other, use set-query - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `alias` (string or null): SQL ops: the name the statement reads this input by - `from` (string, required): previous: the op above (above the first op, the datasheet's one read); op: the one ref names One of `previous`, `op`. - `ref` (string or null): op: the ref of an earlier op in this list, or a read's operation id or alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): Replaces the datasheet's formats; omit to keep them - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - When `type` is `set-read-type` - `type` (`set-read-type`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `readType` (string, required): aggregated: its data, as the tool displays it; raw: its tidy read, to transform; image: its picture One of `aggregated`, `raw`, `image`. - When `type` is `set-unpivot` - `type` (`set-unpivot`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `unpivot` (object or null, required): The columns of the range this datasheet reads to turn into rows, which every datasheet reading the range raw gets, and this one then reads it raw; null reads the range as the sheet shows it - `rows` (array of object, required): One output row per input row and entry, in this order; the input columns no entry names repeat on each - `label` (string, required): What the name column says on this row, such as the column's name or "2022" - `columns` (array of string or null, required): The input column for each of values, in order; null leaves that value empty on this row - `name` (string, required): The column that holds each row's label, such as "Year" - `values` (array of string, required): The columns the values go in: one, such as "Value", or one per measure #### Response `200` Success `application/json` - `conversionError` (string): Why the drafts could not be turned into slides, when one could not. `slides` is empty then: fix it and render again. - `datasheetChangesError` (string): Why the `datasheetChanges` failed, when they did, naming the datasheet and step. `slides` is empty then: fix them with `previewReportDatasheetChanges` and render again. - `slides` (array of object, required): The rendered drafts, in the order they were sent. - `id` (string, required): The slide, by the id it was sent with. - `issues` (array of string, required): What to fix before the draft can become a slide: text that overflows, elements outside the slide, styles the converter drops, colours outside the theme. - `notes` (array of string, required): What to check by eye. These block nothing. - `image` (string (base64) or null, required): The draft as it rendered, as a PNG image encoded in base64. Null when it could not be drawn. ## Uploaded files Your own data, for the slides agent to build slides from: a CSV file sent as JSON, or an Excel workbook sent as a file, as with Upload files in the app. Uploaded files suit data that lives outside a connected BI tool or spreadsheet, such as an export from another system. Upload a CSV file with `createDataset`, add it to a report with `addReportDatasheets`, then pass the datasheet id to the slides agent. Replace its content later and the reports built on it show the new data after their next run. Upload a document, such as a brief or a report, with `createDocument`, then pass its id to the slides agent for it to read as context, as when you attach a document in the chat in the app. ### Get an uploaded file `GET https://api.rollstack.com/public/v1/datasets/{id}` An uploaded CSV file or Excel workbook. A workbook comes with its sheets, the range each one uses and its named ranges: pass a sheet's id as sheetId to also read its cells as text, which shows where a table's header row is. Then add the sheet, or a range of it that starts at the header row, to a report with addReportDatasheets. Cells show what the workbook saved: nothing is recalculated. Requires the `slide_decks:read` scope. Operation ID: `getDataset`. #### Path parameters - `id` (string, required): The uploaded file to read: the `id` returned by `createDataset`, or a datasheet's `datasetId` in `listReportDatasheets`. It can be any uploaded file of your organization, including one another member uploaded. #### Query parameters - `sheetId` (string): A sheet of an uploaded workbook whose cells to read: one of the `sheets[].id` values of an earlier call. The answer's `cells` then holds them. Omit it to list the workbook's sheets only. - `range` (string): The cells to read from the sheet, in A1 notation without the sheet's name, such as `A1:H40`. Omit it to read from the start of the range the sheet uses. Only with `sheetId`. Example: `A1:H40`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the uploaded file. Pass it as `id` to `replaceDataset` and `deleteDataset` and, for a CSV file, as `datasetId` to `addReportDatasheets` to add it to a report. - `name` (string, required): The uploaded file's name: the `name` it was created with for a CSV file, or the workbook's file name for an Excel workbook, such as `Q3 pipeline.xlsx`. Replacing the file's content doesn't change it. - `createdAt` (string (date-time), required): When the file was uploaded. Replacing its content doesn't change it. - `updatedAt` (string (date-time), required): When the file's content was last replaced with `replaceDataset`, or when it was uploaded if it has never been replaced. - `kind` (string, required): What the uploaded file is. A `csv` file is added to a report whole. A `workbook` is added one sheet or range at a time. One of `csv`, `workbook`. - `sheets` (array of object or null, required): A workbook's sheets (tabs), in the order Excel shows them, hidden ones included. `null` for a CSV file. - `id` (string, required): Unique identifier for the sheet within the workbook. Pass it as `sheetId` to `addReportDatasheets`, with the file's `id` as `datasetId`. - `title` (string, required): The sheet's name, as shown on its tab in Excel. - `hidden` (boolean, required): Whether the sheet is hidden in Excel. A hidden sheet can still be read. - `usedRange` (string or null, required): The cells of the sheet that hold something, in A1 notation, such as `A1:H40`: what `addReportDatasheets` reads when you pass no `range`. It can start with title rows or hold several tables, so read its `cells` before adding it. `null` for an empty sheet. - `namedRanges` (array of object or null, required): A workbook's named ranges that lie on one of its sheets. `null` for a CSV file. - `name` (string, required): The named range's name in Excel. - `sheetId` (string, required): The sheet the named range is on: one of `sheets[].id`. - `range` (string, required): The cells the name stands for, in A1 notation. Pass it as `range` to `addReportDatasheets`. - `cells` (object or null, required): The cells of the sheet asked for with `sheetId`. `null` when no sheet was asked for. - `sheetId` (string, required): The sheet the cells were read from. - `range` (string, required): The cells asked for, in A1 notation. - `rows` (array of array of string, required): The cells as text, as Excel shows them, row by row from the top-left cell of `range`, with an empty string for an empty cell. At most 50 rows and 30 columns. Use them to find the row a table's header is on, then add the table with `addReportDatasheets`, starting its `range` at that row. - `truncated` (boolean, required): Whether `range` holds more rows or columns than `rows` shows. Read further with a `range` that starts lower. ### Replace an uploaded file `PUT https://api.rollstack.com/public/v1/datasets/{id}` Replaces an uploaded CSV file's rows, or a workbook's content with a new .xlsx sent as multipart/form-data in the file field. It keeps its id, and a CSV is never replaced by a workbook or the other way round. Reports built on it show the new content after their next run or message to the slides agent. An invalid file leaves the current one in place, and a sheet or range the new workbook no longer has fails its datasheets' reads. Only the user who created it may. From an MCP client, send a workbook with createDatasetUpload and this file's id. Requires the `slide_decks:write` scope. Operation ID: `replaceDataset`. #### Path parameters - `id` (string, required): The uploaded file to replace or delete: the `id` returned by `createDataset`. Only the user who uploaded the file can replace or delete it; for anyone else, the request fails with a `404`, as if the file did not exist. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `csv` (string, required): The file's data, as CSV text: a header row naming the columns, then at least one row of data. With `replaceDataset`, it replaces the file's whole content, header included, and the uploaded file must be a CSV file. The header's names become the column names of the datasheets made from the file: a blank one becomes `Column N`, after the column's position, and a repeated one gets a `_2`, `_3` suffix. Values can be separated by commas, semicolons or tabs, detected from the header row. At most 10 MB. Example: `region,revenue EMEA,1200000 Americas,2400000`. `multipart/form-data` - `file` (string (binary), required): The Excel workbook to upload. With `createDataset`, it becomes a new uploaded file named after the file, such as `Q3 pipeline.xlsx`; with `replaceDataset`, it replaces the content of an uploaded workbook, which keeps its id and name. An uploaded workbook can't be added to a report with `addReportDatasheets`, which takes uploaded CSV files only. The file's name must end in `.xlsx`, and it can be at most 10 MB; legacy `.xls`, macro-enabled and password-protected workbooks are rejected. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the uploaded file. Pass it as `id` to `replaceDataset` and `deleteDataset` and, for a CSV file, as `datasetId` to `addReportDatasheets` to add it to a report. - `name` (string, required): The uploaded file's name: the `name` it was created with for a CSV file, or the workbook's file name for an Excel workbook, such as `Q3 pipeline.xlsx`. Replacing the file's content doesn't change it. - `createdAt` (string (date-time), required): When the file was uploaded. Replacing its content doesn't change it. - `updatedAt` (string (date-time), required): When the file's content was last replaced with `replaceDataset`, or when it was uploaded if it has never been replaced. ### Delete an uploaded file `DELETE https://api.rollstack.com/public/v1/datasets/{id}` Deletes an uploaded CSV file or workbook. Reports built on it keep what they last showed, and their datasheets fail on the next read. Only the user who created it may. Requires the `slide_decks:write` scope. Operation ID: `deleteDataset`. #### Path parameters - `id` (string, required): The uploaded file to replace or delete: the `id` returned by `createDataset`. Only the user who uploaded the file can replace or delete it; for anyone else, the request fails with a `404`, as if the file did not exist. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Get a link to upload a file `POST https://api.rollstack.com/public/v1/datasets/uploads` Answers a link to send a CSV file or an Excel workbook (.xlsx) to from a shell, as it is on disk, at most 10 MB: use it when the user gives you a file, in place of writing a CSV into createDataset, and for every workbook. Run the command it answers with the path of the file. The upload answers the uploaded file with its id, as createDataset does: add it to a report with addReportDatasheets, a workbook after reading its sheets with getDataset. With datasetId, the file replaces the content of that uploaded file. The link works for 10 minutes and for one file: a file that is refused uses it up, so ask for another. Without a shell, write the CSV into createDataset. At most 20 links a minute per user. Requires the `slide_decks:write` scope. Operation ID: `createDatasetUpload`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `datasetId` (string): An uploaded file to replace the content of: its `id` from `createDataset`, or a datasheet's `datasetId` in `listReportDatasheets`. The file sent must be of its kind, a CSV for a CSV and a workbook for a workbook, and it keeps its id and name. Only the user who uploaded it may. Omit it to upload a new file. #### Response `201` Success `application/json` - `uploadUrl` (string, required): Where to send the file, as `multipart/form-data` in the `file` field, with no API key: the link is the permission, for one file. It answers the uploaded file as `createDataset` does, with its `id`. - `command` (string, required): A curl command that sends the file: replace `PATH_TO_FILE` with the file's path and run it in a shell. The file's name must end in `.csv` or `.xlsx`. - `expiresAt` (string (date-time), required): When the link stops working, 10 minutes after it was made. ### Upload a document `POST https://api.rollstack.com/public/v1/documents` Stores a document for the slides agent to read, such as a brief, a report or meeting notes, as when you attach one in the chat in the app: pass its id in documentIds on sendReportMessage. Over MCP, send the document's whole text as Markdown in text. Over REST, you can instead send the file as multipart/form-data in the file field: a .docx, .doc, .odt, .rtf, .pptx, .pdf, .txt or .md file of at most 100 MB and 100 pages, whose pages the agent can also look at. It joins your document library when you and your organization keep one. Requires the `slide_decks:write` scope. Operation ID: `createDocument`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): The document's name, without an extension: it is stored as a Markdown file named after it. The slides agent and the app's chat show it. From 1 to 200 characters. Example: `Q3 strategy brief`. - `text` (string, required): The document's whole text, in Markdown: headings, lists and tables keep their structure for the agent. Send what the document says, not a summary of it. Example: `# Q3 strategy brief Revenue grew 12% in EMEA...`. `multipart/form-data` - `file` (string (binary), required): The document to upload, stored under its file name. Its name must end in `.docx`, `.doc`, `.odt`, `.rtf`, `.pptx`, `.pdf`, `.txt` or `.md`, and it can be at most 100 MB and 100 pages. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the document. Pass it in `documentIds` to `sendReportMessage`. - `name` (string, required): The document's file name, such as `Q3 strategy brief.pdf`. - `pageCount` (number or null, required): How many pages the document has, which the agent can look at. `null` for a text or Markdown file. ### Upload a file `POST https://api.rollstack.com/public/v1/datasets` Stores a CSV for the slides agent to build slides from: a header row, then at least one data row, at most 10 MB. Add it to a report with addReportDatasheets. Over MCP the CSV is written into the tool call, so send large files to this REST endpoint instead. Or send an Excel workbook (.xlsx, at most 10 MB) as multipart/form-data in the file field: it is stored as it is, with all its sheets, formatting and charts, and the user picks its sheets and ranges for a report in the app's editor. Legacy .xls, macro-enabled and password-protected workbooks are rejected. A workbook is read as saved: formulas show their saved results, and nothing is recalculated. When you have the file and a shell, send the file itself with createDatasetUpload instead of writing it into the tool call. List the sheets of a workbook with getDataset, then add a sheet or a range of one to a report with addReportDatasheets. Requires the `slide_decks:write` scope. Operation ID: `createDataset`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): A name for the uploaded file, which its datasheet takes when you add the file to a report with `addReportDatasheets`. Leading and trailing spaces are removed, and a name containing a `/` keeps only its last part: `exports/Q3 pipeline` is stored as `Q3 pipeline`. From 1 to 255 characters. Example: `Q3 pipeline`. - `csv` (string, required): The file's data, as CSV text: a header row naming the columns, then at least one row of data. With `replaceDataset`, it replaces the file's whole content, header included, and the uploaded file must be a CSV file. The header's names become the column names of the datasheets made from the file: a blank one becomes `Column N`, after the column's position, and a repeated one gets a `_2`, `_3` suffix. Values can be separated by commas, semicolons or tabs, detected from the header row. At most 10 MB. Example: `region,revenue EMEA,1200000 Americas,2400000`. `multipart/form-data` - `file` (string (binary), required): The Excel workbook to upload. With `createDataset`, it becomes a new uploaded file named after the file, such as `Q3 pipeline.xlsx`; with `replaceDataset`, it replaces the content of an uploaded workbook, which keeps its id and name. An uploaded workbook can't be added to a report with `addReportDatasheets`, which takes uploaded CSV files only. The file's name must end in `.xlsx`, and it can be at most 10 MB; legacy `.xls`, macro-enabled and password-protected workbooks are rejected. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the uploaded file. Pass it as `id` to `replaceDataset` and `deleteDataset` and, for a CSV file, as `datasetId` to `addReportDatasheets` to add it to a report. - `name` (string, required): The uploaded file's name: the `name` it was created with for a CSV file, or the workbook's file name for an Excel workbook, such as `Q3 pipeline.xlsx`. Replacing the file's content doesn't change it. - `createdAt` (string (date-time), required): When the file was uploaded. Replacing its content doesn't change it. - `updatedAt` (string (date-time), required): When the file's content was last replaced with `replaceDataset`, or when it was uploaded if it has never been replaced. ## Datasheets The data behind a report's charts and tables. A datasheet reads one source, an uploaded file, a dashboard tab of a connection or a range of a spreadsheet, and keeps a copy of what it read; the report's charts and tables are drawn from those copies. A datasheet can also connect a Snowflake or Databricks table, or a Looker explore, Power BI semantic model or Tableau data source, which the slides agent queries in the warehouse or BI tool for each chart and table it builds. Add sources with `addReportDatasheets`, see when each was last read and whether it failed with `listReportDatasheets`, and read the table behind a chart with `getReportDatasheetData`. ### Get the data guide `GET https://api.rollstack.com/public/v1/data-guide` Read this once before you add or shape the data of a report: how to send a CSV or an Excel workbook and pick the range of a sheet, how to check a figure with queryReportData, how to shape data with previewReportDatasheetChanges, renderReportSlides and saveReportDatasheetChanges, and the query model those changes write. It needs no report. With stepFunctions, it also answers the exact params of those step functions, for the steps after a join. Requires the `slide_decks:read` scope. Operation ID: `getReportDataGuide`. #### Query parameters - `stepFunctions` (string or array of string): Step functions whose exact params to answer with the guide, for the steps after a join: repeat the parameter for each, as in `?stepFunctions=filter&stepFunctions=sort`. #### Response `200` Success `application/json` - `guide` (string, required): The guide, in Markdown: how to send a CSV or a workbook, pick a range of a sheet, check a figure with a query, shape data with datasheet changes and save it. - `stepFunctions` (object): Each step function asked for, with its label and the JSON Schema of its params. ### List report datasheets `GET https://api.rollstack.com/public/v1/reports/{id}/datasheets` The datasheets a report's charts and tables are built from, with their source and when each was last read. An entry whose `copyOf` is set repeats that datasheet for one more element of a slide: it shows the same data and is read together with it, so count each piece of data once by skipping the entries with a `copyOf`. Only a datasheet a slide shows has a `lastBuiltAt`. Requires the `slide_decks:read` scope. Operation ID: `listReportDatasheets`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the datasheet. Pass it as `datasheetId` to `getReportDatasheetData` to read its table (a `data` datasheet only), in `datasheetIds` on `startReportRun` to update only some datasheets, or in `datasheetIds` on `sendReportMessage` for the slides agent to use it. - `kind` (string, required): What the datasheet holds. `data`: a table, which `getReportDatasheetData` reads. `picture`: a picture of a dashboard, tab or chart, such as a dashboard added with `addReportDatasheets`, with no table to read. The slides agent can still use it when you pass it in `datasheetIds` on `sendReportMessage`, and `addReportDashboardElements` adds the charts of a Tableau or Power BI one as data. One of `data`, `picture`. - `name` (string, required): The datasheet's name, as shown in the report's editor, where editors can rename it. A datasheet added with `addReportDatasheets` starts out named after its uploaded file, its dashboard or dashboard tab, or its range, such as `A1:F20`. - `sourceType` (string or null, required): The kind of source the datasheet reads; when it reads several, the kind of the first. - `Looker`, `Tableau`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`: data from that BI tool, such as a dashboard, a tab or one of its charts. - `Salesforce`: a Salesforce report. - `Snowflake`, `Databricks`: a query run on that warehouse connection. - `GoogleSheet`, `MicrosoftExcel`: a sheet or range of a Google Sheets or Excel file. - `CsvUpload`: a CSV file uploaded with `createDataset` or in the report's editor. - `XlsxUpload`: a sheet or range of an Excel workbook uploaded to Rollstack. - `ManualTable`: values typed into the report's editor, or the data of a chart imported from PowerPoint. Datasheets don't read `GoogleExcel`, `RollstackVariable` or `Dbt` sources, so expect none of them here. `null` when the datasheet reads no source, or Rollstack no longer has a record of its first source; deleting an uploaded file or a connection doesn't make it `null`. One of `GoogleSheet`, `GoogleExcel`, `MicrosoftExcel`, `Tableau`, `Salesforce`, `Metabase`, `PowerBI`, `Looker`, `RollstackVariable`, `Lightdash`, `Omni`, `Sigma`, `Snowflake`, `Databricks`, `BigQuery`, `CsvUpload`, `XlsxUpload`, `ManualTable`, `Dbt`. - `sourceName` (string or null, required): The name of what the datasheet reads, such as a dashboard tab, a range like `A1:F20`, or an uploaded file. When it reads several sources, the first one's. `null` in the same cases as `sourceType`. - `datasetId` (string or null, required): The uploaded file the datasheet reads, by the id `replaceDataset` takes, when its `sourceType` is `CsvUpload` or `XlsxUpload`. Replace the file, then start a run of the report, to bring new data into the slides drawn from it. `null` for every other source. - `lastReadAt` (string (date-time) or null, required): When Rollstack last read the datasheet's source successfully and stored a fresh copy of its data; for a datasheet that reads several sources, the latest such read of any of them. `null` until a read succeeds. - `lastBuiltAt` (string (date-time) or null, required): When the datasheet's data was last applied to the report's slides, updating the charts, tables and pictures drawn from it. `null` when its current data hasn't been applied to the slides yet, for example while nothing in the report uses the datasheet. - `copyOf` (string or null, required): When this datasheet is a copy of an earlier one of the report, with the same sources, steps and filter values, that one's `id`. An element has a datasheet of its own, so Rollstack makes such a copy for each further element that shows a datasheet. Copies are read from the source together, once, and show the same data: read and change the original. `null` for a datasheet that is no copy. - `error` (string or null, required): Why the datasheet's latest update failed, while reading its source or applying its data to the slides, as a human-readable message. The slides keep showing the datasheet's last good data until an update succeeds. `null` when the latest update worked. ### Add sources to report `POST https://api.rollstack.com/public/v1/reports/{id}/datasheets` Adds sources to a report as datasheets, and answers their ids in the order of the sources. A source is a CSV file uploaded with createDataset, or a dashboard of a Looker, Metabase, Omni, Lightdash, Sigma, Tableau or Power BI connection: find it with searchDashboards, confirm it with the user, optionally check its tabs and charts with getDashboard, and add it by its connection, id and tabId from getDashboard's tabs, or from searchDashboards for a Sigma workbook found by a link (else the tab it opens on, a Power BI report's or Sigma workbook's first page). A dashboard comes in as one picture of the tab, read with the user's access to the connection, from which the slides agent can add its charts. To draw a Tableau or Power BI dashboard's figures yourself, list its charts with getReportDatasheet on that picture and add the ones you need as data with addReportDashboardElements. A source can also be a tabular or summary report of a Salesforce connection, found with searchDashboards and added by its connection and reportId: it comes in as a table of its rows, read with the user's access to the connection; a matrix or joined report is rejected. A source can also be a table or view of a Snowflake or Databricks connection, found with searchTables and added by its connection, database, schema and table: it stays in the warehouse, where the slides agent queries it with SQL with the user's access to the connection, as its default user when one is set, and the queries the agent saves run again on every update. A source can also be a range of a Google Sheets or Excel file the user added in the app: find the file with searchSpreadsheets, take the sheet's id from getSpreadsheet, and pass the range inside the sheet in A1 notation, like A1:F20. A range comes in as a table, read with the user's own Google or Microsoft account on every run. A source can also be a sheet or a range of an uploaded Excel workbook, whose sheets getDataset lists. Pass the ids as datasheetIds on sendReportMessage for the slides agent to build slides from them. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `addReportDatasheets`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `sources` (array of object, required): The data to add to the report, each source becoming one of its datasheets: an uploaded CSV file (`datasetId`), a sheet or range of an uploaded workbook (`datasetId`, `sheetId` and optionally `range`), a dashboard tab (`connectionType`, `connectionId`, `dashboardId` and optionally `tabId`), a Salesforce report (`connectionType`, `connectionId` and `reportId`), a Snowflake or Databricks table (`connectionType`, `connectionId`, `database`, `schema` and `table`), a Looker explore, Power BI semantic model or Tableau data source (`connectionType`, `connectionId` and `modelId`), or a range of a spreadsheet (`spreadsheetId`, `sheetId` and `range`). An uploaded file, a Salesforce report or a range comes in as a table, a warehouse table stays in the warehouse and a model in its BI tool for the slides agent to query, and a dashboard tab comes in as a picture of the tab. If any source can't be added, none is. From 1 to 100 sources. - Option 1 - `datasetId` (string, required): The uploaded file to add: the `id` returned by `createDataset`. A CSV file comes in whole, as one table named after the file. An Excel workbook comes in one sheet at a time, so pass `sheetId` with it. It can be any uploaded file of the report's organization, including one another member uploaded. Example: `b2c4d6e8-f0a1-4b3c-9d5e-7f9a1b3c5d7e`. - `sheetId` (string): For an uploaded workbook, the sheet to read: one of the `sheets[].id` values from `getDataset`. Required for a workbook, and rejected for a CSV file. - `range` (string): For an uploaded workbook, the cells to read from the sheet, in A1 notation without the sheet's name, such as `A3:H40`. The datasheet contains them as a table and is named after the range. Start it at the header row so the columns take its names; without a header, they are named `Column 1`, `Column 2` and so on. Omit it to read everything the sheet uses, in a datasheet named after the sheet: do that only when the sheet's first row is the header. Whole columns such as `A:F` aren't accepted. Example: `A3:H40`. - Option 2 - `connectionType` (string, required): The type of the connection the dashboard is on: `Looker`, `Metabase`, `Omni`, `Lightdash`, `Sigma`, `Tableau` or `PowerBI`. It must match the connection's `type` in `listConnections`. One of `Looker`, `Metabase`, `Omni`, `Lightdash`, `Tableau`, `PowerBI`, `Sigma`. - `connectionId` (string, required): The connection the dashboard is on: the `id` of a connection from `listConnections`. You must have access to the connection in Rollstack. Example: `c8e0a2b4-d6f8-4a0b-8c2d-4e6f8a0b2c4d`. - `dashboardId` (string, required): The dashboard to add: the `id` of a dashboard from `searchDashboards` on this connection. For Tableau and Sigma, it is a workbook, and for Power BI, a report. Example: `128`. - `tabId` (string): The tab to add: one of the `tabs[].id` values from `getDashboard`, which for Tableau are a workbook's views, for Power BI a report's pages and for Sigma a workbook's pages, or the `tabId` of a Sigma workbook `searchDashboards` found by a link. The datasheet is a picture of that tab, named after it. If omitted, Rollstack adds the tab the dashboard opens on (the first view or page for Tableau, Power BI and Sigma), or, for a dashboard without tabs such as an Omni dashboard, the whole dashboard, named after it. A tab the dashboard doesn't have is rejected. Example: `12-overview`. - When `connectionType` is `Salesforce` - `connectionType` (`Salesforce`, required): `Salesforce`. It must match the connection's `type` in `listConnections`. - `connectionId` (string, required): The Salesforce connection the report is on: the `id` of a connection from `listConnections`. You must have access to the connection in Rollstack. Example: `c8e0a2b4-d6f8-4a0b-8c2d-4e6f8a0b2c4d`. - `reportId` (string, required): The report to add: the `id` of a `tabular` or `summary` report from `searchDashboards` on this connection. The datasheet contains the report's rows as a table, a summary report's with its groupings as their first columns, and is named after the report. A matrix or joined report is rejected. Example: `00O5e000008abcdEAA`. - Option 4 - `connectionType` (string, required): The type of the connection the table is on: `Snowflake` or `Databricks`. It must match the connection's `type` in `listConnections`. One of `Snowflake`, `Databricks`. - `connectionId` (string, required): The data warehouse connection the table is on: the `id` of a connection from `listConnections`. You must have your own access to the connection in Rollstack. Example: `c8e0a2b4-d6f8-4a0b-8c2d-4e6f8a0b2c4d`. - `database` (string, required): The database the table is in, as `database` in `searchTables`. - `schema` (string, required): The schema the table is in, as `schema` in `searchTables`. - `table` (string, required): The table or view to add, as `table` in `searchTables`. The datasheet is named `database.schema.table`, and the slides agent queries it in the warehouse with SQL over all its rows. Example: `ORDERS`. - Option 5 - `connectionType` (string, required): The type of the connection the model is on: `Looker`, `PowerBI` or `Tableau`. It must match the connection's `type` in `listConnections`. One of `Looker`, `PowerBI`, `Tableau`. - `connectionId` (string, required): The connection the model is on: the `id` of a connection from `listConnections`. You must have access to the connection in Rollstack, and for Tableau your own Tableau user on it. Example: `c8e0a2b4-d6f8-4a0b-8c2d-4e6f8a0b2c4d`. - `modelId` (string, required): The model to add: the `id` of a Looker explore, Power BI semantic model or Tableau data source from `searchModels` on this connection. The datasheet is named after it and holds no rows: pass its id as `datasheetIds` on `sendReportMessage`, and the slides agent queries the model in its BI tool for the data its slides need. A model the connection doesn't have is rejected. Example: `ecommerce.order_items`. - Option 6 - `spreadsheetId` (string, required): The Google Sheets or Excel file to read from: the `id` of a file from `searchSpreadsheets`. It must be a file you added in the app yourself. Example: `e6f8a0b2-c4d6-4e8f-9a0b-2c4d6e8f0a1b`. - `sheetId` (string, required): The sheet the range is on: one of the `sheets[].id` values from `getSpreadsheet`. A sheet the file doesn't have is rejected. Example: `0`. - `range` (string, required): The cells to read from the sheet, in A1 notation without the sheet's name, such as `A1:F20`, or `B2` for a single cell. The datasheet contains them as a table and is named after the range. Start the range at the header row so the columns take its names; without a header, they are named `Column 1`, `Column 2` and so on. Hidden rows and columns are left out, and whole columns such as `A:F` aren't accepted. Example: `A1:F20`. #### Response `201` Success `application/json` - `datasheetIds` (array of string, required): Unique identifiers of the new datasheets, one per source, in the same order as `sources`. Pass them as `datasheetIds` on `sendReportMessage` for the slides agent to build slides from them. ### Get a datasheet `GET https://api.rollstack.com/public/v1/reports/{id}/datasheets/{datasheetId}` What a datasheet's data is written as: its query, in the shape set-query takes, its one SQL statement, or its join and the steps after it, and its formats. Read it before you change a datasheet with previewReportDatasheetChanges: set-query replaces the whole query, so start from this one. For the picture of a Tableau view or Power BI page added with addReportDatasheets, it also lists the charts on it, which addReportDashboardElements adds as data. Only the report's editors may. Requires the `slide_decks:read` scope. Operation ID: `getReportDatasheet`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `datasheetId` (string, required): One of this report's datasheets, by its `id` in `listReportDatasheets`. #### Response `200` Success `application/json` - `id` (string, required): The datasheet's id. - `name` (string, required): The datasheet's name, as the report's editor shows it. - `kind` (string, required): `data` for a table, `picture` for an image, which has no query. One of `data`, `picture`. - `elements` (array of object or null, required): For the picture of a whole Tableau view or Power BI page, the charts on it, which `addReportDashboardElements` adds as data or pictures. `null` for any other datasheet. Listing them takes the dashboard's picture when it never had one, which can take a minute: past the wait the call answers that the source is still being read, so call it again. - `ref` (string, required): What to pass as `ref` to `addReportDashboardElements` to add this chart. - `name` (string, required): The chart's name on the dashboard. - `type` (string, required): Its kind in the dashboard's tool, such as a Tableau `worksheet` or `legend`. - `reads` (array of string, required): What it can be added as: `data` for its table, `picture` for its image. - `datasheetIds` (array of string, required): The report's datasheets that already read it with the dashboard's filters, to use instead of adding it again. - `elementsNote` (string or null, required): Why `elements` is empty or partial, such as charts not listed yet, or `null`. - `query` (object or null, required): Its data as a query, the Edit data editor's model, in the shape `set-query` takes: change what you need and send it whole. `null` when its data is SQL or a join. - `sql` (string or null, required): Its data as one SQL statement over its reads, or `null`. - `ops` (array of object or null, required): For a datasheet that joins its reads: the join and the steps after it, each by the `ref` `set-ops` keeps it by. `null` for any other. - `formats` (array of object, required): How its columns' numbers are shown: a numfmt pattern for each output column. - `column` (string, required) - `format` (string, required) ### Remove datasheet from report `DELETE https://api.rollstack.com/public/v1/reports/{id}/datasheets/{datasheetId}` Removes a datasheet the report's slides no longer show, such as a source that was added and not used, or one whose read keeps failing. A datasheet a chart, table, picture or sentence still shows is refused: change or remove that slide first. The source itself, such as the dashboard or the uploaded file, is not touched. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `removeReportDatasheet`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `datasheetId` (string, required): One of this report's datasheets, by its `id` in `listReportDatasheets`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `removed` (array of string, required): The datasheet removed. ### Get datasheet data `GET https://api.rollstack.com/public/v1/reports/{id}/datasheets/{datasheetId}/data` The table a report's chart is drawn from: the datasheet's steps run over the copies stored at its sources' last reads; the source is never queried. Only the report's editors may: the table was read with an editor's credentials, can hold columns and rows the slides never show, and skips the source's row-level security. Fails for a `picture` datasheet (its `kind` in `listReportDatasheets`), which has no table. Also fails until every source it reads has been read, after a source's latest read failed, and once a stored copy expires, 30 days after its read. At most 30 reads a minute per user. Requires the `slide_decks:read` scope. Operation ID: `getReportDatasheetData`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `datasheetId` (string, required): The datasheet whose table to read: an `id` from `listReportDatasheets`, or one of the `datasheetIds` returned by `addReportDatasheets`. It must be one of this report's datasheets. A datasheet that reads a picture, such as a dashboard tab added with `addReportDatasheets`, has no table, so the request fails: add the tab's charts as data with `addReportDashboardElements`. #### Query parameters - `limit` (integer): The maximum number of rows to return, starting from the first row of the table. If the table has more, `truncated` is `true`. Can range from `1` to `1000`. Defaults to `200`. #### Response `200` Success `application/json` - `columns` (array of object, required): The columns of the table, in the same order as the cells of each row in `rows`. - `name` (string, required): The column's name in the datasheet's table, which the report's charts and tables use to refer to it. Unless the datasheet renames it, a column read from an uploaded file or a spreadsheet range is named after its header; a blank header becomes `Column N`, after the column's position, and a repeated one gets a `_2`, `_3` suffix. - `label` (string): The column's display name, when its source gives one, such as a field's label in Looker or Metabase. Charts and tables drawn from the datasheet show it instead of `name`, unless a table renames the column. Omitted when the column has none. - `type` (string, required): What the column's cells contain: `number` for numbers, `date` for dates and times, `string` for text, and `boolean` for `true` or `false`. Any cell can also be `null` when it is empty. One of `number`, `date`, `string`, `boolean`. - `rows` (array of array of string or number or boolean or null, required): The rows of the table, starting from the first, at most `limit` of them. Each row is an array of cells in the order of `columns`. An empty cell is `null`, and a `date` cell is an ISO 8601 string in UTC, at midnight when the source gives a day without a time. - `stacking` (string): How the chart in the datasheet's source stacks its series, such as a Looker, Metabase or Power BI chart, or a chart imported from PowerPoint. Area, bar and column charts drawn from the datasheet stack the same way, unless their own Stacking setting overrides it. `none` doesn't stack the series, `stacked` piles them on top of one another, and `percent` piles them up to 100% so each shows its share of the total. Omitted when the source sets no stacking, as with an uploaded file or a spreadsheet range; charts then don't stack unless set to. One of `none`, `stacked`, `percent`. - `totalRow` (`true`) - `truncated` (boolean, required): Whether the table has more rows than `limit`, so `rows` doesn't contain all of them. Raise `limit` to get more, up to the first `1000` rows. - `readAt` (string (date-time), required): When Rollstack read the source data the table is built from. For a datasheet that reads several sources, the oldest of those reads. ### Add dashboard charts to report `POST https://api.rollstack.com/public/v1/reports/{id}/datasheets/{datasheetId}/elements` Adds charts of a Tableau view or Power BI page the report holds as a picture, each as a datasheet of its own: its data, to read with getReportDatasheetData or queryReportData and draw on a slide, its picture, or both. Pass the picture's datasheet id, from addReportDatasheets or listReportDatasheets, and the refs of the charts getReportDatasheet lists for it. Each chart is read with the dashboard's filters and the user's access to the connection, and a chart the report already reads that way is reused. Reading a dashboard can take a minute: past the wait the call answers that the source is still being read, so send the same call again, which reuses what the first one added. It runs one at a time with your queryReportData, previewReportDatasheetChanges and saveReportDatasheetChanges calls: send it once they answer. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `addReportDashboardElements`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `datasheetId` (string, required): One of this report's datasheets, by its `id` in `listReportDatasheets`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `elements` (array of object, required): The charts to add, only the ones the slides need, at most 12 a call. - `ref` (string, required): A chart's `ref` from the `elements` `getReportDatasheet` lists for this dashboard. For a table Tableau builds from several worksheets side by side, the refs of those worksheets joined by commas, like `12,15,18`, add it as one. - `as` (string, required): `data` for its table, to read with `getReportDatasheetData` and draw as a chart, table or figure on a slide; `picture` for its image, to place on a slide as it looks; `both` for the two. Ask only for a read the element lists in its `reads`. One of `data`, `picture`, `both`. #### Response `200` Success `application/json` - `elements` (array of object, required): Each chart you asked for, in the order of `elements`. - `ref` (string, required): The `ref` you passed. - `name` (string or null, required): The chart's name on the dashboard, `null` when it has none. - `dataDatasheetId` (string or null, required): The datasheet of its table, a new one or the one the report already had for this chart with the dashboard's filters. `null` when you asked only for its picture, or when it was refused. - `pictureDatasheetId` (string or null, required): The datasheet of its picture, `null` when you asked only for its data, or when it was refused. - `error` (string or null, required): Why it was refused, or why its data or picture could not be read, `null` when nothing went wrong. ### Preview datasheet changes `POST https://api.rollstack.com/public/v1/reports/{id}/datasheets/changes/preview` Tries changes to a report's datasheets, to shape data before it goes on a slide: a new datasheet, a query, steps after a join, a read type, an unpivot. It runs every datasheet the changes touch over the data stored at the sources' last reads and saves nothing, not even a new datasheet. Answers each datasheet's columns and five sample rows, the ids a new datasheet gets, and the revisions to send to saveReportDatasheetChanges. A change that fails answers valid false with its reason, naming the datasheet and step: fix it and preview again. Draw a slide with the same changes by sending them to renderReportSlides. Only the report's editors may. Your previews run one at a time, together with your queryReportData and saveReportDatasheetChanges calls and the renderReportSlides calls that carry datasheetChanges: send the next only once this one answers, never several at once, and try several datasheets' changes in one preview. At most 30 previews and queryReportData calls a minute per user, counted together. Requires the `slide_decks:write` scope. Operation ID: `previewReportDatasheetChanges`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `changes` (array of object, required): The changes to the report's datasheets, applied in order: `create` for a datasheet the report doesn't have yet (a query, one SQL statement, or a join and steps over elements that datasheets of the report read already, under a `temporaryId` you choose), `set-query` or `set-ops` for the data of one it has (`getReportDatasheet` gives what it is now), `set-read-type` and `set-unpivot`. Each datasheet is its reads followed by the ops over them: call `getReportDataGuide` for the query model, SQL and joins. A `temporaryId` can be used once: after a save, create the next datasheet under another. - When `type` is `create` - `type` (`create`, required) - `temporaryId` (string, required): A stable id for the new datasheet, which later changes in this patch reference it by - `name` (string, required): The datasheet's name - `reads` (array of object, required): The elements it reads, each once: the one a query reads, or those a join reads - `alias` (string, required): The name SQL reads this element by in FROM/JOIN, and ops name it by as a ref - `datasheetRef` (string (uuid), required): An existing datasheet that reads one element: the new datasheet reads that element, with its filters - `readType` (string or null): Omit to read it as that datasheet does One of `aggregated`, `raw`. - `parameters` (array of object, required): User-controlled periods, limits, thresholds and selections: SQL reads them as columns of the params input, a step as {"type":"parameter","key":""} - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object or null): The data as the Edit data editor builds it, over the one read; give query, or ops over several reads - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `ops` (array of object or null): Only over several reads: a join step over every read first, naming each read in its inputs (from op, ref the read alias), then steps - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): With ops; a query has its own formats - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `sql` (string or null): In place of a query or ops: one DuckDB SELECT over the reads, each a table named by its alias, with its formats in formats. Only for what a query can't do, such as a date stored as text (`CAST("Month" AS DATE) AS "Month"`) or a figure from two datasheets that read one row each (`SELECT won."Revenue" / goal."Goal" AS "Share of goal" FROM won, goal`) - When `type` is `set-query` - `type` (`set-query`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object, required): The data as the Edit data editor builds it, replacing all the datasheet's ops but its read: getReportDatasheet gives its current query to start from - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - When `type` is `set-ops` - `type` (`set-ops`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `ops` (array of object, required): The complete op list after the reads, in run order: an op whose ref is an existing op id keeps that op, and existing ops left out are removed. Only on a datasheet with a join step: keep the join first with steps after it; on any other, use set-query - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `alias` (string or null): SQL ops: the name the statement reads this input by - `from` (string, required): previous: the op above (above the first op, the datasheet's one read); op: the one ref names One of `previous`, `op`. - `ref` (string or null): op: the ref of an earlier op in this list, or a read's operation id or alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): Replaces the datasheet's formats; omit to keep them - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - When `type` is `set-read-type` - `type` (`set-read-type`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `readType` (string, required): aggregated: its data, as the tool displays it; raw: its tidy read, to transform; image: its picture One of `aggregated`, `raw`, `image`. - When `type` is `set-unpivot` - `type` (`set-unpivot`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `unpivot` (object or null, required): The columns of the range this datasheet reads to turn into rows, which every datasheet reading the range raw gets, and this one then reads it raw; null reads the range as the sheet shows it - `rows` (array of object, required): One output row per input row and entry, in this order; the input columns no entry names repeat on each - `label` (string, required): What the name column says on this row, such as the column's name or "2022" - `columns` (array of string or null, required): The input column for each of values, in order; null leaves that value empty on this row - `name` (string, required): The column that holds each row's label, such as "Year" - `values` (array of string, required): The columns the values go in: one, such as "Value", or one per measure #### Response `200` Success `application/json` - When `valid` is `true` - `valid` (`true`, required) - `resolvedDatasheetIds` (object, required): The id of each datasheet a `create` makes, by its `temporaryId`. Place a new datasheet on a slide by this id: `renderReportSlides` draws it with the same changes and `saveReportDatasheetChanges` saves it under it. - `resolvedOperationIds` (object, required): The id of each op a change adds, by its `ref`. - `removedOperations` (array of object, required): The existing ops a change drops, so you can check what it replaced. - `datasheetId` (string, required) - `operationId` (string, required) - `summary` (string, required) - `outputs` (object, required): Each changed datasheet by id, with its columns and five sample rows. - `revisions` (object, required): The revision of each existing datasheet the changes edit, to send back to `saveReportDatasheetChanges`. - When `valid` is `false` - `valid` (`false`, required) - `error` (string, required): Why the changes failed, naming the datasheet, op and field when it can. Fix them and preview again. ### Query report data `POST https://api.rollstack.com/public/v1/reports/{id}/data/query` Runs one read-only SQL query over the tables of a report's datasheets, to check a figure before it goes on a slide or to explore data before shaping it. It reads the copies stored at the sources' last reads, never a source, and saves nothing: a datasheet's table is the one getReportDatasheetData answers. Only the report's editors may. At most 200 rows and 30 seconds a query. Your queries run one at a time, together with your previewReportDatasheetChanges and saveReportDatasheetChanges calls and the renderReportSlides calls that carry datasheetChanges: send the next only once this one answers, never several at once, and check several figures in one query, as columns of one row or rows of a UNION ALL. At most 30 queries and previewReportDatasheetChanges calls a minute per user, counted together. Requires the `slide_decks:write` scope. Operation ID: `queryReportData`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `sql` (string, required): One read-only DuckDB query (`SELECT` or `WITH`). Its tables are the report's datasheets, named by their `id` from `listReportDatasheets` in double quotes, as in `SELECT region, SUM(revenue) AS revenue FROM "" GROUP BY region`. A column is a number when every value is one, else text, dates included: `CAST` an ISO date (`YYYY-MM-DD`) to `DATE` before `year()`, `date_trunc()` or date arithmetic. Give every computed column a name with `AS`. #### Response `200` Success `application/json` - `columns` (array of object, required): The columns of the table, in the same order as the cells of each row in `rows`. - `name` (string, required): The column's name in the datasheet's table, which the report's charts and tables use to refer to it. Unless the datasheet renames it, a column read from an uploaded file or a spreadsheet range is named after its header; a blank header becomes `Column N`, after the column's position, and a repeated one gets a `_2`, `_3` suffix. - `label` (string): The column's display name, when its source gives one, such as a field's label in Looker or Metabase. Charts and tables drawn from the datasheet show it instead of `name`, unless a table renames the column. Omitted when the column has none. - `type` (string, required): What the column's cells contain: `number` for numbers, `date` for dates and times, `string` for text, and `boolean` for `true` or `false`. Any cell can also be `null` when it is empty. One of `number`, `date`, `string`, `boolean`. - `rows` (array of array of string or number or boolean or null, required): The rows of the table, starting from the first, at most `limit` of them. Each row is an array of cells in the order of `columns`. An empty cell is `null`, and a `date` cell is an ISO 8601 string in UTC, at midnight when the source gives a day without a time. - `totalRow` (`true`) - `truncated` (boolean, required): Whether the table has more rows than `limit`, so `rows` doesn't contain all of them. Raise `limit` to get more, up to the first `1000` rows. ### Save datasheet changes `POST https://api.rollstack.com/public/v1/reports/{id}/datasheets/changes` Saves changes to a report's datasheets that you tried with previewReportDatasheetChanges: send the same changes with the revisions it answered. Nothing is saved when a datasheet they edit changed since, or when they fail: the answer says why, and you preview again. The charts and tables on slides that show a changed datasheet are read again, and a new datasheet is placed by the id it answers and the slides saved with saveReportSlides. Take the save back by restoring versionBeforeId with restoreReportVersion. It runs one at a time with your queryReportData and previewReportDatasheetChanges calls and the renderReportSlides calls that carry datasheetChanges: send it only once those have answered. Only the report's editors may. Counts against the 20 renders and saves a minute per user. Requires the `slide_decks:write` scope. Operation ID: `saveReportDatasheetChanges`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `changes` (array of object, required): The changes to the report's datasheets, applied in order: `create` for a datasheet the report doesn't have yet (a query, one SQL statement, or a join and steps over elements that datasheets of the report read already, under a `temporaryId` you choose), `set-query` or `set-ops` for the data of one it has (`getReportDatasheet` gives what it is now), `set-read-type` and `set-unpivot`. Each datasheet is its reads followed by the ops over them: call `getReportDataGuide` for the query model, SQL and joins. A `temporaryId` can be used once: after a save, create the next datasheet under another. - When `type` is `create` - `type` (`create`, required) - `temporaryId` (string, required): A stable id for the new datasheet, which later changes in this patch reference it by - `name` (string, required): The datasheet's name - `reads` (array of object, required): The elements it reads, each once: the one a query reads, or those a join reads - `alias` (string, required): The name SQL reads this element by in FROM/JOIN, and ops name it by as a ref - `datasheetRef` (string (uuid), required): An existing datasheet that reads one element: the new datasheet reads that element, with its filters - `readType` (string or null): Omit to read it as that datasheet does One of `aggregated`, `raw`. - `parameters` (array of object, required): User-controlled periods, limits, thresholds and selections: SQL reads them as columns of the params input, a step as {"type":"parameter","key":""} - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object or null): The data as the Edit data editor builds it, over the one read; give query, or ops over several reads - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `ops` (array of object or null): Only over several reads: a join step over every read first, naming each read in its inputs (from op, ref the read alias), then steps - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): With ops; a query has its own formats - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `sql` (string or null): In place of a query or ops: one DuckDB SELECT over the reads, each a table named by its alias, with its formats in formats. Only for what a query can't do, such as a date stored as text (`CAST("Month" AS DATE) AS "Month"`) or a figure from two datasheets that read one row each (`SELECT won."Revenue" / goal."Goal" AS "Share of goal" FROM won, goal`) - When `type` is `set-query` - `type` (`set-query`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `query` (object, required): The data as the Edit data editor builds it, replacing all the datasheet's ops but its read: getReportDatasheet gives its current query to start from - `customFields` (array of object): Columns worked out on each source row before the filters and the grouping, which filters, dimensions, splits and measures can then name like a source column. A formula reads one row only and may name an earlier custom field. Examples: price times quantity, summed by region; deal-size bands with if(); diff_days between two dates, then averaged - `formula` (string, required): A formula over one source row: ${Column} names a source column or an earlier custom field. No sum(), mean(), min(), max(), median(), count(), offset(), index() or running_total(), which read other rows - `as` (string, required): The column's name - `dimensions` (array of object, required): The columns to group by - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `measures` (array of object, required) - `fn` (string, required): One of `sum`, `avg`, `min`, `max`, `median`, `count`, `count_distinct`, `first`, `last`. - `column` (string or null, required): null only with count, which counts rows - `as` (string): Omit for the default name, such as "Sum of Sales" - `filters` (array of object): Only the rows these all match, beside measures of every row: e.g. a count of the mortgages that are Buy to Let. Omit for every row - `pivots` (array of object, required): Dimensions whose values become columns, outer first: each level splits the one above; empty for none - `column` (string, required): A column name, exact and case-sensitive - `bucket` (string or null, required): A date unit to group a date or timestamp column by (month: each month of each year), a part of the date over every year (month_of_year: Jan to Dec, quarter_of_year: 1 to 4, day_of_week: Mon to Sun), else null. This year beside last year by month is month_of_year split by the year One of `day`, `week`, `month`, `quarter`, `year`, `month_of_year`, `quarter_of_year`, `day_of_week`. - `as` (string): Omit for the default name - `groups` (array of object): A text column only: values shown under one name, e.g. Email and Telephone as "Email & Tel"; the others keep theirs - `name` (string, required) - `values` (array of string, required) - `fill` (boolean): A date grouped by a unit or a part only, one key at most: every period between the first and the last (every month, quarter or weekday of a part), for each combination of the other keys, a count or sum of no rows as 0. Omit to show only the periods the rows have - `calculations` (array of object): Columns beside each row over every row the aggregate gives: a rank, a percent of total, a difference or percent difference from the previous row ordered by the only dimension, a total/average/min/max of a measure, or a formula over the row's dimensions and measures, such as a rate. A formula with sum(), mean(), min() or max() reads only the rows the limit keeps, such as each top 10 row's share of the 10. Need a dimension or measure and no split - When `fn` is `rank` - `fn` (`rank`, required) - `column` (string, required): A measure, by its name before renames - `direction` (string, required): desc: the largest ranks 1 One of `asc`, `desc`. - `as` (string): The new column's name. Omit for the default name - When `fn` is `percent_of_total` - `fn` (`percent_of_total`, required) - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - Option 3 - `fn` (string, required): One of `difference`, `percent_difference`. - `column` (string, required): A measure, by its name before renames - `orderBy` (string, required): The query's only dimension, such as a month, by its name before renames: the rows are ordered by it, oldest first - `offset` (integer): How many rows back to compare with; omit for 1, the previous row - `as` (string): The new column's name. Omit for the default name - Option 4 - `fn` (string, required): One of `sum`, `avg`, `min`, `max`. - `column` (string, required): A measure, by its name before renames - `as` (string): The new column's name. Omit for the default name - When `fn` is `formula` - `fn` (`formula`, required) - `formula` (string, required): A formula: ${Column} names a dimension or measure by its name before renames; numbers, "text", yes, no, null; + - * / (dividing by 0 gives empty); = != < <= > >=; AND, OR, NOT; if(condition, then, else), coalesce(a, b), round(x, digits), abs(x), concat(a, b), is_null(x), to_string(x); sum(x), mean(x), min(x) and max(x) of a column over the rows shown, after the row limit, such as ${Sales} / sum(${Sales}) for each row's share of the rows shown; offset(x, n), the value n rows below in the rows shown (-1 the row above, empty past the first or last), and index(x, n), the value in row n of the rows shown (counting from 1), such as ${Sales} - offset(${Sales}, 1) for the lead over the next row; median(x), and count(x) of its values that aren't empty, over the rows shown; running_total(x), the sum of x from the first row shown down to this one, in the rows' order; power(x, y), x to the power y (empty for a negative x with a fractional y); diff_days(start, end), the whole days from the start date to the end date, negative when the end is earlier, empty when either is empty - `as` (string, required): The column's name - `columnOrder` (array of string): Every column once, by its name before renames, in the order to show them, removed columns optional; omit for dimensions, measures, then calculations - `pivotLayout` (object): Omit for the default: columns in the order their values first appear - `columns` (object, required) - When `mode` is `fixed` - `mode` (`fixed`, required) - `values` (array of object, required): One column per value, each under its own name: two values never share a column - When `mode` is `discover` - `mode` (`discover`, required) - `order` (string, required): One of `asc`, `desc`, `first_seen`. - `limit` (integer, required) - `nullLabel` (string or null, required): Column name for NULL values; null drops them - `fill` (number or null, required): Value for empty cells; null leaves them empty - `filters` (array of object, required): All must hold - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `renames` (array of object): Output columns under another name - `from` (string, required): A column name, exact and case-sensitive - `to` (string, required): The column's new name - `sorts` (array of object, required): Columns to sort by, the first first, each next one breaking ties; empty for none - `column` (string, required): A column, by its name before renames; a split's cell by its values - `direction` (string, required): One of `asc`, `desc`. - `nulls` (string): One of `first`, `last`. - `limit` (integer or object or null, required): Rows to keep: a number, an integer parameter, or null for all - `type` (`parameter`, required) - `key` (string, required) - `limitFrom` (string): One of `start`, `end`. - `totals` (object): A table's total row and, with a split, its Total column, each measure over the rows shown (under a limit, only those). Omit for none - `row` (boolean, required): A last row with the total of each column; charts leave it out - `column` (boolean, required): With a pivot after the aggregate: a Total column with each row across the pivot - `formats` (array of object): numfmt patterns by output column - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - `removedColumns` (array of string): Columns, by their name before renames, to leave out of the rows while keeping the grouping, e.g. group by region and month but show no region column; a split's column is named by its values - `keepGroupsWhere` (array of object): Conditions on the grouped rows' dimensions and measures (by their name before renames), all of which must hold, right after the grouping and before the calculations, the sort and the limit, as SQL's HAVING does, so the calculations and the limit only see the rows kept: each region's share among the regions with more than 20 deals. To keep rows by a measure or a calculation while the calculations still cover every group, as for the top 10 of the customers over 1,000,000, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsBeforeLimit` (array of object): Conditions on the grouped rows' dimensions, measures and before-limit calculations (by their name before renames), all of which must hold, after the calculations and before the column order, the sort and the limit, so the limit counts only the rows kept while the calculations still cover every group: the top 10 customers of those over 1,000,000, the regions with over 5% of the total. A condition on a calculation that reads the rows the limit keeps (sum(), offset()) goes in keepRowsWhere. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `keepRowsWhere` (array of object): Conditions on the rows' own columns (dimensions, measures and calculations by their name before renames), all of which must hold, after the sort, the limit and every calculation: keep the rank 1 row of the top 10, with its share of the 10. To keep rows before the limit, use keepRowsBeforeLimit. Needs a dimension or measure and no split - When `kind` is `compare` - `kind` (`compare`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`. - `value` (object, required) - When `kind` is `in` - `kind` (`in`, required) - `column` (string, required): A column name, exact and case-sensitive - `values` (array of object, required) - `negate` (boolean, required) - When `kind` is `between` - `kind` (`between`, required) - `column` (string, required): A column name, exact and case-sensitive - `from` (object, required) - `to` (object, required) - When `kind` is `text` - `kind` (`text`, required) - `column` (string, required): A column name, exact and case-sensitive - `op` (string, required): One of `equals`, `contains`, `starts_with`, `ends_with`. - `value` (object, required) - `caseSensitive` (boolean, required) - `negate` (boolean, required) - When `kind` is `is_blank` - `kind` (`is_blank`, required) - `column` (string, required): A column name, exact and case-sensitive - `negate` (boolean, required) - When `kind` is `relative_date` - `kind` (`relative_date`, required) - `column` (string, required): A column name, exact and case-sensitive - `range` (string, required): One of `current`, `last`, `next`. - `count` (integer or null, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - `complete` (boolean): last/next only: whole units, leaving out the current one, e.g. the last 3 complete months on Oct 21 are Jul, Aug and Sep. Omit for the window through today - `includeCurrent` (boolean): With complete only: the current unit too, e.g. the last 1 complete year with the current one is last year and this year. Omit to leave it out - `toDate` (boolean): current only: the unit so far, through today, e.g. this year to date. Omit for the whole unit - `earlier` (object): current/last only: the same window, this many units earlier: this year to date 1 year earlier is the same dates last year, and the last 3 complete months 3 months earlier are the 3 months before them. Omit for the window itself - `count` (integer, required) - `unit` (string, required): One of `day`, `week`, `month`, `quarter`, `year`. - When `type` is `set-ops` - `type` (`set-ops`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `parameters` (array of object or null): Replaces the datasheet's complete parameter set; omit to keep it - `key` (string, required) - `parameter` (object, required) - When `type` is `string` - `label` (string, required) - `type` (`string`, required) - `value` (string or null, required) - When `type` is `integer` - `label` (string, required) - `type` (`integer`, required) - `value` (integer or null, required) - When `type` is `number` - `label` (string, required) - `type` (`number`, required) - `value` (number or null, required) - When `type` is `boolean` - `label` (string, required) - `type` (`boolean`, required) - `value` (boolean or null, required) - When `type` is `date` - `label` (string, required) - `type` (`date`, required) - `value` (string (date) or null, required) - When `type` is `timestamp` - `label` (string, required) - `type` (`timestamp`, required) - `value` (string (date-time) or null, required) - `ops` (array of object, required): The complete op list after the reads, in run order: an op whose ref is an existing op id keeps that op, and existing ops left out are removed. Only on a datasheet with a join step: keep the join first with steps after it; on any other, use set-query - `ref` (string, required): An existing op id to keep that op, or a new short name - `title` (string or null): Omit to keep a kept op's title; a step op without one shows its step summary - `inputs` (array of object or null): Omit to keep a kept op wired as it is (one that read the op above reads its new op above). A new op reads the op above, which SQL reads as `input`; a new first op reads the datasheet's one read, as `source` or the read's alias - `alias` (string or null): SQL ops: the name the statement reads this input by - `from` (string, required): previous: the op above (above the first op, the datasheet's one read); op: the one ref names One of `previous`, `op`. - `ref` (string or null): op: the ref of an earlier op in this list, or a read's operation id or alias - `step` (object or null): A step op's call; on a kept op, send it only to change it - `fn` (string, required): One of `select`, `rename`, `filter`, `sort`, `limit`, `aggregate`, `pivot`, `window`, `join`. - `params` (object, required): The params of its fn, whose exact JSON Schema getReportDataGuide answers when you name the fn in stepFunctions - `formats` (array of object or null): Replaces the datasheet's formats; omit to keep them - `column` (string, required): An output column, by the name it is shown under, after any rename - `format` (string, required): numfmt pattern, e.g. #,##0.00, $#,##0, 0.0%, yyyy-mm-dd - When `type` is `set-read-type` - `type` (`set-read-type`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `readType` (string, required): aggregated: its data, as the tool displays it; raw: its tidy read, to transform; image: its picture One of `aggregated`, `raw`, `image`. - When `type` is `set-unpivot` - `type` (`set-unpivot`, required) - `datasheetRef` (string, required): An existing datasheet id, or the temporaryId of a datasheet created earlier in this patch - `unpivot` (object or null, required): The columns of the range this datasheet reads to turn into rows, which every datasheet reading the range raw gets, and this one then reads it raw; null reads the range as the sheet shows it - `rows` (array of object, required): One output row per input row and entry, in this order; the input columns no entry names repeat on each - `label` (string, required): What the name column says on this row, such as the column's name or "2022" - `columns` (array of string or null, required): The input column for each of values, in order; null leaves that value empty on this row - `name` (string, required): The column that holds each row's label, such as "Year" - `values` (array of string, required): The columns the values go in: one, such as "Value", or one per measure - `revisions` (object, required): The `revisions` the preview of the same changes answered. The save is refused when a datasheet they name changed since, so it never writes over someone else's edit: preview again and save the new revisions. #### Response `200` Success `application/json` - When `saved` is `true` - `saved` (`true`, required) - `versionBeforeId` (string, required): The version of the report from before the save, which `restoreReportVersion` restores with its datasheets as they were. - `resolvedDatasheetIds` (object, required): The id of each datasheet a `create` made, by its `temporaryId`. Place it on a slide by this id. - `datasheets` (array of object, required): The datasheets on slides whose data was read again, each with its error when the read failed. - `id` (string, required) - `error` (string or null, required) - When `saved` is `false` - `saved` (`false`, required) - `error` (string, required): Why nothing was saved: the changes failed, or a datasheet they edit changed since the preview. Preview again and save with the new `revisions`. ## Parameters Named values of a report, such as a region, that it writes into the filters of the dashboards its datasheets read, and as row filters into columns of its datasheets. One parameter can link differently named filters on several dashboards, and columns of several datasheets, and setting its value filters all of them the same way. A burst's variants each hold their own value of the parameters it varies by. See a report's parameters and the filters and columns they can link with `getReportParameters`, then create one with `createReportParameter`. Change a parameter's value, name, filters or columns with `updateReportParameter`, for example to show the report for another region, or delete it with `deleteReportParameter`. A report that reads no dashboard has no filters to link, but its datasheets can have columns to link once they were read. ### Get report parameters `GET https://api.rollstack.com/public/v1/reports/{id}/parameters` A report's parameters, with which ones a burst can vary by, the dashboard filters and the datasheet columns a parameter can link, with the parameter that already links each. Requires the `slide_decks:read` scope. Operation ID: `getReportParameters`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Response `200` Success `application/json` - `parameters` (array of object, required): The report's parameters, oldest first. Empty until one is created, here or in the app. - `id` (string, required): The report parameter's id. Pass it in `parameterIds` to `createBurst` when `burstable` is `true`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The parameter's value, which the report's datasheets read through the filters it links. `null` when it has none, and those filters keep their own values. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `columns` (array of object, required): The columns of datasheets the parameter links: its value is written into each as a row filter, in that datasheet only. Empty when it links none. - `datasheetId` (string, required): The datasheet's id, as in `listReportDatasheets`. - `datasheetName` (string or null, required): The datasheet's name, or `null` if it has none. - `column` (string, required): The column's name in the datasheet's source. - `kind` (string, required): The kind of value that filters the column, and so the `type` of a parameter value that reaches it: `categorical` takes a list, `number` a number and `date` a date. One of `categorical`, `number`, `date`. - `isLinked` (boolean, required): `false` once the column was unlinked in Rollstack: the parameter no longer writes into it. - `burstable` (boolean, required): Whether a burst can vary by the parameter: it links at least one filter whose `valueType` isn't `null`, or at least one column that is still linked. A parameter that links neither can't be. - `filters` (array of object, required): The filters a parameter can link: those of the dashboards the report's datasheets read. Empty when the report reads no dashboard, such as one built only from uploaded files and spreadsheet ranges, which can't have parameters. - `id` (string, required): The filter's id. Pass it in `filterIds` to `createReportParameter`. - `name` (string, required): The filter's name on its dashboard. - `connectionType` (string, required): The kind of connection the dashboard is on, such as `Looker`. One of `GoogleSheet`, `GoogleExcel`, `MicrosoftExcel`, `Tableau`, `Salesforce`, `Metabase`, `PowerBI`, `Looker`, `RollstackVariable`, `Lightdash`, `Omni`, `Sigma`, `Snowflake`, `Databricks`, `BigQuery`, `CsvUpload`, `XlsxUpload`, `ManualTable`, `Dbt`. - `dashboardName` (string, required): The dashboard the filter is on, as its connection names it. - `datasheets` (array of object, required): The report's datasheets that read the filter's dashboard, which a parameter linking it writes its value into. - `id` (string, required): The datasheet's id, as in `listReportDatasheets`. - `name` (string, required): The datasheet's name. - `parameterId` (string or null, required): The parameter that links the filter, by its `id` in `parameters`. A filter follows one parameter at most, so a new parameter can only link filters where this is `null`. - `valueType` (string or null, required): The kind of value Rollstack can set in the filter, and so the `type` of a parameter value that reaches it. `null` when only the dashboard's own embed can edit the filter: a parameter can link it, but can't set its value or be burst by it. One of `categorical`, `date`, `number`, `text`. - `columns` (array of object, required): The columns a parameter can link: those of the datasheets the report has already read, from a source Rollstack can filter by rows, with a kind of value that can filter them. A datasheet never read, or read before Rollstack kept its columns' types, has none: see `datasheetsToRefresh`. - `datasheetId` (string, required): The datasheet's id, as in `listReportDatasheets`. Pass it in `columns` to `createReportParameter`. - `datasheetName` (string, required): The datasheet's name. - `column` (string, required): The column's name in the datasheet's source. - `kind` (string, required): The kind of value that filters the column: `categorical` takes a list, `number` a number and `date` a date. One of `categorical`, `number`, `date`. - `parameterId` (string or null, required): The parameter that links the column, by its `id` in `parameters`. A column follows one parameter at most, so a new parameter can only link columns where this is `null`. - `datasheetsToRefresh` (array of object, required): The datasheets whose columns can be linked once the report is run again, as a run reads them. - `id` (string, required) - `name` (string, required) ### Create report parameter `POST https://api.rollstack.com/public/v1/reports/{id}/parameters` Creates a parameter of a report, linked to the dashboard filters and datasheet columns given, as the app's report parameters editor does. With a value, writes it into those filters, and as a row filter into those columns, and reads their datasheets again. Answers the parameter. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `createReportParameter`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): The parameter's name, as shown in Rollstack. It can't be the name of another parameter of the report. Example: `Region`. - `filterIds` (array of string (uuid)): The filters the parameter links, by their `id` in `filters` from `getReportParameters`: its value is written into each, in every datasheet that reads its dashboard. Each must have no `parameterId` yet. A burst can vary by the parameter only if one of them has a `valueType`, or it links a column. Defaults to `[]`. - `columns` (array of object): The columns the parameter links, by `datasheetId` and `column` as `columns` in `getReportParameters` lists them: its value is written into each as a row filter, in that datasheet only. Each must have no `parameterId` yet. The value's `type` follows the first filter's `valueType`, or the first column's `kind` when it links no filter that can be set. Defaults to `[]`. - `datasheetId` (string (uuid), required): The datasheet's id, as `datasheetId` in `columns` from `getReportParameters`. - `column` (string, required): The column's name, as `column` in `columns` from `getReportParameters`. - `value` (object or null): The parameter's value, of the `valueType` of the filters it links. When set, it is written into those filters and their datasheets are read again with it, so the report's slides change. If `null` or omitted, as for a parameter a burst's variants will set, the filters keep their own values. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. Defaults to `null`. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) #### Response `201` Success `application/json` - `id` (string, required): The report parameter's id. Pass it in `parameterIds` to `createBurst` when `burstable` is `true`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The parameter's value, which the report's datasheets read through the filters it links. `null` when it has none, and those filters keep their own values. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `columns` (array of object, required): The columns of datasheets the parameter links: its value is written into each as a row filter, in that datasheet only. Empty when it links none. - `datasheetId` (string, required): The datasheet's id, as in `listReportDatasheets`. - `datasheetName` (string or null, required): The datasheet's name, or `null` if it has none. - `column` (string, required): The column's name in the datasheet's source. - `kind` (string, required): The kind of value that filters the column, and so the `type` of a parameter value that reaches it: `categorical` takes a list, `number` a number and `date` a date. One of `categorical`, `number`, `date`. - `isLinked` (boolean, required): `false` once the column was unlinked in Rollstack: the parameter no longer writes into it. - `burstable` (boolean, required): Whether a burst can vary by the parameter: it links at least one filter whose `valueType` isn't `null`, or at least one column that is still linked. A parameter that links neither can't be. - `runId` (string or null, required): The run that reads again the datasheets the value was written into, as `runId` in `getReportRun`. When a run of the report is already going, it reads them after that run. `null` when no value was written, or when you can't run the report. ### Update report parameter `PATCH https://api.rollstack.com/public/v1/reports/{id}/parameters/{parameterId}` Changes a parameter of a report, such as its value to show the report for another region, as the app's report parameters editor does: what you send changes and the rest stays. A new value is written into the filters and columns it links and their datasheets are read again, so the report's slides change; follow that read with runId. Answers the parameter. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `updateReportParameter`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `parameterId` (string (uuid), required): The parameter to act on, by its `id` in `parameters` from `getReportParameters`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): The parameter's new name, as shown in Rollstack. It can't be the name of another parameter of the report. Example: `Region`. - `filterIds` (array of string (uuid)): All the filters the parameter links from now on, by their `id` in `filters` from `getReportParameters`, replacing the ones it links: a filter left out keeps the value it holds, and a filter added must have no other `parameterId`. If omitted, it links the same filters. - `columns` (array of object): All the columns the parameter links from now on, by `datasheetId` and `column` as `columns` in `getReportParameters` lists them, replacing the ones it links: a column left out keeps the row filter it holds, and a column added must have no other `parameterId`. If omitted, it links the same columns. - `datasheetId` (string (uuid), required): The datasheet's id, as `datasheetId` in `columns` from `getReportParameters`. - `column` (string, required): The column's name, as `column` in `columns` from `getReportParameters`. - `value` (object or null): The parameter's new value, of the `valueType` of the filters it links. It is written into those filters and their datasheets are read again with it, so the report's slides change. `null` clears it, and the filters keep the values they hold. If omitted, the value stays. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) #### Response `200` Success `application/json` - `id` (string, required): The report parameter's id. Pass it in `parameterIds` to `createBurst` when `burstable` is `true`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The parameter's value, which the report's datasheets read through the filters it links. `null` when it has none, and those filters keep their own values. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `columns` (array of object, required): The columns of datasheets the parameter links: its value is written into each as a row filter, in that datasheet only. Empty when it links none. - `datasheetId` (string, required): The datasheet's id, as in `listReportDatasheets`. - `datasheetName` (string or null, required): The datasheet's name, or `null` if it has none. - `column` (string, required): The column's name in the datasheet's source. - `kind` (string, required): The kind of value that filters the column, and so the `type` of a parameter value that reaches it: `categorical` takes a list, `number` a number and `date` a date. One of `categorical`, `number`, `date`. - `isLinked` (boolean, required): `false` once the column was unlinked in Rollstack: the parameter no longer writes into it. - `burstable` (boolean, required): Whether a burst can vary by the parameter: it links at least one filter whose `valueType` isn't `null`, or at least one column that is still linked. A parameter that links neither can't be. - `runId` (string or null, required): The run that reads again the datasheets the value was written into, as `runId` in `getReportRun`. When a run of the report is already going, it reads them after that run. `null` when no value was written, or when you can't run the report. ### Delete report parameter `DELETE https://api.rollstack.com/public/v1/reports/{id}/parameters/{parameterId}` Deletes a parameter of a report, as the app's report parameters editor does. The filters and columns it linked keep the last value it wrote, and a burst that varies by it stops varying by it. Refused for the last parameter a burst varies by, and on a burst's variant, whose parameters follow its template report's: delete it there. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `deleteReportParameter`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `parameterId` (string (uuid), required): The parameter to act on, by its `id` in `parameters` from `getReportParameters`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Sharing Who a report is shared with. Share a report with a member of the organization to let them `view` or `edit` it; they get an email. Sharing again with another permission changes it. The owner always has access. `getReport` lists everyone the report is shared with, and `getReportViews` who opened it and how far they read. ### Get report views `GET https://api.rollstack.com/public/v1/reports/{id}/views` Who opened a report and how they read it, as its editors see under Views in the app: each person's visits, time spent and whether they opened it since its last successful run, who it is shared with but hasn't opened it since, and how far into it people read, slide by slide. Editors' own time editing doesn't count. Only its editors may. Requires the `slide_decks:read` scope. Operation ID: `getReportViews`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Response `200` Success `application/json` - `visits` (number, required): How many times people opened the report to read it, editors' own edits left out. Visits a few minutes apart count as one, and ones under 5 seconds don't count. - `medianVisitSeconds` (number or null, required): How long a visit lasts, as the median in seconds. `null` with no visits. - `lastUpdatedAt` (string (date-time) or null, required): When the report's last successful run ended, which `openedSinceUpdate` compares to. `null` if it never ran. - `people` (array of object, required): Who opened the report, the most recent first. - `user` (object, required) - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `visits` (number, required): How many times they opened it. - `seconds` (number, required): How long they spent on it in all, in seconds. - `lastViewedAt` (string (date-time), required): When they last had it open. - `openedSinceUpdate` (boolean, required): Whether they opened it since its last successful run, so saw its latest numbers. - `notOpened` (array of object, required): The members it is shared with who haven't opened it since its last successful run, you left out. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `slides` (array of object, required): How far into the report people read, slide by slide. - `slideId` (string, required): The slide, as `slideId` in `getReportContent`. - `reach` (number, required): The share of visits that reached the slide, from 0 to 1. - `medianSeconds` (number or null, required): How long a visit stays on the slide, as the median in seconds. ### Share report `PUT https://api.rollstack.com/public/v1/reports/{id}/shares/{userId}` Shares a report of any type with a member of the organization to view or edit it, or changes their permission. They get an email. A report that updates a file, such as a Google Slides presentation, also shares the file with them, as the app does. Requires the `slide_decks:write` scope. Operation ID: `shareReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. - `userId` (integer, required): The member to share the report with, or to unshare it from. Use their `id` from `listMembers`, which only owners and admins can call, or their `userId` in `sharedWith` from `getReport` if the report is already shared with them. You can share a report only with active members of the organization, and not with yourself. Anyone the report is shared with can unshare it from themselves, even with `view` permission. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `permission` (string, required): What the member can do with the report. `view` lets them open, export and duplicate it. `comment` also lets them add, reply to and resolve comments on its slides. `edit` also lets them change its slides, data, schedules, email and other settings, run it, send its email, chat with the slides agent about it, and manage who it's shared with. Neither lets them delete the report or transfer its ownership. If the report is already shared with the member, this replaces their permission and they aren't notified again. On a report that updates a file in Google Drive or OneDrive, Rollstack also shares the file with them, as the app does. One of `view`, `comment`, `edit`. #### Response `200` Success `application/json` - `userId` (number, required): The member the report is now shared with: the `userId` from the path. - `permission` (string, required): What the member can now do with the report: the `permission` you sent. One of `view`, `comment`, `edit`. ### Unshare report `DELETE https://api.rollstack.com/public/v1/reports/{id}/shares/{userId}` Removes a user's share of a report of any type, and their access to its file when it updates one, as the app does. Requires the `slide_decks:write` scope. Operation ID: `unshareReport`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. - `userId` (integer, required): The member to share the report with, or to unshare it from. Use their `id` from `listMembers`, which only owners and admins can call, or their `userId` in `sharedWith` from `getReport` if the report is already shared with them. You can share a report only with active members of the organization, and not with yourself. Anyone the report is shared with can unshare it from themselves, even with `view` permission. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Comments What reviewers say about a report's slides, as in its comments in the app. A comment starts a thread on a slide, and replies follow it until someone resolves the thread. Read the comments with `listReportComments`, make the changes they ask for, for example by asking the slides agent in Chat, then reply with `createReportComment` and resolve the thread with `resolveReportComment`. ### List comments `GET https://api.rollstack.com/public/v1/reports/{id}/comments` The comments on a report's slides, oldest first: each thread's first comment, whose threadId is null and which says whether the thread is resolved, then its replies. Read the open threads to see what reviewers asked for. Members who can view the report may. Requires the `slide_decks:read` scope. Operation ID: `listReportComments`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the comment. Pass a thread's first comment's id as `threadId` to reply to it, or to `resolveReportComment`. - `threadId` (string or null, required): The thread the comment replies to, by its first comment's `id`. `null` for the comment that starts a thread. - `slideId` (string, required): The slide the thread is on, as `slideId` in `getReportContent`. - `text` (string, required): What the comment says, as plain text: a mention reads as `@` and the name, and a request to the Rollstack Agent as `@Rollstack`. - `author` (object, required): Who wrote it. A reply the Rollstack Agent posted names the member who asked it. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `byAgent` (boolean, required): Whether the Rollstack Agent posted it, answering a comment that tagged @Rollstack. - `createdAt` (string (date-time), required): When the comment was posted. - `resolvedAt` (string (date-time) or null, required): When its thread was resolved. Only a thread's first comment has it; `null` while the thread is open. - `resolvedBy` (object or null, required): Who resolved the thread. `null` while it is open. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. ### Add comment `POST https://api.rollstack.com/public/v1/reports/{id}/comments` Starts a comment thread on a slide of a report, or replies to a thread, as the user. A reply notifies the thread's other participants who can still open the report. Members who can comment on the report may. Requires the `slide_decks:write` scope. Operation ID: `createReportComment`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `text` (string, required): The comment, as plain text: each line becomes a paragraph, and Markdown marks such as `**` and `#` are removed. Mentions and @Rollstack requests can only be written in the app. At most 5000 characters. Example: `Updated the EMEA numbers on this slide.`. - `slideId` (string): The slide to start a new thread on, as `slideId` in `getReportContent`. Leave it out with `threadId`. - `threadId` (string): The thread to reply to, by its first comment's `id` from `listReportComments`. The reply goes on the thread's slide, and the thread's other participants are notified. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the comment. Pass a thread's first comment's id as `threadId` to reply to it, or to `resolveReportComment`. - `threadId` (string or null, required): The thread the comment replies to, by its first comment's `id`. `null` for the comment that starts a thread. - `slideId` (string, required): The slide the thread is on, as `slideId` in `getReportContent`. - `text` (string, required): What the comment says, as plain text: a mention reads as `@` and the name, and a request to the Rollstack Agent as `@Rollstack`. - `author` (object, required): Who wrote it. A reply the Rollstack Agent posted names the member who asked it. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `byAgent` (boolean, required): Whether the Rollstack Agent posted it, answering a comment that tagged @Rollstack. - `createdAt` (string (date-time), required): When the comment was posted. - `resolvedAt` (string (date-time) or null, required): When its thread was resolved. Only a thread's first comment has it; `null` while the thread is open. - `resolvedBy` (object or null, required): Who resolved the thread. `null` while it is open. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. ### Resolve comment thread `POST https://api.rollstack.com/public/v1/reports/{id}/comments/{commentId}/resolve` Resolves a comment thread once what it asked for is done, or opens it again, as the user. Only a thread's first comment can be resolved. Members who can comment on the report may. Requires the `slide_decks:write` scope. Operation ID: `resolveReportComment`. #### Path parameters - `id` (string, required): The report to act on, by its `id` from `listReports` or `createReport`. Only reports whose `type` is `SlideDeck` work here: another type, such as a Google Slides presentation, returns `400`. You can also copy it from the report's link in Rollstack: it's the part right after `/slides/`. - `commentId` (string, required): The thread to act on, by its first comment's `id` from `listReportComments`, the one whose `threadId` is `null`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `resolved` (boolean): `true` to resolve the thread, `false` to open it again. Defaults to `true`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the comment. Pass a thread's first comment's id as `threadId` to reply to it, or to `resolveReportComment`. - `threadId` (string or null, required): The thread the comment replies to, by its first comment's `id`. `null` for the comment that starts a thread. - `slideId` (string, required): The slide the thread is on, as `slideId` in `getReportContent`. - `text` (string, required): What the comment says, as plain text: a mention reads as `@` and the name, and a request to the Rollstack Agent as `@Rollstack`. - `author` (object, required): Who wrote it. A reply the Rollstack Agent posted names the member who asked it. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `byAgent` (boolean, required): Whether the Rollstack Agent posted it, answering a comment that tagged @Rollstack. - `createdAt` (string (date-time), required): When the comment was posted. - `resolvedAt` (string (date-time) or null, required): When its thread was resolved. Only a thread's first comment has it; `null` while the thread is open. - `resolvedBy` (object or null, required): Who resolved the thread. `null` while it is open. - `id` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. ## Schedules When a report updates on its own. Each schedule starts a run of the whole report at the times it sets, in its timezone: hourly at chosen times of day, or on a cron expression for daily, weekly, monthly, quarterly and yearly ones. A report has up to 10 schedules, replaced together. Schedules are checked every 15 minutes, so a cron expression must run at minute 0, 15, 30 or 45. ### List schedules `GET https://api.rollstack.com/public/v1/reports/{id}/schedules` The schedules of a report of any type, with the syncs each updates and when each runs next, or null for one that never runs again. Read them before `updateReportSchedules`, which replaces them all. Requires the `slide_decks:read` scope. Operation ID: `getReportSchedules`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. ### Replace report schedules `PUT https://api.rollstack.com/public/v1/reports/{id}/schedules` Replaces the schedules of a report of any type, at most 10; an empty list removes them all. Only its editors may. A scheduled run updates the whole report: an AI update on a SlideDeck report, and a refresh of every sync on a report of another type, or only the `syncIds` a schedule names. Schedules are checked every 15 minutes, so a cron that fires more often still runs at most once per 15 minutes. Requires the `slide_decks:write` scope. Operation ID: `updateReportSchedules`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `schedules` (array of object, required): The report's new schedules. They replace all of its current schedules, so read them with `getReportSchedules` first and include any you want to keep, with their `syncIds`; send an empty list to remove them all. When several schedules fall at the same time, the report runs once. Up to 10. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`, and takes no `cronExpression`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires, and take no `selectedTimes`. For those, the frequency doesn't change when the report runs, but the app uses it to describe and edit the schedule, so pick the one that matches your cron expression. One of `hourly`, `daily`, `weekly`, `monthly`, `quarterly`. - `cronExpression` (string): When a `daily`, `weekly`, `monthly` or `quarterly` schedule runs: a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`, such as `0 9 * * 1` for every Monday at 9:00, or `0 9 L * *` for 9:00 on the last day of each month. Required for those frequencies; omit it for `hourly`. Rollstack checks schedules every 15 minutes, so the minute field must include 0, 15, 30 or 45, and runs at other minutes are skipped. At most 100 characters. Example: `0 9 * * 1`. - `selectedTimes` (array of string): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`, such as `09:00` or `13:45`. Required for `hourly`; omit it for other frequencies. Each time must be on the quarter hour (`:00`, `:15`, `:30` or `:45`). From 1 to 96 times. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. For frequencies other than `hourly`, set it to the date and time of the first run: the app shows its time as the schedule's time, and when someone changes the schedule's frequency or days there, it rebuilds `cronExpression` at that time. Example: `2026-11-02T09:00:00Z`. - `endDate` (string (date-time) or null): When the schedule ends: it never runs the report after this date and time. Omit it or pass `null` for a schedule that never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. Must be later than `startDate`. Set it later than the last run you want: a run at exactly this time may be skipped. Defaults to `null`. Example: `2027-11-02T09:00:00Z`. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. UTC offsets such as `+05:30` aren't accepted. Example: `America/New_York`. - `syncIds` (array of string (uuid) or null): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. Omit it or pass `null` to update the whole report. Each id must be a sync of this report, so it only works on a report other than a `SlideDeck`. Keep the `syncIds` `getReportSchedules` returns for schedules you don't mean to change. A sync deleted later is skipped, so a schedule whose syncs are all gone updates nothing. Defaults to `null`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the schedule. `updateReportSchedules` replaces every schedule, so the ids change each time you call it. - `frequency` (string, required): How often the schedule runs. `hourly` runs every day at each time in `selectedTimes`. `daily`, `weekly`, `monthly` and `quarterly` run whenever `cronExpression` fires; those made in the app run every day, on chosen weekdays, on chosen days of the month, or every three months, respectively. `yearly` can't be set through the API or the app, and also runs on `cronExpression`. One of `daily`, `weekly`, `monthly`, `quarterly`, `hourly`, `yearly`. - `cronExpression` (string, required): When the schedule runs, as a five-field cron expression (minute, hour, day of month, month, day of week) in the schedule's `timezone`. For an `hourly` schedule, Rollstack generates it from `selectedTimes` and runs the report at those times instead. Monthly schedules made in the app can use `L` and `#`, such as `0 9 L * *` (last day of the month) or `0 9 ? * 1#1` (first Monday). - `selectedTimes` (array of string, required): The times of day an `hourly` schedule runs, every day, as 24-hour `HH:mm` in the schedule's `timezone`. Other frequencies don't use it; it's empty on those set through the API. - `startDate` (string (date-time), required): When the schedule starts: it never runs the report before this date and time. This is a local date and time in the schedule's `timezone`, written as if it were UTC: `2026-11-02T09:00:00Z` means 9:00 on November 2, 2026 in that timezone, not 9:00 UTC. - `endDate` (string (date-time) or null, required): When the schedule ends: it never runs the report after this date and time. `null` if the schedule never ends. Like `startDate`, this is a local date and time in the schedule's `timezone`, written as if it were UTC. - `timezone` (string, required): The timezone the schedule runs in. Its run times (`cronExpression` or `selectedTimes`), `startDate` and `endDate` are all local times in this timezone, so a schedule set for 9:00 keeps running at 9:00 local time when daylight saving time starts or ends. Given as an IANA timezone name, such as `America/New_York`. - `syncIds` (array of string or null, required): The syncs, from `listReportSyncs`, that the schedule updates on a report other than a `SlideDeck`. `null` when it updates the whole report, which a slide deck always does. - `nextRunAt` (string (date-time) or null, required): When the schedule will next run the report. `null` if it has no runs left before its `endDate`. Unlike `startDate` and `endDate`, this is an actual UTC time. ## Email Who a report's email goes to and how it is sent: its recipients, the sender it goes out through, whether it carries the report as a link, a PDF or a PowerPoint file, and which successful runs send it on their own. Set it up once, then send it now or let the report's runs send it. Send a test email to yourself to check how it looks first. Every send emails all the recipients, so sends have a low rate limit. ### List sent emails of all reports `GET https://api.rollstack.com/public/v1/emails` The emails every report the user can see sent, of any type, newest first, each with its report, as the app's Email sends page lists them: pass status failed and since to find the ones that didn't go out, and burstId for one burst's. Same fields as listReportEmails. Answers up to limit emails, 20 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listEmails`. #### Query parameters - `limit` (integer): Maximum number of emails to return on this page, from 1 to 200. Defaults to `20`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. - `status` (string): Only the emails in this state, as the Email sends page filters them: `failed` the ones that could not be sent, `opened` the ones a recipient opened, and `delivered` the ones the email server accepted, opened or not. If omitted, every email. One of `delivered`, `failed`, `opened`. - `since` (string (date-time)): Only what happened at or after this time, as an ISO 8601 date and time in UTC, such as `2026-11-08T18:00:00Z`. If omitted, from the start. Example: `2026-11-08T18:00:00Z`. - `burstId` (string): Only the emails of this burst, by its `id` from `listBursts`: each variant's own emails, and the emails its email configurations sent, which list its template as their report. If omitted, every report's. #### Response `200` Success `application/json` - `data` (array of object, required): The emails every report you can see sent, of any type, newest first, with what the Email sends page hides from you left empty. To find the emails that failed, pass `status` `failed` and `since`. - `id` (string, required): Identifies the sent email. - `sentAt` (string (date-time), required): When it was sent. - `status` (string, required): `delivered` when the email server accepted it, `failed` when it could not be sent (`error` says why), and `opened` once a recipient opened it, which Rollstack sees only when the organization has email analytics on. One of `delivered`, `failed`, `opened`. - `trigger` (string or null, required): `scheduled` when a scheduled run of the report sent it; `manual` when someone sent it, in the app or with `sendReportEmail`. `null` when it was not recorded. One of `manual`, `scheduled`. - `sender` (object, required): The member it was sent as: who sent it, or whose run sent it. - `name` (string or null, required) - `email` (string, required) - `subject` (string or null, required): The email's subject. `null` unless you own the report or it is shared with you directly, as on the Email sends page. - `to` (array of string, required): The addresses it was sent to. Empty unless you own the report, it is shared with you directly, or you are an owner or admin of the organization. - `cc` (array of string, required): The addresses copied on it, under the same rule as `to`. - `bcc` (array of string, required): The addresses it was blind-copied to, under the same rule as `to`. - `error` (string or null, required): Why it could not be sent, when it `failed`. `null` otherwise, or when you may not see its `subject`. - `report` (object, required): The report that sent it. - `id` (string, required): The report's `id`, to pass to the `/reports/{id}` endpoints, such as `getReport`. - `name` (string or null, required): The report's name. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of emails. `null` when there are no more. ### Get email settings `GET https://api.rollstack.com/public/v1/reports/{id}/email-config` Who a report's email goes to and how it is sent, for a report of any type. Answers 404 until its email is set up, as on a burst's variant that sends no email of its own. For a burst, read `listBurstVariants`, which has every variant's recipients, and `listBurstEmailConfigs` rather than calling this on each variant. On an older report that sends to several recipient groups, `to`, `cc`, `bcc` and `replyTo` list every group's addresses together. Requires the `slide_decks:read` scope. Operation ID: `getReportEmailConfig`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Response `200` Success `application/json` - `to` (array of string, required): The addresses the report's email is sent to. When empty, no one receives it: the report's runs send no email and `sendReportEmail` returns 400. - `cc` (array of string, required): The addresses copied on the report's email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the report's email without the other recipients seeing them. - `replyTo` (array of string, required): The addresses recipients' replies go to instead of the sender. They don't receive the email themselves. Empty when replies go to the sender. - `groupRecipients` (boolean, required): Whether all the addresses in `to` receive one email together. When `false`, each address in `to` gets its own email with the same `cc`, `bcc` and `replyTo`, so the addresses in `cc` and `bcc` receive one copy per address in `to`. - `smtpServerId` (string or null, required): The SMTP connection the report's email is sent through, from `listSmtpConnections`; recipients see its `from` address as the sender. `null` when the email is sent from Rollstack's own address. - `sharingFormat` (string, required): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `trigger` (string, required): Which of the report's runs email it automatically. A run emails it when it updates everything, or when all its failures are in `ignoredFailureStatusMessages`. On a slide deck, `all` and `scheduled` work the same way: only runs started by its schedules (see `getReportSchedules`) send the email, and a slide deck with no datasheets is never emailed by its runs. On an older report, `all` emails after every run of the whole report, whether started by a schedule, with `startReportRun` or in the app, and `scheduled` only after runs its schedules start; a run of only some syncs never emails it. With `none` (Manual in the app), no run sends it: the email goes out only when sent with `sendReportEmail` or from the app. One of `all`, `none`, `scheduled`. - `ignoredFailureStatusMessages` (array of string, required): The failures that don't stop a run from emailing the report (see `trigger`). A run with failures still sends the email when all of them are in this list. On a slide deck, a run in which every datasheet fails never does. A slide deck's run records each failed datasheet as `internal_server_error`, so on a slide deck that is the only value with an effect. An older report's run records each failed sync's own reason, the `error.code` `listReportSyncs` shows. The other values describe why a sync of an older report failed, and have an effect only on older reports: - `dashboard_not_found`, or the older `tableau_view_not_found`: the dashboard, Tableau workbook, Power BI report or spreadsheet could not be found. - `dashboard_tab_not_found`: the dashboard tab, Tableau view, Power BI report page or spreadsheet sheet could not be found. - `dashboard_not_ready`: the dashboard took too long to load. - `dashboard_has_errors`: the dashboard or spreadsheet failed to load because of an error in the tool it comes from. - `dashboard_invalid_layout`: the dashboard's layout is invalid, and it needs to be saved again. - `element_not_found`, or the older `metabase_element_not_found` and `looker_element_not_found`: the visualization could not be found. - `slide_not_found`, or the older `google_slide_not_found`: the slide that shows the visualization could not be found. - `file_not_found`: the spreadsheet file the visualization comes from could not be found. - `sheet_not_found`: the spreadsheet sheet could not be found. - `sheet_hidden`: the spreadsheet sheet is hidden and needs to be unhidden. - `range_not_found`: the spreadsheet range could not be found. - `duplicate_file_failed`: Rollstack could not prepare the spreadsheet file for the update. - `merged_range_on_filter_range`: the visualization has merged cells, which filters can't be applied to. - `insufficient_permissions`: the owner doesn't have edit access to the file. - `image_cropping_failed`: Rollstack could not crop the visualization's image. - `visualization_not_found`: the visualization could not be found in the dashboard. - `visualization_not_ready`: the visualization took too long to load. - `visualization_has_errors`: the visualization failed to load because of an error in the tool it comes from. - `visualization_empty`, or the older `empty_data`: the visualization is empty. - `invalid_credentials`: the connection's credentials are invalid. - `missing_credentials`: the connection's credentials were deleted, or the owner's access to it was suspended. - `instance_unavailable`: the data source's instance is temporarily unavailable. - `column_not_found`: a column the native chart uses is missing from its data. - `fetch_summary_data_error`, `fetch_visual_specification_error`, `missing_data`, `missing_formatted_value` and `viz_not_ready`: Rollstack could not fetch the data of a native chart. - `incorrect_data_structure`: the native chart's structure doesn't fit its data. - `malformed_data`: Rollstack could not fetch the data of a native chart or, from Snowflake or Databricks, the query is invalid. - `worksheet_not_found`: the Tableau worksheet could not be found. - `sync_not_found`: the visualization was deleted. - `file_update_failed`: the data was fetched but could not be written into the file. - `emailAnalyticsEnabled` (boolean, required): Whether Rollstack tracks when recipients open the report's email; opened emails show as Opened in the report's Email sends panel in the app. Opens are tracked only while email analytics is also on for the organization (`emailAnalyticsEnabled` from `getOrganization`). Rollstack detects them through an invisible image in the email. - `createdAt` (string (date-time), required): When the report's email settings were created. Until they exist, `getReportEmailConfig` returns 404. - `updatedAt` (string (date-time), required): When the report's email settings were last saved. Changes the slides agent makes to the recipients alone don't update it. ### Replace email settings `PUT https://api.rollstack.com/public/v1/reports/{id}/email-config` Sets who a report's email goes to and how it is sent, for a report of any type, replacing the settings this endpoint covers; Drive sharing, attachment folders and the email's subject and body stay as set in the app. Only its editors may. The sender must be the user's own or shared with the organization. A report that sends to several recipient groups returns 400: change those in the app. Requires the `slide_decks:email` scope. Operation ID: `updateReportEmailConfig`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `to` (array of string, required): The addresses to send the report's email to. If empty, no one receives it: the report's runs send no email and `sendReportEmail` returns 400. At most 100 addresses across `to`, `cc` and `bcc`. - `cc` (array of string): The addresses to copy on the report's email, which every recipient can see. If omitted, no one is copied. Counts toward the 100 addresses allowed across `to`, `cc` and `bcc`. Defaults to `[]`. - `bcc` (array of string): The addresses to also send the report's email to without the other recipients seeing them. If omitted, no one is blind-copied. Counts toward the 100 addresses allowed across `to`, `cc` and `bcc`. Defaults to `[]`. - `replyTo` (array of string): The addresses recipients' replies should go to instead of the sender. They don't receive the email themselves. If omitted, replies go to the sender. Defaults to `[]`. - `groupRecipients` (boolean): Whether to send one email to all the addresses in `to` together. Set it to `false` to send each address in `to` its own email with the same `cc`, `bcc` and `replyTo`; the addresses in `cc` and `bcc` then receive one copy per address in `to`. Defaults to `true`. - `smtpServerId` (string or null): The SMTP connection to send the report's email through, from `listSmtpConnections`; recipients see its `from` address as the sender. If `null` or omitted, the email is sent from Rollstack's own address. A connection `listSmtpConnections` doesn't list, or a Google or Microsoft account Rollstack can no longer send from, returns 403 unless it is already the report's sender. Defaults to `null`. Example: `9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a`. - `sharingFormat` (string): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. `cloudLink` on an older report, `link` on a slide deck, or `ppt` on a Google Docs or Word report returns 400. For `cloudLink`, set up the export in the report's Update runs settings in the app first. If omitted, keeps the current format, or for a report whose email isn't set up yet, `pdf` on a slide deck and `link` on an older report. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. If omitted, keeps the current setting, or for a report whose email isn't set up yet, `true` on a slide deck and `false` on an older report. - `trigger` (string): Which of the report's runs email it automatically. A run emails it when it updates everything, or when all its failures are in `ignoredFailureStatusMessages`. On a slide deck, `all` and `scheduled` work the same way: only runs started by its schedules (see `getReportSchedules`) send the email, and a slide deck with no datasheets is never emailed by its runs. On an older report, `all` emails after every run of the whole report, whether started by a schedule, with `startReportRun` or in the app, and `scheduled` only after runs its schedules start; a run of only some syncs never emails it. With `none` (Manual in the app), no run sends it: the email goes out only when sent with `sendReportEmail` or from the app. Defaults to `all`. One of `all`, `none`, `scheduled`. - `ignoredFailureStatusMessages` (array of string): The failures that shouldn't stop a run from emailing the report (see `trigger`). A run with failures still sends the email when all of them are in this list. On a slide deck, a run in which every datasheet fails never does. On a slide deck, include `internal_server_error` to email the report even when some of its datasheets fail. On an older report, include the `error.code` values from `listReportSyncs` to ignore. Defaults to `slide_not_found` alone, so by default a slide deck's run with any failed datasheet sends no email, and an older report's run still emails when only syncs on a missing slide fail. The other values describe why a sync of an older report failed, and have an effect only on older reports: - `dashboard_not_found`, or the older `tableau_view_not_found`: the dashboard, Tableau workbook, Power BI report or spreadsheet could not be found. - `dashboard_tab_not_found`: the dashboard tab, Tableau view, Power BI report page or spreadsheet sheet could not be found. - `dashboard_not_ready`: the dashboard took too long to load. - `dashboard_has_errors`: the dashboard or spreadsheet failed to load because of an error in the tool it comes from. - `dashboard_invalid_layout`: the dashboard's layout is invalid, and it needs to be saved again. - `element_not_found`, or the older `metabase_element_not_found` and `looker_element_not_found`: the visualization could not be found. - `slide_not_found`, or the older `google_slide_not_found`: the slide that shows the visualization could not be found. - `file_not_found`: the spreadsheet file the visualization comes from could not be found. - `sheet_not_found`: the spreadsheet sheet could not be found. - `sheet_hidden`: the spreadsheet sheet is hidden and needs to be unhidden. - `range_not_found`: the spreadsheet range could not be found. - `duplicate_file_failed`: Rollstack could not prepare the spreadsheet file for the update. - `merged_range_on_filter_range`: the visualization has merged cells, which filters can't be applied to. - `insufficient_permissions`: the owner doesn't have edit access to the file. - `image_cropping_failed`: Rollstack could not crop the visualization's image. - `visualization_not_found`: the visualization could not be found in the dashboard. - `visualization_not_ready`: the visualization took too long to load. - `visualization_has_errors`: the visualization failed to load because of an error in the tool it comes from. - `visualization_empty`, or the older `empty_data`: the visualization is empty. - `invalid_credentials`: the connection's credentials are invalid. - `missing_credentials`: the connection's credentials were deleted, or the owner's access to it was suspended. - `instance_unavailable`: the data source's instance is temporarily unavailable. - `column_not_found`: a column the native chart uses is missing from its data. - `fetch_summary_data_error`, `fetch_visual_specification_error`, `missing_data`, `missing_formatted_value` and `viz_not_ready`: Rollstack could not fetch the data of a native chart. - `incorrect_data_structure`: the native chart's structure doesn't fit its data. - `malformed_data`: Rollstack could not fetch the data of a native chart or, from Snowflake or Databricks, the query is invalid. - `worksheet_not_found`: the Tableau worksheet could not be found. - `sync_not_found`: the visualization was deleted. - `file_update_failed`: the data was fetched but could not be written into the file. Defaults to `["slide_not_found"]`. - `emailAnalyticsEnabled` (boolean): Whether to track when recipients open the report's email; opened emails show as Opened in the report's Email sends panel in the app. Setting it to `true` returns 403 unless email analytics is on for the organization (`emailAnalyticsEnabled` from `getOrganization`). Defaults to `false`. #### Response `200` Success `application/json` - `to` (array of string, required): The addresses the report's email is sent to. When empty, no one receives it: the report's runs send no email and `sendReportEmail` returns 400. - `cc` (array of string, required): The addresses copied on the report's email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the report's email without the other recipients seeing them. - `replyTo` (array of string, required): The addresses recipients' replies go to instead of the sender. They don't receive the email themselves. Empty when replies go to the sender. - `groupRecipients` (boolean, required): Whether all the addresses in `to` receive one email together. When `false`, each address in `to` gets its own email with the same `cc`, `bcc` and `replyTo`, so the addresses in `cc` and `bcc` receive one copy per address in `to`. - `smtpServerId` (string or null, required): The SMTP connection the report's email is sent through, from `listSmtpConnections`; recipients see its `from` address as the sender. `null` when the email is sent from Rollstack's own address. - `sharingFormat` (string, required): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `trigger` (string, required): Which of the report's runs email it automatically. A run emails it when it updates everything, or when all its failures are in `ignoredFailureStatusMessages`. On a slide deck, `all` and `scheduled` work the same way: only runs started by its schedules (see `getReportSchedules`) send the email, and a slide deck with no datasheets is never emailed by its runs. On an older report, `all` emails after every run of the whole report, whether started by a schedule, with `startReportRun` or in the app, and `scheduled` only after runs its schedules start; a run of only some syncs never emails it. With `none` (Manual in the app), no run sends it: the email goes out only when sent with `sendReportEmail` or from the app. One of `all`, `none`, `scheduled`. - `ignoredFailureStatusMessages` (array of string, required): The failures that don't stop a run from emailing the report (see `trigger`). A run with failures still sends the email when all of them are in this list. On a slide deck, a run in which every datasheet fails never does. A slide deck's run records each failed datasheet as `internal_server_error`, so on a slide deck that is the only value with an effect. An older report's run records each failed sync's own reason, the `error.code` `listReportSyncs` shows. The other values describe why a sync of an older report failed, and have an effect only on older reports: - `dashboard_not_found`, or the older `tableau_view_not_found`: the dashboard, Tableau workbook, Power BI report or spreadsheet could not be found. - `dashboard_tab_not_found`: the dashboard tab, Tableau view, Power BI report page or spreadsheet sheet could not be found. - `dashboard_not_ready`: the dashboard took too long to load. - `dashboard_has_errors`: the dashboard or spreadsheet failed to load because of an error in the tool it comes from. - `dashboard_invalid_layout`: the dashboard's layout is invalid, and it needs to be saved again. - `element_not_found`, or the older `metabase_element_not_found` and `looker_element_not_found`: the visualization could not be found. - `slide_not_found`, or the older `google_slide_not_found`: the slide that shows the visualization could not be found. - `file_not_found`: the spreadsheet file the visualization comes from could not be found. - `sheet_not_found`: the spreadsheet sheet could not be found. - `sheet_hidden`: the spreadsheet sheet is hidden and needs to be unhidden. - `range_not_found`: the spreadsheet range could not be found. - `duplicate_file_failed`: Rollstack could not prepare the spreadsheet file for the update. - `merged_range_on_filter_range`: the visualization has merged cells, which filters can't be applied to. - `insufficient_permissions`: the owner doesn't have edit access to the file. - `image_cropping_failed`: Rollstack could not crop the visualization's image. - `visualization_not_found`: the visualization could not be found in the dashboard. - `visualization_not_ready`: the visualization took too long to load. - `visualization_has_errors`: the visualization failed to load because of an error in the tool it comes from. - `visualization_empty`, or the older `empty_data`: the visualization is empty. - `invalid_credentials`: the connection's credentials are invalid. - `missing_credentials`: the connection's credentials were deleted, or the owner's access to it was suspended. - `instance_unavailable`: the data source's instance is temporarily unavailable. - `column_not_found`: a column the native chart uses is missing from its data. - `fetch_summary_data_error`, `fetch_visual_specification_error`, `missing_data`, `missing_formatted_value` and `viz_not_ready`: Rollstack could not fetch the data of a native chart. - `incorrect_data_structure`: the native chart's structure doesn't fit its data. - `malformed_data`: Rollstack could not fetch the data of a native chart or, from Snowflake or Databricks, the query is invalid. - `worksheet_not_found`: the Tableau worksheet could not be found. - `sync_not_found`: the visualization was deleted. - `file_update_failed`: the data was fetched but could not be written into the file. - `emailAnalyticsEnabled` (boolean, required): Whether Rollstack tracks when recipients open the report's email; opened emails show as Opened in the report's Email sends panel in the app. Opens are tracked only while email analytics is also on for the organization (`emailAnalyticsEnabled` from `getOrganization`). Rollstack detects them through an invisible image in the email. - `createdAt` (string (date-time), required): When the report's email settings were created. Until they exist, `getReportEmailConfig` returns 404. - `updatedAt` (string (date-time), required): When the report's email settings were last saved. Changes the slides agent makes to the recipients alone don't update it. ### List sent emails `GET https://api.rollstack.com/public/v1/reports/{id}/emails` The emails a report of any type sent, newest first: when, how, to whom, and whether each was delivered, failed or opened. To check many reports, call listEmails instead, which lists every report's emails with their report, and a burst's with its burstId. Answers up to limit emails, 20 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listReportEmails`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Query parameters - `limit` (integer): Maximum number of emails to return on this page, from 1 to 200. Defaults to `20`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The emails the report sent, newest first: the ones sent with `sendReportEmail` or from the app, and the ones its schedules' runs sent. Set up who gets them with `updateReportEmailConfig`. - `id` (string, required): Identifies the sent email. - `sentAt` (string (date-time), required): When it was sent. - `status` (string, required): `delivered` when the email server accepted it, `failed` when it could not be sent (`error` says why), and `opened` once a recipient opened it, which Rollstack sees only when the organization has email analytics on. One of `delivered`, `failed`, `opened`. - `trigger` (string or null, required): `scheduled` when a scheduled run of the report sent it; `manual` when someone sent it, in the app or with `sendReportEmail`. `null` when it was not recorded. One of `manual`, `scheduled`. - `sender` (object, required): The member it was sent as: who sent it, or whose run sent it. - `name` (string or null, required) - `email` (string, required) - `subject` (string or null, required): The email's subject. `null` unless you own the report or it is shared with you directly, as on the Email sends page. - `to` (array of string, required): The addresses it was sent to. Empty unless you own the report, it is shared with you directly, or you are an owner or admin of the organization. - `cc` (array of string, required): The addresses copied on it, under the same rule as `to`. - `bcc` (array of string, required): The addresses it was blind-copied to, under the same rule as `to`. - `error` (string or null, required): Why it could not be sent, when it `failed`. `null` otherwise, or when you may not see its `subject`. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of emails. `null` when there are no more. ### Send email `POST https://api.rollstack.com/public/v1/reports/{id}/emails` Emails a report to its recipients now, as it is. Only its editors may. Answers 400 when it has no recipients. An email report needs its email template set up in the app first. Sends in the background; while the user's send of the report is going, starts nothing. At most 5 sends a minute per user, test sends included. From an AI client, the send only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:email` scope. Operation ID: `sendReportEmail`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Send test email `POST https://api.rollstack.com/public/v1/reports/{id}/emails/test` Sends a report's email to the user only, and waits until it is sent. Only its editors may. Counts against the 5 sends a minute. Requires the `slide_decks:email` scope. Operation ID: `sendReportTestEmail`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Bursts A burst makes one report per audience from a template report: each variant is a copy of the template that holds its own values of what the burst varies by, such as a region or an account, so it shows only its data. A Rollstack report's burst varies by report parameters, which its datasheets read; an older report's burst, such as of a Google Slides or PowerPoint file, varies by filters of its syncs, and each variant is a copy of the file in the burst's folder. Make a report the template of a burst with `createBurst`, or find one with `listBursts`, then see its variants, where their runs stand and who they are emailed to with `listBurstVariants`. Add variants by their parameter or filter values, remove them, run them all with `startBurstRun`, and set who each one is emailed to. Adding and running variants answer at once: follow the batch you added with `getBurstVariantBatch` and the variants' runs with `getBurstRun`, which wait for them to end. Each variant is also a report, so the `/reports/{id}` endpoints its type takes work on it: an older report's variants don't take the ones for Rollstack reports, such as `getReportContent`. Change a burst's settings with `updateBurstSettings`, an older report's burst's filters with `updateBurstFilters`, rename it with `renameBurst` and delete it with `deleteBurst`. Its email comes two ways: each variant's own email, which its runs send to its own recipients (set them with `updateBurstVariantRecipients`, its settings with `updateBurstVariantEmailSettings`, and send now with `sendBurstVariantEmails`), and the burst's email configurations, each one email to its own recipients with every variant it selects (`listBurstEmailConfigs` and the endpoints next to it). ### List bursts `GET https://api.rollstack.com/public/v1/bursts` The bursts of reports the user can see, newest first: those of Rollstack reports, whose variants differ by report parameters, and those of older reports such as Google Slides or PowerPoint files, whose variants differ by filters, as kind says. Each comes with what its variants differ by and the template report they are copied from. You can filter by name, ignoring case. Answers up to limit bursts, 50 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. listReports leaves out the reports of a burst, its template and variants. Requires the `slide_decks:read` scope. Operation ID: `listBursts`. #### Query parameters - `name` (string): Only return bursts whose name contains this text, ignoring case: `region` matches `Regional Review`. Example: `regional`. - `limit` (integer): Maximum number of bursts to return on this page, from 1 to 200. Defaults to `50`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The bursts on this page, most recently created first. - `id` (string, required): Unique identifier for the burst. Pass it as `id` to the other `/bursts/{id}` endpoints. - `name` (string, required): Name of the burst, as members see it in Rollstack. It is the template report's name when the burst is created, and is part of each variant report's name unless `variantNaming` is `sameName`. - `folderId` (string or null, required): The folder the burst is in, by its `id` in `listFolders`. `null` when the burst is at the top level. - `owner` (object, required): The member who owns the burst: whoever created it, unless ownership has since been transferred in the app. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. - `templateReportId` (string or null, required): The template report, which every variant was copied from when it was added, by its `id` for `getReport` and the other `/reports/{id}` endpoints. Changes to the template reach existing variants only when pushed from the app; variants added later copy it as it is then. `null` if the template was deleted. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `kind` (string, required): What the variants differ by. `parameters`: report parameters of a Rollstack report, listed in `parameters` and set with `parameters` in `addBurstVariants`. `filters`: filters of an older report's syncs, such as a Google Slides or PowerPoint file, listed in `filters` and set with `filters` in `addBurstVariants`. One of `parameters`, `filters`. - `reportType` (string, required): The type of report the burst copies, as `type` in `listReports`: `SlideDeck` for a Rollstack report, which bursts by `parameters`, any other type for an older report, which bursts by `filters`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `parameters` (array of object, required): The template report's parameters the variants differ by, in the order their values name a variant. Each variant holds its own value of each, which its datasheets' filters read. Empty for a burst by `filters`. - `id` (string, required): The report parameter's id on the template report. Use it as a key of `parameters` in `addBurstVariants`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The template's value of the parameter, which a variant keeps when it doesn't set one. `null` when the template has none. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `filters` (array of object, required): The filters of the template report's syncs that the variants differ by, primary ones first in the order their values name a variant. Each variant holds its own value of each, applied to the syncs that read the filter's dashboard. Empty for a burst by `parameters`. - `id` (string, required): The filter's id. Use it as a key of `filters` in `addBurstVariants`. - `name` (string, required): The filter's name on its dashboard, as shown in Rollstack. - `primary` (boolean, required): Whether the filter names the variants: a variant added without a `name` is named after its primary filters' values, in order. A secondary filter only narrows what each variant shows. - `valueType` (string or null, required): The kind of value the filter takes, and so the `type` of a variant's value of it. `null` when Rollstack doesn't know the filter's editor: copy the shape of a variant's value instead. One of `categorical`, `date`, `number`, `text`. - `variantCount` (number, required): How many variants the burst has, including any you can't open. - `appUrl` (string (uri), required): Link that opens the burst in Rollstack. - `createdAt` (string (date-time), required): When the burst was created. `listBursts` returns the newest first. - `updatedAt` (string (date-time), required): When the burst's details last changed. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of bursts. `null` when there are no more. ### Create burst `POST https://api.rollstack.com/public/v1/bursts` Makes a report the template of a new burst, and answers the burst, named after the report and with no variants yet. Add them with addBurstVariants. A Rollstack report's variants differ by the report parameters in parameterIds, found with getReportParameters. An older report's variants differ by the filters in filters, found with listReportSyncFilters: a folder is made for the burst in Google Drive or OneDrive and the report's file is copied into it as the template, which can take a minute. Only the report's editors may. Requires the `slide_decks:write` scope. Operation ID: `createBurst`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `templateReportId` (string, required): The report to make the template of the burst, by its `id` from `listReports`. You must be able to edit it, and it can't already be part of a burst. A Rollstack report must have datasheets, and becomes the template as it is. An older report must have syncs: its file is copied into a new folder for the burst, and the copy becomes the template. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. - `parameterIds` (array of string (uuid)): For a Rollstack report: the template report's parameters the variants differ by, by their `id` from `getReportParameters`, in the order their values name a variant. Each must be `burstable` there. At least one. - `filters` (object): For an older report, such as a Google Slides or PowerPoint file: the filters of its syncs the variants differ by. - `primaryIds` (array of string, required): The filters that name the variants, by their `id` from `listReportSyncFilters`, in the order their values name a variant. 1 to 3. With more than one, each variant's file goes in a folder per value, one level per filter. - `secondaryIds` (array of string): Filters a variant can also set, which don't name it, by their `id` from `listReportSyncFilters`. Defaults to `[]`. - `parentFolderId` (string): For an older report: the Google Drive or OneDrive folder to create the burst's folder in, by its id in that drive. The template and the variants' files go in the burst's folder. Defaults to the top of your drive. - `driveId` (string): For an older report: the shared drive `parentFolderId` is in. Leave it out for a folder in your own drive. - `variantNaming` (string): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. Defaults to `suffix`. One of `sameName`, `prefix`, `suffix`. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the burst. Pass it as `id` to the other `/bursts/{id}` endpoints. - `name` (string, required): Name of the burst, as members see it in Rollstack. It is the template report's name when the burst is created, and is part of each variant report's name unless `variantNaming` is `sameName`. - `folderId` (string or null, required): The folder the burst is in, by its `id` in `listFolders`. `null` when the burst is at the top level. - `owner` (object, required): The member who owns the burst: whoever created it, unless ownership has since been transferred in the app. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. - `templateReportId` (string or null, required): The template report, which every variant was copied from when it was added, by its `id` for `getReport` and the other `/reports/{id}` endpoints. Changes to the template reach existing variants only when pushed from the app; variants added later copy it as it is then. `null` if the template was deleted. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `kind` (string, required): What the variants differ by. `parameters`: report parameters of a Rollstack report, listed in `parameters` and set with `parameters` in `addBurstVariants`. `filters`: filters of an older report's syncs, such as a Google Slides or PowerPoint file, listed in `filters` and set with `filters` in `addBurstVariants`. One of `parameters`, `filters`. - `reportType` (string, required): The type of report the burst copies, as `type` in `listReports`: `SlideDeck` for a Rollstack report, which bursts by `parameters`, any other type for an older report, which bursts by `filters`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `parameters` (array of object, required): The template report's parameters the variants differ by, in the order their values name a variant. Each variant holds its own value of each, which its datasheets' filters read. Empty for a burst by `filters`. - `id` (string, required): The report parameter's id on the template report. Use it as a key of `parameters` in `addBurstVariants`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The template's value of the parameter, which a variant keeps when it doesn't set one. `null` when the template has none. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `filters` (array of object, required): The filters of the template report's syncs that the variants differ by, primary ones first in the order their values name a variant. Each variant holds its own value of each, applied to the syncs that read the filter's dashboard. Empty for a burst by `parameters`. - `id` (string, required): The filter's id. Use it as a key of `filters` in `addBurstVariants`. - `name` (string, required): The filter's name on its dashboard, as shown in Rollstack. - `primary` (boolean, required): Whether the filter names the variants: a variant added without a `name` is named after its primary filters' values, in order. A secondary filter only narrows what each variant shows. - `valueType` (string or null, required): The kind of value the filter takes, and so the `type` of a variant's value of it. `null` when Rollstack doesn't know the filter's editor: copy the shape of a variant's value instead. One of `categorical`, `date`, `number`, `text`. - `variantCount` (number, required): How many variants the burst has, including any you can't open. - `appUrl` (string (uri), required): Link that opens the burst in Rollstack. - `createdAt` (string (date-time), required): When the burst was created. `listBursts` returns the newest first. - `updatedAt` (string (date-time), required): When the burst's details last changed. ### List burst email configurations `GET https://api.rollstack.com/public/v1/bursts/{id}/email-configs` A burst's email configurations, as the app's Burst email settings show them: each one email to its own recipients that includes every variant it selects, sent only when you send it. Unlike each variant's own email, which its runs send to its own recipients. What both sent is in listEmails with burstId. Requires the `slide_decks:read` scope. Operation ID: `listBurstEmailConfigs`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Identifies the configuration. Pass it as `configId` to the other `/email-configs/{configId}` endpoints. - `name` (string or null, required): The configuration's name, as shown in the burst's Emailing tab in the app. - `to` (array of string, required): The addresses the email goes to. - `cc` (array of string, required): The addresses copied on the email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the email without the others seeing them. - `replyTo` (array of string, required): Where replies to the email go. - `variantIds` (array of string, required): The variants the email includes, by their `id` in `listBurstVariants`. Empty includes every variant, also those added later. - `sharingFormat` (string, required): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `zipAttachments` (boolean, required): Whether the variants' files come in one zip file, with a file format. - `emailAnalyticsEnabled` (boolean, required): Whether opens of the email are tracked. - `smtpServerId` (string or null, required): The SMTP connection the email is sent through, from `listSmtpConnections`; `null` sends from Rollstack's own address. - `createdAt` (string (date-time), required): When the configuration was created. - `updatedAt` (string (date-time), required): When the configuration last changed. ### Create burst email configuration `POST https://api.rollstack.com/public/v1/bursts/{id}/email-configs` Adds an email configuration to a burst and answers it: one email to its recipients with the variants it selects, every variant by default. Sends nothing. Only the burst's owner and admins may. Requires the `slide_decks:email` scope. Operation ID: `createBurstEmailConfig`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string or null): The configuration's name, as shown in the burst's Emailing tab in the app. - `to` (array of string): The addresses the email goes to. - `cc` (array of string): The addresses copied on the email, which every recipient can see. - `bcc` (array of string): The addresses that also receive the email without the others seeing them. - `replyTo` (array of string): Where replies to the email go. - `variantIds` (array of string): The variants the email includes, by their `id` in `listBurstVariants`. Empty includes every variant, also those added later. - `sharingFormat` (string): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `zipAttachments` (boolean): Whether the variants' files come in one zip file, with a file format. - `emailAnalyticsEnabled` (boolean): Whether opens of the email are tracked. - `smtpServerId` (string or null): The SMTP connection the email is sent through, from `listSmtpConnections`; `null` sends from Rollstack's own address. #### Response `201` Success `application/json` - `id` (string, required): Identifies the configuration. Pass it as `configId` to the other `/email-configs/{configId}` endpoints. - `name` (string or null, required): The configuration's name, as shown in the burst's Emailing tab in the app. - `to` (array of string, required): The addresses the email goes to. - `cc` (array of string, required): The addresses copied on the email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the email without the others seeing them. - `replyTo` (array of string, required): Where replies to the email go. - `variantIds` (array of string, required): The variants the email includes, by their `id` in `listBurstVariants`. Empty includes every variant, also those added later. - `sharingFormat` (string, required): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `zipAttachments` (boolean, required): Whether the variants' files come in one zip file, with a file format. - `emailAnalyticsEnabled` (boolean, required): Whether opens of the email are tracked. - `smtpServerId` (string or null, required): The SMTP connection the email is sent through, from `listSmtpConnections`; `null` sends from Rollstack's own address. - `createdAt` (string (date-time), required): When the configuration was created. - `updatedAt` (string (date-time), required): When the configuration last changed. ### Get burst run `GET https://api.rollstack.com/public/v1/bursts/{id}/runs` Where the runs of a burst's variants stand, such as those startBurstRun started, with how each variant's latest run ended. Waits up to waitSeconds for none of them to be running and answers as soon as that happens, so call it again while the status is running. A run started in the app or by a schedule counts too. Requires the `slide_decks:read` scope. Operation ID: `getBurstRun`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Query parameters - `waitSeconds` (integer): How long this call waits for the work to finish, in seconds: the message to the slides agent on `getReportMessage`, the run on `getReportRun`, the batch of variants being added on `getBurstVariantBatch`, the runs of a burst's variants on `getBurstRun`. It returns as soon as the work is done, or as things stand once the time is up, so call it again while `status` is still `queued` or `running`. `0` returns at once. Defaults to `20`; at most `30`. Defaults to `20`. #### Response `200` Success `application/json` - `status` (string, required): Where the burst's run stands. `running`: some variants are still running; call `getBurstRun` again to keep waiting. `completed`: none is running, and each variant's `lastRunStatus` says how its latest run ended. One of `running`, `completed`. - `variants` (array of object, required): The burst's variants you can see, oldest first. - `id` (string, required): The variant's report id. - `name` (string, required): The variant's report name. - `runId` (string or null, required): The variant's run in progress, whoever started it. Pass it with the variant's `id` to `getReportRun` or `cancelReportRun`. `null` once the variant isn't running. - `lastRunStatus` (string or null, required): How the variant's latest run that ended went: `completed`, `failed` or `cancelled`, as `lastRunStatus` on the report says. `null` if it has never run. Check `lastSyncedAt` to tell whether that run is the one you started; `listReportRuns` says why a run failed. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `lastSyncedAt` (string (date-time) or null, required): When the variant's latest run ended, whatever its outcome. `null` if it has never run. ### Run burst variants `POST https://api.rollstack.com/public/v1/bursts/{id}/runs` Starts a run of every variant of a burst, or of the variants passed, as startReportRun does for each: it refreshes the variant's data, and repairs a Rollstack report's slides with AI. An older report's variants run together as the app's Update runs them, in batches and behind the organization's other burst runs, so a variant can wait its turn before its run shows. Each such run updates the variant's file when it has one, and emails the variant to its recipients when its email trigger is `all`, as startReportRun does. The template report isn't run; run it with startReportRun. Answers each variant's run at once: follow them all with getBurstRun until none is running, or one with getReportRun, passing the variant's id and runId. A variant already running answers that run and starts nothing. From an AI client, a run that emails variants only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:run` scope. Operation ID: `startBurstRun`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `variantIds` (array of string): The variants to run, by their `id` in `listBurstVariants`, instead of every variant, such as those whose last run failed. Each must be a variant of this burst. 1 to 500 ids. #### Response `202` Success `application/json` - `runs` (array of object, required): The variants running, each as a run of its own report. - `id` (string, required): The variant's report id. - `name` (string, required): The variant's report name. - `runId` (string, required): The variant's run. Follow the burst's runs together with `getBurstRun`, or this one with the variant's `id` on `getReportRun`; cancel it with `cancelReportRun`. - `started` (boolean, required): Whether this request started the run. `false` when a run of the variant was already going, whoever started it; `runId` is then that run's. - `failed` (array of object, required): The variants whose run could not start, such as those you can't run since you only contribute to the burst. The others still started. - `id` (string, required): The variant's report id. - `name` (string, required): The variant's report name. - `code` (string, required): Why its run could not start, as an error code, such as `forbidden`. - `message` (string, required): Why its run could not start, in words. ### Get burst settings `GET https://api.rollstack.com/public/v1/bursts/{id}/settings` A burst's settings, as its Settings tab in the app shows them: how its variants are named, and for an older report's burst, how each variant's run updates its file, what it does with empty charts, how it archives and how its filters match. Its folders and schedules are set in the app. Requires the `slide_decks:read` scope. Operation ID: `getBurstSettings`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Response `200` Success `application/json` - `kind` (string, required): What the burst's variants differ by, as `kind` in `listBursts`. One of `parameters`, `filters`. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `updateMethod` (string, required): How each variant's run changes its file. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original. `updateVisualizations` is the method email reports are created with. It applies to new variants and to the existing ones. For an older report's burst only: a Rollstack report's burst returns 400. One of `update`, `archive`, `updateVisualizations`. - `variantEmptyVisualizations` (string, required): What a variant's run does with a chart or table that has no data for its values. `show` places it empty, `hideNoCascade` leaves it out of the file, `hideCascade` hides its slide when every visualization on the slide is empty, and `hideCascadeIfAtLeastOneVisualizationIsEmpty` hides its slide when any of them is. For an older report's burst only: a Rollstack report's burst returns 400. One of `show`, `hideNoCascade`, `hideCascade`, `hideCascadeIfAtLeastOneVisualizationIsEmpty`. - `archiveVariantsInFolder` (boolean, required): With `updateMethod` `archive`: whether each variant's archived copies go in an archive folder next to its file, rather than beside it. For an older report's burst only: a Rollstack report's burst returns 400. - `datestampSuffix` (string, required): With `updateMethod` `archive`: the date format added to the name of each archived copy. For an older report's burst only: a Rollstack report's burst returns 400. - `caseInsensitiveFilters` (boolean, required): Whether a variant's filter values match the dashboard's values whatever their case. It applies when filters are next applied, such as with `reapplyBurstFilters`. For an older report's burst only: a Rollstack report's burst returns 400. ### Update burst settings `PATCH https://api.rollstack.com/public/v1/bursts/{id}/settings` Changes the settings passed and answers them all. A Rollstack report's burst takes only variantNaming. An older report's run settings, such as updateMethod, also apply to its existing variants. Only the burst's owner and admins may. Requires the `slide_decks:write` scope. Operation ID: `updateBurstSettings`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `variantNaming` (string): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `updateMethod` (string): How each variant's run changes its file. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original. `updateVisualizations` is the method email reports are created with. It applies to new variants and to the existing ones. For an older report's burst only: a Rollstack report's burst returns 400. One of `update`, `archive`, `updateVisualizations`. - `variantEmptyVisualizations` (string): What a variant's run does with a chart or table that has no data for its values. `show` places it empty, `hideNoCascade` leaves it out of the file, `hideCascade` hides its slide when every visualization on the slide is empty, and `hideCascadeIfAtLeastOneVisualizationIsEmpty` hides its slide when any of them is. For an older report's burst only: a Rollstack report's burst returns 400. One of `show`, `hideNoCascade`, `hideCascade`, `hideCascadeIfAtLeastOneVisualizationIsEmpty`. - `archiveVariantsInFolder` (boolean): With `updateMethod` `archive`: whether each variant's archived copies go in an archive folder next to its file, rather than beside it. For an older report's burst only: a Rollstack report's burst returns 400. - `datestampSuffix` (string): With `updateMethod` `archive`: the date format added to the name of each archived copy. For an older report's burst only: a Rollstack report's burst returns 400. - `caseInsensitiveFilters` (boolean): Whether a variant's filter values match the dashboard's values whatever their case. It applies when filters are next applied, such as with `reapplyBurstFilters`. For an older report's burst only: a Rollstack report's burst returns 400. #### Response `200` Success `application/json` - `kind` (string, required): What the burst's variants differ by, as `kind` in `listBursts`. One of `parameters`, `filters`. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `updateMethod` (string, required): How each variant's run changes its file. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original. `updateVisualizations` is the method email reports are created with. It applies to new variants and to the existing ones. For an older report's burst only: a Rollstack report's burst returns 400. One of `update`, `archive`, `updateVisualizations`. - `variantEmptyVisualizations` (string, required): What a variant's run does with a chart or table that has no data for its values. `show` places it empty, `hideNoCascade` leaves it out of the file, `hideCascade` hides its slide when every visualization on the slide is empty, and `hideCascadeIfAtLeastOneVisualizationIsEmpty` hides its slide when any of them is. For an older report's burst only: a Rollstack report's burst returns 400. One of `show`, `hideNoCascade`, `hideCascade`, `hideCascadeIfAtLeastOneVisualizationIsEmpty`. - `archiveVariantsInFolder` (boolean, required): With `updateMethod` `archive`: whether each variant's archived copies go in an archive folder next to its file, rather than beside it. For an older report's burst only: a Rollstack report's burst returns 400. - `datestampSuffix` (string, required): With `updateMethod` `archive`: the date format added to the name of each archived copy. For an older report's burst only: a Rollstack report's burst returns 400. - `caseInsensitiveFilters` (boolean, required): Whether a variant's filter values match the dashboard's values whatever their case. It applies when filters are next applied, such as with `reapplyBurstFilters`. For an older report's burst only: a Rollstack report's burst returns 400. ### List burst variants `GET https://api.rollstack.com/public/v1/bursts/{id}/variants` A burst's variants the user can open, oldest first, each with its values of the burst's parameters or filters, how its latest run went, whether one is going, and who its email goes to. adding lists the variants the user is still adding. Answers up to limit variants, 50 by default and 200 at most, and a nextCursor: pass it as cursor for the next page, until it is null. Requires the `slide_decks:read` scope. Operation ID: `listBurstVariants`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Query parameters - `limit` (integer): Maximum number of variants to return on this page, from 1 to 200. Defaults to `50`. - `cursor` (string): Where to continue the list: pass the `nextCursor` returned with the previous page to get the next one. Omit it for the first page. Example: `6c1f9a2e-3b4d-4e8f-9a1b-2c3d4e5f6a7b`. #### Response `200` Success `application/json` - `data` (array of object, required): The variants on this page that you can open, oldest first. Each variant is a report of the burst's `reportType`: pass its `id` to `getReport`, `startReportRun` and the other `/reports/{id}` endpoints its type takes. `running` and `lastRunStatus` tell where its runs stand. - `id` (string, required): Unique identifier for the report. Pass it as `id` to the other `/reports/{id}` endpoints. - `type` (string, required): The kind of report, which decides the endpoints that work on it. - `SlideDeck`: a slide deck built in Rollstack. Every `/reports/{id}` endpoint works on it, except `listReportSyncs` and `convertReport`. - `GoogleSlides`, `GoogleDocs`, `MicrosoftPowerPoint`, `MicrosoftWord`: a file in Google Drive or OneDrive that Rollstack updates with its visualizations. - `UploadedPPTXFile`: a PowerPoint file uploaded to Rollstack, which it updates the same way. - `Email`: an email report, whose visualizations Rollstack sends in an email. On a report that isn't a `SlideDeck`, only `getReport`, `updateReport`, `deleteReport`, `shareReport`, `unshareReport`, `getReportSchedules`, `updateReportSchedules`, `startReportRun`, `listReportRuns`, `getReportRun`, `cancelReportRun`, `listReportSyncs` and the email endpoints (`getReportEmailConfig`, `updateReportEmailConfig`, `listReportEmails`, `sendReportEmail`, `sendReportTestEmail`) work, and `convertReport` on a `GoogleSlides` or `MicrosoftPowerPoint` report. The other `/reports/{id}` endpoints take `SlideDeck` reports only, as their `id` says, and return `400`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `name` (string, required): Name of the report, as members see it in Rollstack. Change it with `updateReport`. - `folderId` (string or null, required): The folder the report is in, by its `id` in `listFolders`. `null` when the report is at the top level, outside any folder. - `owner` (object, required): The member who owns the report: whoever created it, unless ownership has since been transferred, in the app or with `transferReportOwnership`. Only the owner can delete the report. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. Rollstack emails this address when a scheduled run of the report fails, while `notifyOnFailure` is `true`. - `permission` (string or null, required): Your access to the report, as the user the API key belongs to. `view` lets you open and export it, and see its datasheets, runs, schedules and email setup. `comment` also lets you add, reply to and resolve comments on its slides. `edit` also lets you change it: rename or move it, chat with the slides agent about it, add datasheets and read their data, start runs, set its schedules and email, send its email, and share it. It's never `null` here, since the API only returns reports you can at least view. One of `view`, `comment`, `edit`. - `timezone` (string or null, required): The report's timezone, such as `America/New_York`. The slides agent uses it to tell today's date, and the report's emails show the time of its last successful update (`{{last_updated_at}}`) in it. On a report that updates a file, such as a Google Slides presentation, it's also the timezone of the file's date variables, unless the organization's `timezone` replaces it. Schedules don't use it: each has its own `timezone`. `null` when the report has none, in which case the slides agent uses UTC. Reports created with `createReport` start with the organization's `timezone` from `getOrganization`, if it has one. - `notifyOnFailure` (boolean, required): Whether Rollstack emails the report's owner when a scheduled run fails or some of its datasheets, or a file's visualizations, fail to refresh, copying everyone in `notificationMailingList`. Runs started in the app or with `startReportRun` never send this email. New reports start with `true`. - `lastSyncedAt` (string (date-time) or null, required): When the report's latest run ended, whatever its outcome. `null` if the report has never run. - `lastSuccessfulUpdateAt` (string (date-time) or null, required): When the report's latest fully successful run ended: one that refreshed every datasheet it ran on, or every visualization on a report that updates a file, with none failing. Runs with nothing to refresh don't count. The report's emails show this time as `{{last_updated_at}}`. `null` until the report has had such a run. - `lastRunStatus` (string or null, required): How the report's latest run ended. `completed`: it finished, even if some datasheets or visualizations failed to refresh or it had none to refresh; on a `SlideDeck` report, `listReportDatasheets` shows each datasheet's `error`. `failed`: it stopped on an error, or none of its datasheets or visualizations could be refreshed. `cancelled`: it was stopped before it finished, for example with `cancelReportRun`. `null` if the report has never run. `running` and `timed_out` never appear here: check `running` to see whether a run is in progress. One of `running`, `completed`, `failed`, `cancelled`, `timed_out`. - `running` (boolean, required): Whether a run of the report is in progress, whoever started it, such as you with `startReportRun`, a member in the app, or one of its schedules. While it's `true`, `startReportRun` returns that run instead of starting another. - `appUrl` (string (uri), required): Link that opens the report in Rollstack. - `fileUrl` (string or null, required): Link that opens the Google Slides, Google Docs, PowerPoint or Word file the report updates. `null` for a slide deck, an email report or an uploaded PowerPoint file, which have no file to open, and for a Microsoft file whose link Rollstack has not read yet. - `createdAt` (string (date-time), required): When the report was created. `listReports` returns the newest first. - `updatedAt` (string (date-time), required): When the report's details last changed, such as its name, folder or owner, or the outcome of its latest run. - `parameters` (array of object, required): The variant's value of each parameter the burst varies by, in the burst's order. Empty for a burst by `filters`. - `id` (string, required): The report parameter's id on the template report. Use it as a key of `parameters` in `addBurstVariants`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The value the variant holds: the one it was added with, or the template's when it set none. `null` when neither had one. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `filters` (array of object, required): The variant's value of each filter the burst varies by, in the burst's order. Empty for a burst by `parameters`. - `id` (string, required): The filter's id. Use it as a key of `filters` in `addBurstVariants`. - `name` (string, required): The filter's name on its dashboard, as shown in Rollstack. - `value` (object or null, required): The value the variant applies to the filter, as it was added with. `null` when it sets none, and the filter keeps its value on the dashboard. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `recipients` (object, required): Who the variant's email goes to, all empty until its own email is set up, as on a variant whose burst emails only through the configurations `listBurstEmailConfigs` lists. Set them with `updateBurstVariantRecipients`. - `to` (array of string, required): The addresses the report's email is sent to. When empty, no one receives it: the report's runs send no email and `sendReportEmail` returns 400. - `cc` (array of string, required): The addresses copied on the report's email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the report's email without the other recipients seeing them. - `nextCursor` (string or null, required): Pass it as `cursor` to get the next page of variants. `null` when there are no more. - `adding` (array of object, required): The variants you are adding with `addBurstVariants` or in the app, while that is still going. Empty once every one is done. To wait for variants you added, follow the `batchId` from `addBurstVariants` with `getBurstVariantBatch` rather than listing again. - `name` (string, required): The name the variant is added with, as `addBurstVariants` returned it. - `status` (string, required): Where adding it stands. `queued`: it waits for the variants before it. `running`: its report is being copied from the template and run for the first time. `completed`: it is among the burst's variants in `listBurstVariants`, though its first run may have only partly completed, as its `lastRunStatus` says. `failed`: either it could not be added, or its report was added but its first run failed. Look for it in `listBurstVariants` to tell which. `cancelled`: it was cancelled in the app, before it was added or during its first run. Its report may still be among the burst's variants. One of `queued`, `running`, `completed`, `failed`, `cancelled`. - `error` (string or null, required): Why the variant failed, when that is known, while `status` is `failed`. `null` otherwise, including when its report was added and only its first run failed. ### Add burst variants `POST https://api.rollstack.com/public/v1/bursts/{id}/variants` Adds variants to a burst by their values of its report parameters, or of its filters for an older report's burst: each is a copy of the template report with its own values, then runs once to fetch its data. An older report's variant is a copy of its file in the burst's folder. Report parameter values and filter ids are checked first, so a request with one the burst can't take adds nothing. Answers at once with the batch's batchId and the names the variants are added with: follow the batch with getBurstVariantBatch until it ends. Requires the `slide_decks:write` scope. Operation ID: `addBurstVariants`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `variants` (array of object, required): The variants to add, 1 to 500. Variants may hold the same values as one another or as an existing variant: each is added as its own report. - `name` (string): The variant's name, which its report's name is built from as the burst's `variantNaming` says. If omitted, it is named after the values it sets, like `EMEA - Q1 2026`: its parameters' values, or its primary filters' values. - `parameters` (object): For a burst by `parameters`: the value the variant sets of each report parameter, by its `id` in the burst's `parameters`. A parameter left out keeps the template's value. A value must be one the template's datasheet filters can take, or the request returns 400 and adds nothing. Example: `{"5e7a9c1b-3d5f-4b7d-9e1a-3c5e7a9b1d3f":{"type":"categorical","values":["EMEA"]}}`. - `filters` (object): For a burst by `filters`: the value the variant applies to each filter, by its `id` in the burst's `filters`, at least one. A filter left out keeps its value on the dashboard. An id that isn't one of the burst's filters returns 400 and adds nothing. Example: `{"3b1f8c2e-6a4d-4f1e-9b2a-7c5d8e1f2a3b":{"type":"categorical","values":["EMEA"]}}`. #### Response `202` Success `application/json` - `batchId` (string, required): Identifies the batch of variants being added. Pass it to `getBurstVariantBatch`, which waits for them to be added. Variants you add while another of your batches on the burst is going join it, under the same id. - `variants` (array of object, required): The variants being added, in the order sent. - `name` (string, required): The name the variant is added with. ### Get burst variant batch `GET https://api.rollstack.com/public/v1/bursts/{id}/variants/batches/{batchId}` A batch of variants being added to a burst, with where each variant stands: copied from the template report, then run once to fetch its data. Waits up to waitSeconds for the batch to end and answers as soon as it does, so call it again while the status is running. Your later batch on the burst reuses the id, so this describes the latest one. Requires the `slide_decks:read` scope. Operation ID: `getBurstVariantBatch`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. - `batchId` (string, required): The batch, by the `batchId` that `addBurstVariants` returned. A member's batches on a burst share one id, so it always refers to their latest. #### Query parameters - `waitSeconds` (integer): How long this call waits for the work to finish, in seconds: the message to the slides agent on `getReportMessage`, the run on `getReportRun`, the batch of variants being added on `getBurstVariantBatch`, the runs of a burst's variants on `getBurstRun`. It returns as soon as the work is done, or as things stand once the time is up, so call it again while `status` is still `queued` or `running`. `0` returns at once. Defaults to `20`; at most `30`. Defaults to `20`. #### Response `200` Success `application/json` - `batchId` (string, required): Identifies the batch, as returned by `addBurstVariants`. - `status` (string, required): Where the batch stands. It stays `running` until every variant in it is added and has run once, then says how it ended. - `running`: variants are still being added. Call `getBurstVariantBatch` again to keep waiting. - `completed`: the batch finished. Each of `variants` says how it went; find the added ones among the burst's variants in `listBurstVariants`. - `failed`: every variant failed, or the batch stopped on an error. A variant fails both when it can't be added and when it is added but its first run fails, so some may still be among the burst's variants in `listBurstVariants`. - `cancelled`: the batch was stopped in the app before it finished. One of `running`, `completed`, `failed`, `cancelled`. - `startedAt` (string (date-time), required): When the batch started. - `finishedAt` (string (date-time) or null, required): When the batch ended, whatever its outcome. `null` while it is `running`. - `variants` (array of object, required): The variants in the batch, in the order they were sent, each with where adding it stands. - `name` (string, required): The name the variant is added with, as `addBurstVariants` returned it. - `status` (string, required): Where adding it stands. `queued`: it waits for the variants before it. `running`: its report is being copied from the template and run for the first time. `completed`: it is among the burst's variants in `listBurstVariants`, though its first run may have only partly completed, as its `lastRunStatus` says. `failed`: either it could not be added, or its report was added but its first run failed. Look for it in `listBurstVariants` to tell which. `cancelled`: it was cancelled in the app, before it was added or during its first run. Its report may still be among the burst's variants. One of `queued`, `running`, `completed`, `failed`, `cancelled`. - `error` (string or null, required): Why the variant failed, when that is known, while `status` is `failed`. `null` otherwise, including when its report was added and only its first run failed. ### List sync filters `GET https://api.rollstack.com/public/v1/reports/{id}/syncs/{syncId}/filters` The filters of the dashboard an older report's sync reads, which a burst of the report can vary by: pass their ids in filters to createBurst. Read from the dashboard with your access to its connection, so it can take a few seconds. Find the report's syncs with listReportSyncs. A Rollstack report bursts by report parameters instead: see getReportParameters. Requires the `slide_decks:read` scope. Operation ID: `listReportSyncFilters`. #### Path parameters - `id` (string, required): The report to act on, of any `type`, by its `id` from `listReports` or `createReport`. You can also copy it from the report's link in Rollstack (`appUrl`): it's the part right after `/slides/` or `/destinations/`. - `syncId` (string, required): The sync whose dashboard filters to list, by its `id` from `listReportSyncs`. #### Response `200` Success `application/json` - `filters` (array of object, required): The filters of the sync's dashboard a burst can vary by, by name. - `id` (string, required): The filter's id. Pass it in `filters` to `createBurst` to make a burst whose variants differ by it. - `name` (string, required): The filter's name on the sync's dashboard. - `valueType` (string or null, required): The kind of value Rollstack can set in the filter: the `type` of each variant's value of it. `null` when Rollstack doesn't know the filter's editor. One of `categorical`, `date`, `number`, `text`. - `unsupported` (array of object, required): The dashboard's filters Rollstack can't set, so a burst can't vary by them. - `name` (string, required): The filter's name on the dashboard. ### Send burst email configuration `POST https://api.rollstack.com/public/v1/bursts/{id}/email-configs/{configId}/send` Sends a burst's email configuration now: one email to its recipients with each variant it selects. Building it outlasts the request, so it goes out after the answer. Send a test with sendBurstEmailConfigTest first to check how it looks. Only the burst's owner and admins may. Sends have a low rate limit. From an AI client, the send only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:email` scope. Operation ID: `sendBurstEmailConfig`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. - `configId` (string, required): The email configuration, by its `id` from `listBurstEmailConfigs`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `202` Success `application/json` - `id` (string, required): The email configuration. - `name` (string or null, required): The email configuration's name. ### Send variant emails `POST https://api.rollstack.com/public/v1/bursts/{id}/variants/emails` Sends each variant's own email now, to its own recipients, as the app's Send does: every variant, or those passed. The template sends nothing. Every recipient gets an email. Only the burst's owner and admins may. Sends have a low rate limit. From an AI client, the send only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:email` scope. Operation ID: `sendBurstVariantEmails`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `variantIds` (array of string): The variants to act on, by their `id` in `listBurstVariants`, instead of every variant. Each must be a variant of this burst. 1 to 500 ids. #### Response `202` Success `application/json` - `sending` (array of object, required): The variants whose email is going out now, each to its own recipients. See each one's sends with `listReportEmails`. - `id` (string, required): The report's id. - `name` (string, required): The report's name. - `skipped` (array of object, required): The variants left out since their email has no one in `to`. Set them with `updateBurstVariantRecipients`. - `id` (string, required): The report's id. - `name` (string, required): The report's name. ### Rename burst `PATCH https://api.rollstack.com/public/v1/bursts/{id}` Renames a burst and answers it, and with renameVariants its reports too. Only the burst's owner and admins may. Requires the `slide_decks:write` scope. Operation ID: `renameBurst`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): The burst's new name. - `renameVariants` (boolean): Whether to rename every report in the burst after the new name too, as `variantNaming` builds each name, the template included. A Rollstack report's burst renames the template, which is the report the burst was made from. Defaults to `false`. - `renameFiles` (boolean): For a burst of Google Slides, Google Docs, PowerPoint or Word reports: whether to also rename the burst's folders, and with `renameVariants` each report's file, in Google Drive or OneDrive. It goes on after the answer. Defaults to `false`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the burst. Pass it as `id` to the other `/bursts/{id}` endpoints. - `name` (string, required): Name of the burst, as members see it in Rollstack. It is the template report's name when the burst is created, and is part of each variant report's name unless `variantNaming` is `sameName`. - `folderId` (string or null, required): The folder the burst is in, by its `id` in `listFolders`. `null` when the burst is at the top level. - `owner` (object, required): The member who owns the burst: whoever created it, unless ownership has since been transferred in the app. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. - `templateReportId` (string or null, required): The template report, which every variant was copied from when it was added, by its `id` for `getReport` and the other `/reports/{id}` endpoints. Changes to the template reach existing variants only when pushed from the app; variants added later copy it as it is then. `null` if the template was deleted. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `kind` (string, required): What the variants differ by. `parameters`: report parameters of a Rollstack report, listed in `parameters` and set with `parameters` in `addBurstVariants`. `filters`: filters of an older report's syncs, such as a Google Slides or PowerPoint file, listed in `filters` and set with `filters` in `addBurstVariants`. One of `parameters`, `filters`. - `reportType` (string, required): The type of report the burst copies, as `type` in `listReports`: `SlideDeck` for a Rollstack report, which bursts by `parameters`, any other type for an older report, which bursts by `filters`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `parameters` (array of object, required): The template report's parameters the variants differ by, in the order their values name a variant. Each variant holds its own value of each, which its datasheets' filters read. Empty for a burst by `filters`. - `id` (string, required): The report parameter's id on the template report. Use it as a key of `parameters` in `addBurstVariants`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The template's value of the parameter, which a variant keeps when it doesn't set one. `null` when the template has none. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `filters` (array of object, required): The filters of the template report's syncs that the variants differ by, primary ones first in the order their values name a variant. Each variant holds its own value of each, applied to the syncs that read the filter's dashboard. Empty for a burst by `parameters`. - `id` (string, required): The filter's id. Use it as a key of `filters` in `addBurstVariants`. - `name` (string, required): The filter's name on its dashboard, as shown in Rollstack. - `primary` (boolean, required): Whether the filter names the variants: a variant added without a `name` is named after its primary filters' values, in order. A secondary filter only narrows what each variant shows. - `valueType` (string or null, required): The kind of value the filter takes, and so the `type` of a variant's value of it. `null` when Rollstack doesn't know the filter's editor: copy the shape of a variant's value instead. One of `categorical`, `date`, `number`, `text`. - `variantCount` (number, required): How many variants the burst has, including any you can't open. - `appUrl` (string (uri), required): Link that opens the burst in Rollstack. - `createdAt` (string (date-time), required): When the burst was created. `listBursts` returns the newest first. - `updatedAt` (string (date-time), required): When the burst's details last changed. ### Delete burst `DELETE https://api.rollstack.com/public/v1/bursts/{id}` Deletes a burst with every report in it, the template included, as the app does, and can't be undone. A Rollstack report's burst uses the report it was made from as its template, so that report is deleted too. Files in Google Drive or OneDrive stay. Only the burst's owner may. From an AI client, the deletion only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:write` scope. Operation ID: `deleteBurst`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `id` (string, required): The deleted burst. - `name` (string, required): The deleted burst's name. ### Set variant email settings `PATCH https://api.rollstack.com/public/v1/bursts/{id}/variants/email-settings` Changes how the variants' own emails are sent, as the app's Burst settings in its Emailing tab do: only the settings passed, on the template, whose settings new variants copy, and on the variants. Each keeps its recipients: set them with updateBurstVariantRecipients. Sends no email. Members who only contribute change their own variants. See a report's settings with getReportEmailConfig. Requires the `slide_decks:email` scope. Operation ID: `updateBurstVariantEmailSettings`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `variantIds` (array of string): The reports to change, by their `id`: variants from `listBurstVariants`, and the burst's `templateReportId`, whose settings new variants copy. If omitted, the template and every variant you can edit. - `smtpServerId` (string or null): The SMTP connection to send the emails through, from `listSmtpConnections`; `null` sends from Rollstack's own address. If omitted, each report keeps its own sender. - `sharingFormat` (string): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. If omitted, stays as it is. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. If omitted, stays as it is. - `trigger` (string): Which of the report's runs email it automatically. A run emails it when it updates everything, or when all its failures are in `ignoredFailureStatusMessages`. On a slide deck, `all` and `scheduled` work the same way: only runs started by its schedules (see `getReportSchedules`) send the email, and a slide deck with no datasheets is never emailed by its runs. On an older report, `all` emails after every run of the whole report, whether started by a schedule, with `startReportRun` or in the app, and `scheduled` only after runs its schedules start; a run of only some syncs never emails it. With `none` (Manual in the app), no run sends it: the email goes out only when sent with `sendReportEmail` or from the app. If omitted, stays as it is. One of `all`, `none`, `scheduled`. - `groupRecipients` (boolean): Whether each variant sends one email to all its `to` addresses together, rather than one email per address. If omitted, stays as it is. - `ignoredFailureStatusMessages` (array of string): The failures that shouldn't stop a run from emailing a variant (see `trigger`), such as the `error.code` values from `listReportSyncs`. If omitted, stays as it is. The other values describe why a sync of an older report failed, and have an effect only on older reports: - `dashboard_not_found`, or the older `tableau_view_not_found`: the dashboard, Tableau workbook, Power BI report or spreadsheet could not be found. - `dashboard_tab_not_found`: the dashboard tab, Tableau view, Power BI report page or spreadsheet sheet could not be found. - `dashboard_not_ready`: the dashboard took too long to load. - `dashboard_has_errors`: the dashboard or spreadsheet failed to load because of an error in the tool it comes from. - `dashboard_invalid_layout`: the dashboard's layout is invalid, and it needs to be saved again. - `element_not_found`, or the older `metabase_element_not_found` and `looker_element_not_found`: the visualization could not be found. - `slide_not_found`, or the older `google_slide_not_found`: the slide that shows the visualization could not be found. - `file_not_found`: the spreadsheet file the visualization comes from could not be found. - `sheet_not_found`: the spreadsheet sheet could not be found. - `sheet_hidden`: the spreadsheet sheet is hidden and needs to be unhidden. - `range_not_found`: the spreadsheet range could not be found. - `duplicate_file_failed`: Rollstack could not prepare the spreadsheet file for the update. - `merged_range_on_filter_range`: the visualization has merged cells, which filters can't be applied to. - `insufficient_permissions`: the owner doesn't have edit access to the file. - `image_cropping_failed`: Rollstack could not crop the visualization's image. - `visualization_not_found`: the visualization could not be found in the dashboard. - `visualization_not_ready`: the visualization took too long to load. - `visualization_has_errors`: the visualization failed to load because of an error in the tool it comes from. - `visualization_empty`, or the older `empty_data`: the visualization is empty. - `invalid_credentials`: the connection's credentials are invalid. - `missing_credentials`: the connection's credentials were deleted, or the owner's access to it was suspended. - `instance_unavailable`: the data source's instance is temporarily unavailable. - `column_not_found`: a column the native chart uses is missing from its data. - `fetch_summary_data_error`, `fetch_visual_specification_error`, `missing_data`, `missing_formatted_value` and `viz_not_ready`: Rollstack could not fetch the data of a native chart. - `incorrect_data_structure`: the native chart's structure doesn't fit its data. - `malformed_data`: Rollstack could not fetch the data of a native chart or, from Snowflake or Databricks, the query is invalid. - `worksheet_not_found`: the Tableau worksheet could not be found. - `sync_not_found`: the visualization was deleted. - `file_update_failed`: the data was fetched but could not be written into the file. - `emailAnalyticsEnabled` (boolean): Whether to track when recipients open the emails. `true` returns 403 unless email analytics is on for the organization. If omitted, stays as it is. #### Response `200` Success `application/json` - `updated` (array of object, required): The reports whose email settings changed. Their recipients stay as they were. - `id` (string, required): The report's id. - `name` (string, required): The report's name. ### Update burst email configuration `PATCH https://api.rollstack.com/public/v1/bursts/{id}/email-configs/{configId}` Changes the fields passed of a burst's email configuration and answers it. Sends nothing. Only the burst's owner and admins may. Requires the `slide_decks:email` scope. Operation ID: `updateBurstEmailConfig`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. - `configId` (string, required): The email configuration, by its `id` from `listBurstEmailConfigs`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string or null): The configuration's name, as shown in the burst's Emailing tab in the app. - `to` (array of string): The addresses the email goes to. - `cc` (array of string): The addresses copied on the email, which every recipient can see. - `bcc` (array of string): The addresses that also receive the email without the others seeing them. - `replyTo` (array of string): Where replies to the email go. - `variantIds` (array of string): The variants the email includes, by their `id` in `listBurstVariants`. Empty includes every variant, also those added later. - `sharingFormat` (string): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `zipAttachments` (boolean): Whether the variants' files come in one zip file, with a file format. - `emailAnalyticsEnabled` (boolean): Whether opens of the email are tracked. - `smtpServerId` (string or null): The SMTP connection the email is sent through, from `listSmtpConnections`; `null` sends from Rollstack's own address. #### Response `200` Success `application/json` - `id` (string, required): Identifies the configuration. Pass it as `configId` to the other `/email-configs/{configId}` endpoints. - `name` (string or null, required): The configuration's name, as shown in the burst's Emailing tab in the app. - `to` (array of string, required): The addresses the email goes to. - `cc` (array of string, required): The addresses copied on the email, which every recipient can see. - `bcc` (array of string, required): The addresses that also receive the email without the others seeing them. - `replyTo` (array of string, required): Where replies to the email go. - `variantIds` (array of string, required): The variants the email includes, by their `id` in `listBurstVariants`. Empty includes every variant, also those added later. - `sharingFormat` (string, required): How the email delivers the report. `pdf` and `ppt` send it as a PDF or PowerPoint file, attached or behind a download button (see `sendAttachmentAsLink`); a slide deck leaves its hidden slides out. `link` sends a link to the Google Drive or OneDrive file an older report updates, shared with the recipients as set in the app; an email report sends its content in the email itself, and a slide deck has no such file, so one whose settings still contain `link` is emailed as a PDF behind a download button. `cloudLink` (Exported link in the app), for slide decks only, sends a link to the copy exported to Google Drive or OneDrive and shares it with the addresses in `to`, `cc` and `bcc` with the sharing permission set in the app, viewer unless changed there; if no permission is set, as after PDF or PPT was picked in the app, the copy isn't shared with them. One of `link`, `pdf`, `ppt`, `cloudLink`. - `sendAttachmentAsLink` (boolean, required): Whether the email puts the `pdf` or `ppt` file behind a Download PDF or Download PPT button instead of attaching it. When `false`, the file is attached. Has no effect with `cloudLink`. - `zipAttachments` (boolean, required): Whether the variants' files come in one zip file, with a file format. - `emailAnalyticsEnabled` (boolean, required): Whether opens of the email are tracked. - `smtpServerId` (string or null, required): The SMTP connection the email is sent through, from `listSmtpConnections`; `null` sends from Rollstack's own address. - `createdAt` (string (date-time), required): When the configuration was created. - `updatedAt` (string (date-time), required): When the configuration last changed. ### Delete burst email configuration `DELETE https://api.rollstack.com/public/v1/bursts/{id}/email-configs/{configId}` Deletes a burst's email configuration. Its past sends stay. Only the burst's owner and admins may. Requires the `slide_decks:email` scope. Operation ID: `deleteBurstEmailConfig`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. - `configId` (string, required): The email configuration, by its `id` from `listBurstEmailConfigs`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `id` (string, required): The email configuration. - `name` (string or null, required): The email configuration's name. ### Set variant recipients `PUT https://api.rollstack.com/public/v1/bursts/{id}/variants/recipients` Sets who each variant's email goes to, replacing its to, cc and bcc. Its other email settings, such as its sender and which runs send it, stay as copied from the template; a variant without email settings gets the defaults. Sends no email. As in the app, the burst's owner and admins can set any variant's recipients, other members only those of variants they own or can edit; the others are skipped, as is a variant with several recipient groups, which the app asks to reconcile first. Requires the `slide_decks:email` scope. Operation ID: `updateBurstVariantRecipients`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `variants` (array of object, required): The variants whose recipients to replace, 1 to 500. The other variants, and the rest of each variant's email settings, stay as they are. - `id` (string, required): The variant, by its `id` in `listBurstVariants`. - `to` (array of string, required): The addresses to send the variant's email to. If empty, no one receives it. At most 100 addresses across `to`, `cc` and `bcc`. - `cc` (array of string): The addresses to copy on the variant's email, which every recipient can see. If omitted, no one is copied. Defaults to `[]`. - `bcc` (array of string): The addresses to also send the variant's email to without the other recipients seeing them. If omitted, no one is blind-copied. Defaults to `[]`. #### Response `200` Success `application/json` - `updated` (array of string, required): The variants whose recipients were replaced, by their `id`. - `skipped` (array of string, required): The variants passed that were left as they were, by their `id`: those you can't edit, since you only contribute to the burst, and ids that aren't variants of it. ### Update burst filters `PUT https://api.rollstack.com/public/v1/bursts/{id}/filters` Replaces the filters an older report's burst varies by, then writes every variant's values into its syncs again, which can take a minute, and answers the burst. A filter left out is removed with every variant's value of it, unless replace carries those values to its new filter: confirm with the user first. Variants keep their files and names. Only the burst's owner and admins may. A Rollstack report's burst varies by report parameters and returns 400. Requires the `slide_decks:write` scope. Operation ID: `updateBurstFilters`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `primaryIds` (array of string, required): The filters that name the variants, by their `id` in the burst's `filters` or from `listReportSyncFilters`, in the order their values name a variant. 1 to 3. - `secondaryIds` (array of string): Filters a variant can also set, which don't name it. Defaults to `[]`. - `replace` (array of object): Carries every variant's value of a filter you're replacing to its new filter, such as one moved to another dashboard. Without it, a filter left out is removed together with every variant's value of it, which can't be undone. Defaults to `[]`. - `fromId` (string, required): A filter the burst varies by now, by its `id` in its `filters`. - `toId` (string, required): The new filter, among `primaryIds` or `secondaryIds`, that takes its values. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the burst. Pass it as `id` to the other `/bursts/{id}` endpoints. - `name` (string, required): Name of the burst, as members see it in Rollstack. It is the template report's name when the burst is created, and is part of each variant report's name unless `variantNaming` is `sameName`. - `folderId` (string or null, required): The folder the burst is in, by its `id` in `listFolders`. `null` when the burst is at the top level. - `owner` (object, required): The member who owns the burst: whoever created it, unless ownership has since been transferred in the app. - `id` (number, required): The owner's user id, the same as their `id` in `listMembers`. - `name` (string, required): The owner's name, as shown in Rollstack. - `email` (string, required): The owner's email address. - `templateReportId` (string or null, required): The template report, which every variant was copied from when it was added, by its `id` for `getReport` and the other `/reports/{id}` endpoints. Changes to the template reach existing variants only when pushed from the app; variants added later copy it as it is then. `null` if the template was deleted. - `variantNaming` (string, required): How each variant's report is named from the burst's name and the name the variant is added with, `EMEA` in a burst named `Regional Review`: `suffix` gives `Regional Review - EMEA`, `prefix` gives `EMEA - Regional Review`, and `sameName` gives `EMEA`. It applies to variants added from then on. One of `sameName`, `prefix`, `suffix`. - `kind` (string, required): What the variants differ by. `parameters`: report parameters of a Rollstack report, listed in `parameters` and set with `parameters` in `addBurstVariants`. `filters`: filters of an older report's syncs, such as a Google Slides or PowerPoint file, listed in `filters` and set with `filters` in `addBurstVariants`. One of `parameters`, `filters`. - `reportType` (string, required): The type of report the burst copies, as `type` in `listReports`: `SlideDeck` for a Rollstack report, which bursts by `parameters`, any other type for an older report, which bursts by `filters`. One of `GoogleDocs`, `GoogleSlides`, `MicrosoftPowerPoint`, `MicrosoftWord`, `Email`, `UploadedPPTXFile`, `SlideDeck`. - `parameters` (array of object, required): The template report's parameters the variants differ by, in the order their values name a variant. Each variant holds its own value of each, which its datasheets' filters read. Empty for a burst by `filters`. - `id` (string, required): The report parameter's id on the template report. Use it as a key of `parameters` in `addBurstVariants`. - `name` (string, required): The report parameter's name, as shown in Rollstack. - `value` (object or null, required): The template's value of the parameter, which a variant keeps when it doesn't set one. `null` when the template has none. A value of a report parameter, in the shape of its type. Copy the shape of the parameter's `value` in `listBursts`, or of a variant's in `listBurstVariants`: - A list of values: `{ "type": "categorical", "values": ["EMEA"] }`, with at least one value. `operator` can also be `is_not`, `contains` or `doesnt_contain`; it is `is` when left out. - A number: `{ "type": "number", "value": 10 }`. Text: `{ "type": "text", "value": "EMEA" }`. - A date range: `{ "type": "date", "subtype": "date_range", "startDate": "2026-01-01", "endDate": "2026-03-31" }`. One date: `{ "type": "date", "subtype": "date_single", "date": "2026-03-31" }`. - A month or a quarter: `{ "type": "date", "subtype": "date_month_year", "month": 3, "year": 2026 }` (months 1 to 12), `{ "type": "date", "subtype": "date_quarter_year", "quarter": 1, "year": 2026 }`. - A relative period: `{ "type": "date", "subtype": "date_relative", "rangeType": "lastN", "rangeN": 3, "periodType": "months" }`. `rangeType` is `current`, `lastN` or `nextN`; `periodType` is `days`, `weeks`, `months`, `quarters` or `years`, or `completeDays` through `completeYears` for whole periods only. - When `type` is `categorical` - `type` (`categorical`, required) - `values` (array of string or number, required) - `operator` (string): One of `is`, `is_not`, `contains`, `doesnt_contain`. - When `type` is `date` and `subtype` is `date_range` - `type` (`date`, required) - `subtype` (`date_range`, required) - `startDate` (string, required) - `endDate` (string, required) - When `type` is `date` and `subtype` is `date_relative` - `type` (`date`, required) - `subtype` (`date_relative`, required) - `rangeType` (string, required): One of `current`, `lastN`, `nextN`. - `rangeN` (number, required) - `periodType` (string, required): One of `days`, `weeks`, `months`, `quarters`, `years`, `completeDays`, `completeWeeks`, `completeMonths`, `completeQuarters`, `completeYears`. - When `type` is `date` and `subtype` is `date_month_year` - `type` (`date`, required) - `subtype` (`date_month_year`, required) - `month` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_quarter_year` - `type` (`date`, required) - `subtype` (`date_quarter_year`, required) - `quarter` (number, required) - `year` (number, required) - When `type` is `date` and `subtype` is `date_single` - `type` (`date`, required) - `subtype` (`date_single`, required) - `date` (string, required) - When `type` is `date` and `subtype` is `date_null` - `type` (`date`, required) - `subtype` (`date_null`, required) - When `type` is `number` - `type` (`number`, required) - `value` (number, required) - When `type` is `text` - `type` (`text`, required) - `value` (string, required) - `filters` (array of object, required): The filters of the template report's syncs that the variants differ by, primary ones first in the order their values name a variant. Each variant holds its own value of each, applied to the syncs that read the filter's dashboard. Empty for a burst by `parameters`. - `id` (string, required): The filter's id. Use it as a key of `filters` in `addBurstVariants`. - `name` (string, required): The filter's name on its dashboard, as shown in Rollstack. - `primary` (boolean, required): Whether the filter names the variants: a variant added without a `name` is named after its primary filters' values, in order. A secondary filter only narrows what each variant shows. - `valueType` (string or null, required): The kind of value the filter takes, and so the `type` of a variant's value of it. `null` when Rollstack doesn't know the filter's editor: copy the shape of a variant's value instead. One of `categorical`, `date`, `number`, `text`. - `variantCount` (number, required): How many variants the burst has, including any you can't open. - `appUrl` (string (uri), required): Link that opens the burst in Rollstack. - `createdAt` (string (date-time), required): When the burst was created. `listBursts` returns the newest first. - `updatedAt` (string (date-time), required): When the burst's details last changed. ### Reapply burst filters `POST https://api.rollstack.com/public/v1/bursts/{id}/filters/reapply` Writes each variant's filter values into its syncs again, as the app's Reapply does: after syncs were added to the template, or a filter changed on its dashboard. It reads the dashboards with your access to their connections, and runs nothing: run the variants afterwards with startBurstRun. Members who only contribute reapply their own variants. A Rollstack report's burst returns 400. Requires the `slide_decks:write` scope. Operation ID: `reapplyBurstFilters`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `variantIds` (array of string): The variants to act on, by their `id` in `listBurstVariants`, instead of every variant. Each must be a variant of this burst. 1 to 500 ids. #### Response `200` Success `application/json` - `reapplied` (array of object, required): The variants whose filter values were written into their syncs again. Run them with `startBurstRun` to see the change. - `id` (string, required): The variant's report id. - `name` (string, required): The variant's report name. ### Remove burst variants `POST https://api.rollstack.com/public/v1/bursts/{id}/variants/remove` Removes variants of a burst by their ids, and deletes their reports. Find the ids with listBurstVariants, which shows each variant's parameter or filter values, and confirm them with the user. An older report's variant file stays in Google Drive or OneDrive. The user must be able to edit every variant passed, or nothing is removed: the burst's owner and admins can edit them all, other members only their own. From an AI client, the removal only asks the user to confirm it in Rollstack: it answers `confirmation-required` and runs once they confirm. Requires the `slide_decks:write` scope. Operation ID: `removeBurstVariants`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `variantIds` (array of string, required): The variants to remove, by their `id` in `listBurstVariants`, which shows each one's parameter or filter values. Each must be a variant of this burst. 1 to 500 ids. #### Response `200` Success `application/json` - `removed` (array of object, required): The variants removed, whose reports are deleted. - `id` (string, required): The removed variant's report id. - `name` (string, required): The removed variant's report name. ### Send burst email configuration test `POST https://api.rollstack.com/public/v1/bursts/{id}/email-configs/{configId}/test` Sends a burst's email configuration to you alone, to check how it looks before sending it. Only the burst's owner and admins may. Sends have a low rate limit. Requires the `slide_decks:email` scope. Operation ID: `sendBurstEmailConfigTest`. #### Path parameters - `id` (string, required): The burst to act on, by its `id` from `listBursts`. You can also copy it from the burst's link in Rollstack: it's the part right after `/collections/`. - `configId` (string, required): The email configuration, by its `id` from `listBurstEmailConfigs`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `200` Success `application/json` - `id` (string, required): The email configuration. - `name` (string or null, required): The email configuration's name. ## Connections Data source connections: the Looker, Metabase, Omni, Lightdash, Sigma, Tableau, Power BI and Salesforce instances, and Snowflake and Databricks warehouses, reports read data from. Credentials are write-only and tested before they are saved; reads never answer them. Use `searchDashboards` and `getDashboard` to find a dashboard and its tabs, then add it to a report with `addReportDatasheets`. On a Salesforce connection, `searchDashboards` finds reports, which you add with `addReportDatasheets` directly. On a Snowflake or Databricks connection, `searchTables` finds tables and views, which you add the same way. On a Looker, Power BI or Tableau connection, `searchModels` finds its explores, semantic models and published data sources: add one the same way and the slides agent queries it in the BI tool. Snowflake and Databricks connect through browser OAuth, so only the app can create them or change their credentials. ### List connections `GET https://api.rollstack.com/public/v1/connections` The data source connections the user can see, without their credentials: each one's type, name, settings such as its URL, owner, admins, default user and whether any user's access works. Requires the `connections:read` scope. Operation ID: `listConnections`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the connection. Pass it with `type` to the other `/connections/{type}/{id}` endpoints. - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `name` (string, required): The connection's name, as members see it in Rollstack. - `config` (object, required): The connection's settings other than its credentials, which Rollstack never returns. Each type has only the settings that apply to it. - `baseUrl` (string): The URL of the instance the connection reads from, such as your Looker, Metabase or Snowflake URL. For Sigma, the API base URL of your Sigma organization's region. Power BI and Omni connections have none: an Omni connection's account is in `instanceSlug`. - `siteName` (string or null): Tableau only: the Tableau site the connection reads from, as your Tableau URLs name it after `#/site/`. `null` for a Tableau Server's default site. - `instanceSlug` (string): Omni only: your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). - `organizationSlug` (string): Sigma only: your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme`). - `projectId` (string): Lightdash only: the ID of the Lightdash project whose dashboards the connection reads. - `embeddingMode` (string): Looker only: how Rollstack opens the connection's Looker dashboards to capture their charts. `signed`: through embed URLs signed with the connection's embed secret. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Looker, Power BI and Sigma only: whose permissions in the tool apply when members read data. `per_user`: each member's own, through their own API key in Looker or found by their email in Power BI, if the connection was created with a Power BI email. `impersonated` (Looker only): one admin API key acts as each member's Looker user, found by their email. `shared`: everyone gets the same access, that of the connection's API key in Looker or of the app registration in Power BI. Sigma: `internal`, each member's own Sigma account, found by their email; `embed_users`, the same, else an embed user Rollstack creates with the account type and teams set in the app. - `authMethod` (string): Metabase, Snowflake and Databricks only: how Rollstack signs in. For Metabase, `apiKey` uses an admin API key and applies each member's Metabase permissions, found by their email, while `password` signs each member in with their own Metabase password. For Snowflake and Databricks, `oauth` has each member connect their own account through a browser sign-in, while `service` has everyone read through one Snowflake service user, with a key pair, or one Databricks service principal. - `autoProvision` (boolean, required): Whether members who join the organization get access to the connection automatically. When `false`, its owner and admins add members with `addConnectionUsers`. - `isActive` (boolean, required): Whether at least one member's access to the connection works, so data can be read through it. `false` when none does: for example, members still have to enter their own credentials in the app, no user in the tool has their email, or their credentials were found invalid. - `defaultUserId` (number or null, required): The user id of the connection's default user, which the app calls its service account. Everyone with access to the connection reads its data through this member's access instead of their own. `null` when there's none, so each member reads with their own access. - `owner` (object or null, required): The member who owns the connection, usually the one who created it. Only the owner can delete the connection and add or remove its admins. `null` if no member holds the owner role. - `id` (number, required): The owner's user id, as `listMembers` returns it. - `email` (string, required): The owner's email address. - `admins` (array of object, required): The members who manage the connection, each with their role on it: its owner and its admins. - `userId` (number, required): The member's user id, as `listMembers` returns it. - `role` (string, required): The member's role on the connection. `owner`: owns the connection; only they can delete it and add or remove admins. `admin`: can change the connection's settings and credentials, and manage who has access to it. One of `owner`, `admin`. - `hasCredentials` (`true`, required): Always `true`. Credentials are write-only: Rollstack never returns them. Change them with `replaceConnectionCredentials`. - `createdAt` (string (date-time), required): When the connection was created. - `updatedAt` (string (date-time), required): When the connection was last updated, for example renamed or given new credentials. ### Create connection `POST https://api.rollstack.com/public/v1/connections` Creates a data source connection after testing its credentials. Only owners and admins of the organization may. Snowflake and Databricks connect through browser OAuth, so only the app can create them. Requires the `connections:write` scope. Operation ID: `createConnection`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - When `type` is `Tableau` - `baseUrl` (string, required): The URL of the Tableau Cloud or Server instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.online.tableau.com`. - `type` (`Tableau`, required): Set to `Tableau` to connect Tableau Cloud or Tableau Server. When replacing credentials, it must match the `type` in the path. - `siteName` (string or null): The Tableau site the connection reads from, as your Tableau URLs name it after `#/site/` (`acme` in `https://online.tableau.com/#/site/acme/workbooks`). `null` for a Tableau Server's default site, which is also what omitting it means when creating the connection. It can't change when replacing credentials: omit it or send the connection's current `config.siteName`. Example: `acme`. - `clientId` (string, required): The Client ID of the Tableau connected app Rollstack signs in through. In Tableau, create it under Settings > Connected Apps > New Connected App > Direct Trust, with access to all projects and all domains allowed, then enable it. Example: `0f8e1c2d-3b4a-4c5d-9e6f-7a8b9c0d1e2f`. - `secretId` (string, required): The Secret ID of the connected app's secret, shown with its Client ID under Settings > Connected Apps in Tableau. Example: `5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d`. - `secretValue` (string, required): The Secret Value of the same connected app secret as `secretId`. Example: `your-connected-app-secret`. - `username` (string, required): Your Tableau username, usually your email: the connected app signs in to Tableau as this user, and Rollstack tests the credentials with it. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern, such as their email if this is yours. Members can change theirs in the app. Example: `jane@acme.com`. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Looker` - `baseUrl` (string, required): The URL of the Looker instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.cloud.looker.com`. - `type` (`Looker`, required): Set to `Looker` to connect a Looker instance. When replacing credentials, it must match the `type` in the path. - `clientId` (string, required): The client ID of the Looker API key Rollstack connects with. A Looker admin generates it under Admin > Users > Users: open the user or service account, then Edit keys under API keys. With `impersonated` authorization, that Looker user must have the Admin role. Example: `kG8mQ2xYp4Rz7wNs3Vbc`. - `clientSecret` (string, required): The client secret generated with `clientId`, from the same Looker API key. Example: `your-looker-client-secret`. - `embedSecret` (string, required): The embed secret Rollstack signs Looker embed URLs with to open your dashboards. Generate it on the Embed page of Looker's Admin panel, where you also add `https://*.rollstack.com` to the Embedded Domain Allowlist. Example: `your-looker-embed-secret`. - `embeddingMode` (string, required): How Rollstack opens your Looker dashboards to capture their charts. `signed` (recommended): through embed URLs signed with `embedSecret`. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Whose Looker permissions apply when members read data through the connection. `per_user`: each member reads with an API key of their own Looker user, so they see what their Looker permissions allow; every member needs their own API key set up. `impersonated`: this API key, whose Looker user must have the Admin role, acts as each member's Looker user, found by their email. `shared`: everyone reads with this API key and its permissions. Defaults to `per_user` when creating the connection. Changing it overwrites every member's Looker credentials, which can't be undone. When replacing credentials, omitting it keeps the connection's current value. One of `per_user`, `impersonated`, `shared`. - `lookerUserEmail` (string or null): With `impersonated` authorization, the email of the Looker user this API key acts as when Rollstack tests the credentials, usually your own; the test fails unless this or `lookerUserId` finds a Looker user. When members read data, each acts as the Looker user with their own email instead. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `lookerUserId` (string or null): With `impersonated` authorization, the id of the Looker user this API key acts as when Rollstack tests the credentials. When there's none, Rollstack finds it from `lookerUserEmail`. When replacing credentials, omitting it keeps the connection's current value. Example: `42`. - `userAttributes` (object): Looker user attributes, by attribute name, that Rollstack sets for every member when it opens dashboards through signed embed URLs, such as a `region` your Looker models filter rows by. They take precedence over the Looker user's own values for those attributes. If omitted when creating the connection, none are set. When replacing credentials, omitting it keeps the connection's current value. Example: `{"region":"EMEA"}`. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Lightdash` - `baseUrl` (string, required): The URL of the Lightdash instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.lightdash.cloud`. - `personalAccessToken` (string, required): The Lightdash token Rollstack connects with: a personal access token, starting with `ldpat_`, or a service account token, starting with `ldsvc_`. When the connection is created, your access uses it; every other member sets their own token in the app. Example: `ldpat_your-personal-access-token`. - `userEmail` (string or null): The email of the Lightdash user whose user attributes Rollstack applies when it opens dashboards through your access. Only used with a service account token (`ldsvc_`); when it's set, the token must have Lightdash's Admin role, or the test fails. If `null`, the attributes of the token's own user apply. When the connection is created, only your access gets it: other members' access applies the attributes of their own token's user. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `projectId` (string, required): The ID of the Lightdash project whose dashboards the connection reads, shown at the bottom of the Project Settings page in Lightdash. Example: `3e5f7a9b-1c2d-4e3f-8a5b-7c9d1e3f5a7b`. - `embedSecret` (string, required): The embed secret Rollstack signs Lightdash embed tokens with to open your dashboards. Generate it in Lightdash under Project Settings > Embed Configuration. Example: `your-lightdash-embed-secret`. - `type` (`Lightdash`, required): Set to `Lightdash` to connect a Lightdash project. When replacing credentials, it must match the `type` in the path. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Metabase` - `baseUrl` (string, required): The URL of the Metabase instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.metabaseapp.com`. - `embedSecret` (string, required): The embedding secret key Rollstack signs Metabase embed URLs with to open your dashboards. In Metabase's Admin settings, go to Embedding, enable embedding, then generate the Embedding Secret Key under More details. Example: `your-metabase-embedding-secret`. - `authMethod` (string, required): How Rollstack signs in to Metabase. `apiKey` (recommended): with the admin API key in `apiKey`, matching each member to the Metabase user with their email, so they only see the dashboards their Metabase permissions allow. `password`: each member signs in with their own Metabase username and password; members other than you enter their password in the app. One of `password`, `apiKey`. - `type` (`Metabase`, required): Set to `Metabase` to connect a Metabase instance. When replacing credentials, it must match the `type` in the path. - `username` (string, required): Your Metabase username, usually your email. With `password` auth, Rollstack signs in with it and `password`; with `apiKey` auth, it finds your Metabase user, whose permissions apply. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern. Example: `jane@acme.com`. - `password` (string or null): Your Metabase password, required with `password` auth. When the connection is created, only your access gets it: other members enter their own in the app. Defaults to `null`. Example: `your-metabase-password`. - `apiKey` (string or null): The admin API key Rollstack reads Metabase with, required with `apiKey` auth. Every member's access uses it. Defaults to `null`. Example: `mb_your-api-key`. - `sessionId` (string or null): With `password` auth, an existing Metabase session token for Rollstack to use. If omitted, Rollstack signs in with `username` and `password` to get one, and again whenever it stops working. Defaults to `null`. Example: `8c1d3e5f-7a9b-4c1d-8e3f-5a7b9c1d3e5f`. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Salesforce` - `type` (`Salesforce`, required): Set to `Salesforce` to connect a Salesforce org. When replacing credentials, it must match the `type` in the path. - `baseUrl` (string, required): The URL of the Salesforce instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.my.salesforce.com`. - `clientId` (string, required): The Consumer Key of the External Client App you create for Rollstack in Salesforce. Enable the JWT Bearer Flow on it and upload Rollstack's certificate, which you can download from the Salesforce connection setup in the Rollstack app. Find the key in the External Client App's Settings tab, under OAuth Settings > Consumer Key and Secret. Example: `your-consumer-key`. - `username` (string, required): Your Salesforce username: Rollstack signs in to Salesforce as this user through the JWT Bearer Flow, and tests the credentials with it. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern. Example: `jane@acme.com`. - `useCrma` (boolean, required): Whether you can also add CRM Analytics dashboards from this connection to Rollstack reports, besides Salesforce reports. When `false`, only Salesforce reports are offered. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `PowerBI` - `clientId` (string, required): The Application (client) ID of the Microsoft Entra app registration Rollstack reads Power BI through, shown on its Overview page in the Azure Portal. Add the app to each Power BI workspace Rollstack should read, with the Member role. Example: `2b4d6f8a-0c1e-4a3b-9d5f-7b9d1f3a5c7e`. - `tenantId` (string, required): The Directory (tenant) ID of your Microsoft Entra tenant, shown next to the Application ID on the app registration's Overview page. Example: `4d6f8a0c-2e3a-4b5c-8d7e-9f1a3b5c7d9e`. - `secretValue` (string, required): The Value of a client secret of the app registration, created in the Azure Portal under Certificates & secrets > New client secret. Example: `your-client-secret-value`. - `userEmail` (string or null): Your email in Power BI, used with `per_user` authorization: your access to the connection then shows only the Power BI reports this account can see, and each other member's access only those their own Power BI account, found by their Rollstack email, can see. If `null` or omitted when creating the connection, no member's Power BI permissions apply, even with `per_user`: everyone sees what the app registration can see. Replacing it later only affects members who get access afterward. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `authorizationMode` (string, required): Whose Power BI permissions apply. `per_user`: each member only sees the Power BI reports their own Power BI account can access, found by their email, as long as `userEmail` is set; the app registration needs read-only Admin API access. `shared`: every member sees everything the app registration can see, whatever their Power BI permissions. One of `shared`, `per_user`. - `type` (`PowerBI`, required): Set to `PowerBI` to connect Power BI. When replacing credentials, it must match the `type` in the path. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Omni` - `instanceSlug` (string, required): Your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). It can't change when replacing credentials: send the connection's current `config.instanceSlug`. Example: `acme`. - `externalUserEmail` (string, required): The email of your Omni user, usually your own email; the test fails unless an Omni user has it. When the connection is created, your access opens dashboards as this Omni user, with that user's groups, user attributes and dashboards, and each other member's access as the Omni user with their Rollstack email. Example: `jane@acme.com`. - `apiKey` (string, required): An Omni organization API key, which every member's access uses. In Omni, go to Settings > API Access > Organization keys and click Generate New Key. Example: `your-omni-api-key`. - `embedSecret` (string, required): The embed secret Rollstack signs Omni embed URLs with to open your dashboards. In Omni, find it under Settings > Embed > Admin; if there's no Embed section, ask Omni support to enable it. Example: `your-omni-embed-secret`. - `type` (`Omni`, required): Set to `Omni` to connect an Omni account. When replacing credentials, it must match the `type` in the path. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - When `type` is `Sigma` - `baseUrl` (string, required): The API base URL of your Sigma organization, which depends on the cloud and region it runs in. In Sigma, find it under Administration > Developer access. It can't change when replacing credentials: send the connection's current `config.baseUrl`. One of `https://aws-api.sigmacomputing.com`, `https://api.us-a.aws.sigmacomputing.com`, `https://api.ca.aws.sigmacomputing.com`, `https://api.eu.aws.sigmacomputing.com`, `https://api.ch.aws.sigmacomputing.com`, `https://api.uk.aws.sigmacomputing.com`, `https://api.au.aws.sigmacomputing.com`, `https://api.in.aws.sigmacomputing.com`, `https://api.us.azure.sigmacomputing.com`, `https://api.eu.azure.sigmacomputing.com`, `https://api.ca.azure.sigmacomputing.com`, `https://api.uk.azure.sigmacomputing.com`, `https://api.au.azure.sigmacomputing.com`, `https://api.sigmacomputing.com`, `https://api.sa.gcp.sigmacomputing.com`. Example: `https://aws-api.sigmacomputing.com`. - `organizationSlug` (string, required): Your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme/workbook/...`). Any Sigma URL of the organization works too. It can't change when replacing credentials: send the connection's current `config.organizationSlug`. Example: `acme`. - `serviceClientId` (string, required): The client ID of Sigma client credentials with the REST API and Embedding scopes, which every member's access uses. The Embedding scope is part of Sigma's secure embedding add-on. Their owner must be an active Sigma Admin. In Sigma, go to Administration > Developer access and click Create new. Example: `your-sigma-client-id`. - `serviceClientSecret` (string, required): The client secret Sigma shows once, when it creates the client credentials. Rollstack stores it encrypted and never returns it. Example: `your-sigma-client-secret`. - `externalUserEmail` (string, required): The email of your Sigma member, usually your own email; the test fails unless a Sigma member has it. When the connection is created, your access opens workbooks as this Sigma member, and each other member's access as the Sigma member with their Rollstack email. Example: `jane@acme.com`. - `type` (`Sigma`, required): Set to `Sigma` to connect a Sigma organization. When replacing credentials, it must match the `type` in the path. - `name` (string, required): The name members will see for the connection in Rollstack. Example: `Acme Looker`. - `autoProvision` (boolean): Whether everyone in the organization gets access to the connection: every active member right away, and each new member as they join. When `false`, only you get access, and you add others with `addConnectionUsers`. Defaults to `true`. - Option 9: Not supported: Snowflake and Databricks connections are created, and their credentials changed, only in the Rollstack app. A request with either type returns a `400` error. - `type` (string, required): `Snowflake` or `Databricks`. Create these connections, and change their credentials, in the Rollstack app. One of `Snowflake`, `Databricks`. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the connection. Pass it with `type` to the other `/connections/{type}/{id}` endpoints. - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `name` (string, required): The connection's name, as members see it in Rollstack. - `config` (object, required): The connection's settings other than its credentials, which Rollstack never returns. Each type has only the settings that apply to it. - `baseUrl` (string): The URL of the instance the connection reads from, such as your Looker, Metabase or Snowflake URL. For Sigma, the API base URL of your Sigma organization's region. Power BI and Omni connections have none: an Omni connection's account is in `instanceSlug`. - `siteName` (string or null): Tableau only: the Tableau site the connection reads from, as your Tableau URLs name it after `#/site/`. `null` for a Tableau Server's default site. - `instanceSlug` (string): Omni only: your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). - `organizationSlug` (string): Sigma only: your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme`). - `projectId` (string): Lightdash only: the ID of the Lightdash project whose dashboards the connection reads. - `embeddingMode` (string): Looker only: how Rollstack opens the connection's Looker dashboards to capture their charts. `signed`: through embed URLs signed with the connection's embed secret. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Looker, Power BI and Sigma only: whose permissions in the tool apply when members read data. `per_user`: each member's own, through their own API key in Looker or found by their email in Power BI, if the connection was created with a Power BI email. `impersonated` (Looker only): one admin API key acts as each member's Looker user, found by their email. `shared`: everyone gets the same access, that of the connection's API key in Looker or of the app registration in Power BI. Sigma: `internal`, each member's own Sigma account, found by their email; `embed_users`, the same, else an embed user Rollstack creates with the account type and teams set in the app. - `authMethod` (string): Metabase, Snowflake and Databricks only: how Rollstack signs in. For Metabase, `apiKey` uses an admin API key and applies each member's Metabase permissions, found by their email, while `password` signs each member in with their own Metabase password. For Snowflake and Databricks, `oauth` has each member connect their own account through a browser sign-in, while `service` has everyone read through one Snowflake service user, with a key pair, or one Databricks service principal. - `autoProvision` (boolean, required): Whether members who join the organization get access to the connection automatically. When `false`, its owner and admins add members with `addConnectionUsers`. - `isActive` (boolean, required): Whether at least one member's access to the connection works, so data can be read through it. `false` when none does: for example, members still have to enter their own credentials in the app, no user in the tool has their email, or their credentials were found invalid. - `defaultUserId` (number or null, required): The user id of the connection's default user, which the app calls its service account. Everyone with access to the connection reads its data through this member's access instead of their own. `null` when there's none, so each member reads with their own access. - `owner` (object or null, required): The member who owns the connection, usually the one who created it. Only the owner can delete the connection and add or remove its admins. `null` if no member holds the owner role. - `id` (number, required): The owner's user id, as `listMembers` returns it. - `email` (string, required): The owner's email address. - `admins` (array of object, required): The members who manage the connection, each with their role on it: its owner and its admins. - `userId` (number, required): The member's user id, as `listMembers` returns it. - `role` (string, required): The member's role on the connection. `owner`: owns the connection; only they can delete it and add or remove admins. `admin`: can change the connection's settings and credentials, and manage who has access to it. One of `owner`, `admin`. - `hasCredentials` (`true`, required): Always `true`. Credentials are write-only: Rollstack never returns them. Change them with `replaceConnectionCredentials`. - `createdAt` (string (date-time), required): When the connection was created. - `updatedAt` (string (date-time), required): When the connection was last updated, for example renamed or given new credentials. ### Get connection `GET https://api.rollstack.com/public/v1/connections/{type}/{id}` A data source connection, without its credentials. listConnections gives its type and id. Requires the `connections:read` scope. Operation ID: `getConnection`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the connection. Pass it with `type` to the other `/connections/{type}/{id}` endpoints. - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `name` (string, required): The connection's name, as members see it in Rollstack. - `config` (object, required): The connection's settings other than its credentials, which Rollstack never returns. Each type has only the settings that apply to it. - `baseUrl` (string): The URL of the instance the connection reads from, such as your Looker, Metabase or Snowflake URL. For Sigma, the API base URL of your Sigma organization's region. Power BI and Omni connections have none: an Omni connection's account is in `instanceSlug`. - `siteName` (string or null): Tableau only: the Tableau site the connection reads from, as your Tableau URLs name it after `#/site/`. `null` for a Tableau Server's default site. - `instanceSlug` (string): Omni only: your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). - `organizationSlug` (string): Sigma only: your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme`). - `projectId` (string): Lightdash only: the ID of the Lightdash project whose dashboards the connection reads. - `embeddingMode` (string): Looker only: how Rollstack opens the connection's Looker dashboards to capture their charts. `signed`: through embed URLs signed with the connection's embed secret. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Looker, Power BI and Sigma only: whose permissions in the tool apply when members read data. `per_user`: each member's own, through their own API key in Looker or found by their email in Power BI, if the connection was created with a Power BI email. `impersonated` (Looker only): one admin API key acts as each member's Looker user, found by their email. `shared`: everyone gets the same access, that of the connection's API key in Looker or of the app registration in Power BI. Sigma: `internal`, each member's own Sigma account, found by their email; `embed_users`, the same, else an embed user Rollstack creates with the account type and teams set in the app. - `authMethod` (string): Metabase, Snowflake and Databricks only: how Rollstack signs in. For Metabase, `apiKey` uses an admin API key and applies each member's Metabase permissions, found by their email, while `password` signs each member in with their own Metabase password. For Snowflake and Databricks, `oauth` has each member connect their own account through a browser sign-in, while `service` has everyone read through one Snowflake service user, with a key pair, or one Databricks service principal. - `autoProvision` (boolean, required): Whether members who join the organization get access to the connection automatically. When `false`, its owner and admins add members with `addConnectionUsers`. - `isActive` (boolean, required): Whether at least one member's access to the connection works, so data can be read through it. `false` when none does: for example, members still have to enter their own credentials in the app, no user in the tool has their email, or their credentials were found invalid. - `defaultUserId` (number or null, required): The user id of the connection's default user, which the app calls its service account. Everyone with access to the connection reads its data through this member's access instead of their own. `null` when there's none, so each member reads with their own access. - `owner` (object or null, required): The member who owns the connection, usually the one who created it. Only the owner can delete the connection and add or remove its admins. `null` if no member holds the owner role. - `id` (number, required): The owner's user id, as `listMembers` returns it. - `email` (string, required): The owner's email address. - `admins` (array of object, required): The members who manage the connection, each with their role on it: its owner and its admins. - `userId` (number, required): The member's user id, as `listMembers` returns it. - `role` (string, required): The member's role on the connection. `owner`: owns the connection; only they can delete it and add or remove admins. `admin`: can change the connection's settings and credentials, and manage who has access to it. One of `owner`, `admin`. - `hasCredentials` (`true`, required): Always `true`. Credentials are write-only: Rollstack never returns them. Change them with `replaceConnectionCredentials`. - `createdAt` (string (date-time), required): When the connection was created. - `updatedAt` (string (date-time), required): When the connection was last updated, for example renamed or given new credentials. ### Update connection `PATCH https://api.rollstack.com/public/v1/connections/{type}/{id}` Renames a connection, changes whether new members get access, or changes the default user, whose access everyone without their own uses. Send only the fields to change, at least one; a null defaultUserId removes the default user. Requires the `connections:write` scope. Operation ID: `updateConnection`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): The new name members will see for the connection in Rollstack. If omitted, the name stays the same. Example: `Acme Looker`. - `autoProvision` (boolean): Whether members who join the organization from now on get access to the connection automatically. Turning it on doesn't give access to current members who don't have it: add them with `addConnectionUsers`. If omitted, the setting stays the same. - `defaultUserId` (integer or null): The member to make the connection's default user, which the app calls its service account, by user id from `listConnectionUsers`: they must already have access to the connection. Everyone with access to the connection reads its data through this member's access instead of their own. Setting another member replaces the current default user, and `null` removes it, so each member reads with their own access again. If omitted, it stays the same. Only the connection's owner and admins may change it, and a Databricks connection can't have one. On Sigma, their access must match an active Sigma member, which `isActive` from `listConnectionUsers` shows, or the call answers 404 `datasource-user-not-found`. Example: `1042`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the connection. Pass it with `type` to the other `/connections/{type}/{id}` endpoints. - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `name` (string, required): The connection's name, as members see it in Rollstack. - `config` (object, required): The connection's settings other than its credentials, which Rollstack never returns. Each type has only the settings that apply to it. - `baseUrl` (string): The URL of the instance the connection reads from, such as your Looker, Metabase or Snowflake URL. For Sigma, the API base URL of your Sigma organization's region. Power BI and Omni connections have none: an Omni connection's account is in `instanceSlug`. - `siteName` (string or null): Tableau only: the Tableau site the connection reads from, as your Tableau URLs name it after `#/site/`. `null` for a Tableau Server's default site. - `instanceSlug` (string): Omni only: your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). - `organizationSlug` (string): Sigma only: your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme`). - `projectId` (string): Lightdash only: the ID of the Lightdash project whose dashboards the connection reads. - `embeddingMode` (string): Looker only: how Rollstack opens the connection's Looker dashboards to capture their charts. `signed`: through embed URLs signed with the connection's embed secret. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Looker, Power BI and Sigma only: whose permissions in the tool apply when members read data. `per_user`: each member's own, through their own API key in Looker or found by their email in Power BI, if the connection was created with a Power BI email. `impersonated` (Looker only): one admin API key acts as each member's Looker user, found by their email. `shared`: everyone gets the same access, that of the connection's API key in Looker or of the app registration in Power BI. Sigma: `internal`, each member's own Sigma account, found by their email; `embed_users`, the same, else an embed user Rollstack creates with the account type and teams set in the app. - `authMethod` (string): Metabase, Snowflake and Databricks only: how Rollstack signs in. For Metabase, `apiKey` uses an admin API key and applies each member's Metabase permissions, found by their email, while `password` signs each member in with their own Metabase password. For Snowflake and Databricks, `oauth` has each member connect their own account through a browser sign-in, while `service` has everyone read through one Snowflake service user, with a key pair, or one Databricks service principal. - `autoProvision` (boolean, required): Whether members who join the organization get access to the connection automatically. When `false`, its owner and admins add members with `addConnectionUsers`. - `isActive` (boolean, required): Whether at least one member's access to the connection works, so data can be read through it. `false` when none does: for example, members still have to enter their own credentials in the app, no user in the tool has their email, or their credentials were found invalid. - `defaultUserId` (number or null, required): The user id of the connection's default user, which the app calls its service account. Everyone with access to the connection reads its data through this member's access instead of their own. `null` when there's none, so each member reads with their own access. - `owner` (object or null, required): The member who owns the connection, usually the one who created it. Only the owner can delete the connection and add or remove its admins. `null` if no member holds the owner role. - `id` (number, required): The owner's user id, as `listMembers` returns it. - `email` (string, required): The owner's email address. - `admins` (array of object, required): The members who manage the connection, each with their role on it: its owner and its admins. - `userId` (number, required): The member's user id, as `listMembers` returns it. - `role` (string, required): The member's role on the connection. `owner`: owns the connection; only they can delete it and add or remove admins. `admin`: can change the connection's settings and credentials, and manage who has access to it. One of `owner`, `admin`. - `hasCredentials` (`true`, required): Always `true`. Credentials are write-only: Rollstack never returns them. Change them with `replaceConnectionCredentials`. - `createdAt` (string (date-time), required): When the connection was created. - `updatedAt` (string (date-time), required): When the connection was last updated, for example renamed or given new credentials. ### Delete connection `DELETE https://api.rollstack.com/public/v1/connections/{type}/{id}` Deletes a connection with every user's access to it and every sync that uses it. Only its owner may. Requires the `connections:write` scope. Operation ID: `deleteConnection`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Search dashboards `GET https://api.rollstack.com/public/v1/connections/{type}/{id}/dashboards` The dashboards of a Looker, Metabase, Omni, Lightdash, Sigma, Tableau or Power BI connection whose name holds any word of query or its singular, in any case, at most 50: those the most of the organization's reports read first, copies, old and personal ones last, then most words first, read with the user's access to the connection. A Tableau dashboard is a workbook, its views its tabs; a Power BI one a report, its pages its tabs; a Sigma one a workbook, its pages its tabs. On a Sigma connection, query can be a link to a workbook the user pasted: it finds only that workbook, with the page the link opens on as tabId, but not the link's control values, saved view or tag, and a link to another Sigma organization is rejected. On a Salesforce connection it finds reports the same way, the most recently run first among equals, each with its format: a report has no tabs, so add a tabular or summary one to a report with addReportDatasheets by its reportId, without getDashboard, and tell the user a matrix or joined one can't be added yet. Search by the name the user gives, confirm the dashboard with the user, then check its tabs and charts with getDashboard or add it to a report with addReportDatasheets. listConnections gives the connection's type and id. Requires the `connections:read` scope. Operation ID: `searchDashboards`. #### Path parameters - `type` (string, required): The type of connection, as `type` in `listConnections`: the BI tool it connects to. Only Looker, Metabase, Omni, Lightdash, Sigma, Tableau and Power BI (`PowerBI`) connections have dashboards, and on a `Salesforce` connection the search finds its reports. One of `Looker`, `Metabase`, `Omni`, `Lightdash`, `Tableau`, `PowerBI`, `Sigma`, `Salesforce`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Query parameters - `query` (string): Words to search for in names, separated by spaces: a dashboard, table, model or spreadsheet is returned when its name contains any of them, case-insensitively, a table's full name with its database and schema. If omitted, results aren't filtered by name. At most 50 results are returned either way. Example: `revenue`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Identifies the dashboard in its BI tool. Pass it as `dashboardId` to `getDashboard` or `addReportDatasheets`. For Tableau it is the workbook's id; for Power BI, the report's workspace id and report id, joined by a dot; for Sigma, the workbook's UUID, not the short id in its links. For Salesforce it is a report's id, to pass as `reportId` to `addReportDatasheets`; a report has no tabs, so `getDashboard` doesn't read it. - `name` (string, required): The dashboard's name in its BI tool. For Tableau and Sigma it is the workbook's name, for Power BI and Salesforce the report's. - `folder` (string or null, required): Where the dashboard is filed in its BI tool: its Looker, Omni or Salesforce folder, Metabase collection, Power BI workspace or Sigma path (`My Documents` for a workbook in your own Sigma documents). Helps tell apart dashboards with the same name, such as copies of a Power BI report in several workspaces. `null` when the BI tool gives none, and always for Lightdash and Tableau. - `decks` (number, required): How many of your organization's reports have a datasheet that reads from this dashboard through this connection. Results are sorted by this count, highest first. - `tabId` (string): Only for a Sigma workbook found by a link to one of its pages or elements: the page the link opens on, to pass as `tabId` to `getDashboard` or `addReportDatasheets`. - `tabName` (string): Only with `tabId`: the name of the page the link opens on, as Sigma shows it. - `format` (string): Only for a Salesforce report: its format in Salesforce. Only `tabular` and `summary` reports can be added with `addReportDatasheets`; `matrix` and `joined` reports can't be added yet, so tell the user rather than offering them. One of `tabular`, `summary`, `matrix`, `joined`. ### Get dashboard `GET https://api.rollstack.com/public/v1/connections/{type}/{id}/dashboards/{dashboardId}` A dashboard of a Looker, Metabase, Omni, Lightdash, Sigma, Tableau or Power BI connection, read with the user's access to the connection (a Salesforce report has no tabs or charts to read, so add it with addReportDatasheets directly): its tabs, and the charts and filters of the tab tabId names, one of the ids in tabs (else the one the dashboard opens on, a Power BI report's or Sigma workbook's first page). Tableau and Power BI list no charts or filters here: once the tab is added to a report, its charts are listed from its picture for the slides agent to add; a Sigma page lists its charts and tables, and the workbook's controls as its filters. Find the dashboard's id with searchDashboards. Confirm the dashboard and tab with the user, then add it to a report with addReportDatasheets; for another tab, call it again with that tab's id from tabs. Requires the `connections:read` scope. Operation ID: `getDashboard`. #### Path parameters - `type` (string, required): The type of connection, as `type` in `listConnections`: the BI tool it connects to. Only Looker, Metabase, Omni, Lightdash, Sigma, Tableau and Power BI (`PowerBI`) connections have dashboards. One of `Looker`, `Metabase`, `Omni`, `Lightdash`, `Tableau`, `PowerBI`, `Sigma`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. - `dashboardId` (string, required): The dashboard to read, by the `id` that `searchDashboards` returns. #### Query parameters - `tabId` (string): The dashboard tab to read, by its `id` from the `tabs` that `getDashboard` returns: a Looker, Metabase or Lightdash tab, a Tableau view, a Power BI page or a Sigma page. If omitted, the dashboard's first tab is used, or the whole dashboard when it has no tabs, as on Omni. A tab the dashboard doesn't have returns a 404 error. Example: `12-overview`. #### Response `200` Success `application/json` - `connection` (object, required): The connection the dashboard was read through: the one in the request path. - `id` (string, required): Unique identifier for the connection, the `id` in the request path. - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `name` (string, required): The connection's name, as members see it in Rollstack. - `dashboard` (object, required): The dashboard you asked for. - `id` (string, required): Identifies the dashboard in its BI tool. Pass it as `dashboardId` to `getDashboard` or `addReportDatasheets`. For Tableau it is the workbook's id; for Power BI, the report's workspace id and report id, joined by a dot; for Sigma, the workbook's UUID, not the short id in its links. For Salesforce it is a report's id, to pass as `reportId` to `addReportDatasheets`; a report has no tabs, so `getDashboard` doesn't read it. - `name` (string, required): The dashboard's name in its BI tool. For Tableau and Sigma it is the workbook's name, for Power BI the report's. - `url` (string, required): A link that opens the dashboard in its BI tool. For Tableau, it opens the workbook on the view in `tabId`; for Sigma, on its first page. - `tabs` (array of object, required): The dashboard's tabs: a Looker, Metabase or Lightdash dashboard's tabs, a Tableau workbook's views, a Power BI report's pages or a Sigma workbook's pages, never its hidden ones. Empty when the dashboard has no tabs, as always on Omni. - `id` (string, required): Identifies the tab. Pass it as `tabId` to read that tab with `getDashboard`, or to add it to a report with `addReportDatasheets`. Its form depends on the BI tool: a Looker layout id, a Metabase `{id}-{slug}` such as `12-overview`, a Lightdash tab uuid, a Tableau view id, a Power BI page's internal name or a Sigma page id. - `name` (string, required): The tab's name as shown in the BI tool, such as a Power BI page's display name. - `tabId` (string or null, required): The tab `elements` comes from: the one you passed as `tabId`, or the dashboard's first tab if you passed none. `null` when the dashboard was read as a whole, as when it has no tabs. - `elements` (array of object, required): The charts and other elements on that tab, or on the whole dashboard when `tabId` is `null`. Once you add the tab to a report with `addReportDatasheets`, the slides agent can add these elements to the report's slides. For Sigma, only the page's charts and tables, without its texts, images and controls. Always empty for Tableau and Power BI: their charts are listed once the tab is added to a report, by `getReportDatasheet` on its picture, and `addReportDashboardElements` or the slides agent can then add them. - `id` (string, required): Identifies the element in its BI tool, such as a Looker tile's id, a Metabase dashboard card's id, a Lightdash chart's uuid or a Sigma element's id. - `name` (string, required): The element's title as shown on the dashboard. An element without a title, such as a text card, is named after its type instead, as in `Text`. - `type` (string, required): The kind of element, in the BI tool's own terms, such as `looker_column` for a Looker column chart, `saved_chart` for a Lightdash chart, `kpi-chart` for a Sigma KPI or `text` for a Metabase text card. - `filters` (array of object, required): The dashboard's filters, and on Omni its controls too. For Sigma, the controls on every page of the workbook, so two can share a label. Always empty for Tableau and Power BI. - `name` (string, required): The filter's label as shown on the dashboard. For Metabase it is the filter's slug instead, and for a Sigma control without a label, its control ID. ### Search models `GET https://api.rollstack.com/public/v1/connections/{type}/{id}/models` The models of a Looker, Power BI or Tableau connection whose name or group holds any word of query or its singular, in any case, at most 50: Looker explores grouped by LookML model, Power BI semantic models by workspace, Tableau published data sources by project, read with the user's access to the connection (on Tableau, their own Tableau user). A model is what the slides agent queries in its BI tool for the data a slide needs, where a dashboard tab comes in as a picture. Confirm the model with the user, then add it to a report with addReportDatasheets by its modelId and pass the new datasheet's id to sendReportMessage. listConnections gives the connection's type and id. Requires the `connections:read` scope. Operation ID: `searchModels`. #### Path parameters - `type` (string, required): The type of connection, as `type` in `listConnections`. Only Looker, Power BI (`PowerBI`) and Tableau connections have models: Looker explores, Power BI semantic models and Tableau published data sources. One of `Looker`, `PowerBI`, `Tableau`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Query parameters - `query` (string): Words to search for in names, separated by spaces: a dashboard, table, model or spreadsheet is returned when its name contains any of them, case-insensitively, a table's full name with its database and schema. If omitted, results aren't filtered by name. At most 50 results are returned either way. Example: `revenue`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Identifies the model in its BI tool, as `searchModels` lists it. Pass it as `modelId` to `addReportDatasheets`. - `name` (string, required): The model's name, as the app lists it: a Looker explore's label, else its name, a Power BI semantic model's or a Tableau data source's name. - `group` (string, required): What the app lists it under: the LookML model of a Looker explore, the workspace of a Power BI semantic model, the project of a Tableau data source. - `description` (string or null, required): A Looker explore's description from its LookML. `null` when it has none, and for Power BI and Tableau. ### Search tables `GET https://api.rollstack.com/public/v1/connections/{type}/{id}/tables` The tables and views of a Snowflake or Databricks connection whose full name, database.schema.table, holds any word of query, in any case, at most 50, read with the user's access to the connection, as its default user when one is set. The first search of a connection reads its whole catalog, which can take a while on a large warehouse. Search by the name the user gives and confirm the table with the user, then add it to a report with addReportDatasheets by its connection, database, schema and table, and pass the datasheet id on sendReportMessage: the slides agent queries it in the warehouse with SQL over all its rows. listConnections gives the connection's type and id. Requires the `connections:read` scope. Operation ID: `searchTables`. #### Path parameters - `type` (string, required): The type of connection, as `type` in `listConnections`: the `Snowflake` or `Databricks` data warehouse. One of `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Query parameters - `query` (string): Words to search for in names, separated by spaces: a dashboard, table, model or spreadsheet is returned when its name contains any of them, case-insensitively, a table's full name with its database and schema. If omitted, results aren't filtered by name. At most 50 results are returned either way. Example: `revenue`. #### Response `200` Success `application/json`: array of object - `database` (string, required): The database the table is in, its Unity Catalog catalog on Databricks. Pass it as `database` to `addReportDatasheets`. - `schema` (string, required): The schema the table is in. Pass it as `schema` to `addReportDatasheets`. - `table` (string, required): The table's name. Pass it as `table` to `addReportDatasheets`. - `type` (string, required): Whether it is a `table`, a `view` or a Databricks `metric_view`. All three can be added to a report. One of `table`, `view`, `metric_view`. ### Replace credentials `PUT https://api.rollstack.com/public/v1/connections/{type}/{id}/credentials` Replaces every credential of a connection, after testing them. Its users' access gets the new credentials too. The instance (baseUrl, siteName, instanceSlug, organizationSlug) can't change; siteName can be left out to keep the stored site. Settings the connection doesn't show (Looker user and attributes, userEmail) keep their value when left out, but Omni's and Sigma's externalUserEmail must be sent. A failed test answers 422 with the provider's code and message. Requires the `credentials:write` scope. Operation ID: `replaceConnectionCredentials`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - When `type` is `Tableau` - `baseUrl` (string, required): The URL of the Tableau Cloud or Server instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.online.tableau.com`. - `type` (`Tableau`, required): Set to `Tableau` to connect Tableau Cloud or Tableau Server. When replacing credentials, it must match the `type` in the path. - `siteName` (string or null): The Tableau site the connection reads from, as your Tableau URLs name it after `#/site/` (`acme` in `https://online.tableau.com/#/site/acme/workbooks`). `null` for a Tableau Server's default site, which is also what omitting it means when creating the connection. It can't change when replacing credentials: omit it or send the connection's current `config.siteName`. Example: `acme`. - `clientId` (string, required): The Client ID of the Tableau connected app Rollstack signs in through. In Tableau, create it under Settings > Connected Apps > New Connected App > Direct Trust, with access to all projects and all domains allowed, then enable it. Example: `0f8e1c2d-3b4a-4c5d-9e6f-7a8b9c0d1e2f`. - `secretId` (string, required): The Secret ID of the connected app's secret, shown with its Client ID under Settings > Connected Apps in Tableau. Example: `5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d`. - `secretValue` (string, required): The Secret Value of the same connected app secret as `secretId`. Example: `your-connected-app-secret`. - `username` (string, required): Your Tableau username, usually your email: the connected app signs in to Tableau as this user, and Rollstack tests the credentials with it. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern, such as their email if this is yours. Members can change theirs in the app. Example: `jane@acme.com`. - When `type` is `Looker` - `baseUrl` (string, required): The URL of the Looker instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.cloud.looker.com`. - `type` (`Looker`, required): Set to `Looker` to connect a Looker instance. When replacing credentials, it must match the `type` in the path. - `clientId` (string, required): The client ID of the Looker API key Rollstack connects with. A Looker admin generates it under Admin > Users > Users: open the user or service account, then Edit keys under API keys. With `impersonated` authorization, that Looker user must have the Admin role. Example: `kG8mQ2xYp4Rz7wNs3Vbc`. - `clientSecret` (string, required): The client secret generated with `clientId`, from the same Looker API key. Example: `your-looker-client-secret`. - `embedSecret` (string, required): The embed secret Rollstack signs Looker embed URLs with to open your dashboards. Generate it on the Embed page of Looker's Admin panel, where you also add `https://*.rollstack.com` to the Embedded Domain Allowlist. Example: `your-looker-embed-secret`. - `embeddingMode` (string, required): How Rollstack opens your Looker dashboards to capture their charts. `signed` (recommended): through embed URLs signed with `embedSecret`. `private`: through Looker's API, by exporting dashboards as PDFs, which is slower and less reliable. `cookieless` currently works like `signed`. One of `signed`, `cookieless`, `private`. - `authorizationMode` (string): Whose Looker permissions apply when members read data through the connection. `per_user`: each member reads with an API key of their own Looker user, so they see what their Looker permissions allow; every member needs their own API key set up. `impersonated`: this API key, whose Looker user must have the Admin role, acts as each member's Looker user, found by their email. `shared`: everyone reads with this API key and its permissions. Defaults to `per_user` when creating the connection. Changing it overwrites every member's Looker credentials, which can't be undone. When replacing credentials, omitting it keeps the connection's current value. One of `per_user`, `impersonated`, `shared`. - `lookerUserEmail` (string or null): With `impersonated` authorization, the email of the Looker user this API key acts as when Rollstack tests the credentials, usually your own; the test fails unless this or `lookerUserId` finds a Looker user. When members read data, each acts as the Looker user with their own email instead. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `lookerUserId` (string or null): With `impersonated` authorization, the id of the Looker user this API key acts as when Rollstack tests the credentials. When there's none, Rollstack finds it from `lookerUserEmail`. When replacing credentials, omitting it keeps the connection's current value. Example: `42`. - `userAttributes` (object): Looker user attributes, by attribute name, that Rollstack sets for every member when it opens dashboards through signed embed URLs, such as a `region` your Looker models filter rows by. They take precedence over the Looker user's own values for those attributes. If omitted when creating the connection, none are set. When replacing credentials, omitting it keeps the connection's current value. Example: `{"region":"EMEA"}`. - When `type` is `Lightdash` - `baseUrl` (string, required): The URL of the Lightdash instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.lightdash.cloud`. - `personalAccessToken` (string, required): The Lightdash token Rollstack connects with: a personal access token, starting with `ldpat_`, or a service account token, starting with `ldsvc_`. When the connection is created, your access uses it; every other member sets their own token in the app. Example: `ldpat_your-personal-access-token`. - `userEmail` (string or null): The email of the Lightdash user whose user attributes Rollstack applies when it opens dashboards through your access. Only used with a service account token (`ldsvc_`); when it's set, the token must have Lightdash's Admin role, or the test fails. If `null`, the attributes of the token's own user apply. When the connection is created, only your access gets it: other members' access applies the attributes of their own token's user. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `projectId` (string, required): The ID of the Lightdash project whose dashboards the connection reads, shown at the bottom of the Project Settings page in Lightdash. Example: `3e5f7a9b-1c2d-4e3f-8a5b-7c9d1e3f5a7b`. - `embedSecret` (string, required): The embed secret Rollstack signs Lightdash embed tokens with to open your dashboards. Generate it in Lightdash under Project Settings > Embed Configuration. Example: `your-lightdash-embed-secret`. - `type` (`Lightdash`, required): Set to `Lightdash` to connect a Lightdash project. When replacing credentials, it must match the `type` in the path. - When `type` is `Metabase` - `baseUrl` (string, required): The URL of the Metabase instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.metabaseapp.com`. - `embedSecret` (string, required): The embedding secret key Rollstack signs Metabase embed URLs with to open your dashboards. In Metabase's Admin settings, go to Embedding, enable embedding, then generate the Embedding Secret Key under More details. Example: `your-metabase-embedding-secret`. - `authMethod` (string, required): How Rollstack signs in to Metabase. `apiKey` (recommended): with the admin API key in `apiKey`, matching each member to the Metabase user with their email, so they only see the dashboards their Metabase permissions allow. `password`: each member signs in with their own Metabase username and password; members other than you enter their password in the app. One of `password`, `apiKey`. - `type` (`Metabase`, required): Set to `Metabase` to connect a Metabase instance. When replacing credentials, it must match the `type` in the path. - `username` (string, required): Your Metabase username, usually your email. With `password` auth, Rollstack signs in with it and `password`; with `apiKey` auth, it finds your Metabase user, whose permissions apply. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern. Example: `jane@acme.com`. - `password` (string or null): Your Metabase password, required with `password` auth. When the connection is created, only your access gets it: other members enter their own in the app. Defaults to `null`. Example: `your-metabase-password`. - `apiKey` (string or null): The admin API key Rollstack reads Metabase with, required with `apiKey` auth. Every member's access uses it. Defaults to `null`. Example: `mb_your-api-key`. - `sessionId` (string or null): With `password` auth, an existing Metabase session token for Rollstack to use. If omitted, Rollstack signs in with `username` and `password` to get one, and again whenever it stops working. Defaults to `null`. Example: `8c1d3e5f-7a9b-4c1d-8e3f-5a7b9c1d3e5f`. - When `type` is `Salesforce` - `type` (`Salesforce`, required): Set to `Salesforce` to connect a Salesforce org. When replacing credentials, it must match the `type` in the path. - `baseUrl` (string, required): The URL of the Salesforce instance the connection reads from. It can't change when replacing credentials: send the connection's current `config.baseUrl`, or create a new connection for another instance. Trailing slashes are removed. Example: `https://acme.my.salesforce.com`. - `clientId` (string, required): The Consumer Key of the External Client App you create for Rollstack in Salesforce. Enable the JWT Bearer Flow on it and upload Rollstack's certificate, which you can download from the Salesforce connection setup in the Rollstack app. Find the key in the External Client App's Settings tab, under OAuth Settings > Consumer Key and Secret. Example: `your-consumer-key`. - `username` (string, required): Your Salesforce username: Rollstack signs in to Salesforce as this user through the JWT Bearer Flow, and tests the credentials with it. When the connection is created, your access uses it, and each other member who gets access is given a username derived from their Rollstack email in the same pattern. Example: `jane@acme.com`. - `useCrma` (boolean, required): Whether you can also add CRM Analytics dashboards from this connection to Rollstack reports, besides Salesforce reports. When `false`, only Salesforce reports are offered. - When `type` is `PowerBI` - `clientId` (string, required): The Application (client) ID of the Microsoft Entra app registration Rollstack reads Power BI through, shown on its Overview page in the Azure Portal. Add the app to each Power BI workspace Rollstack should read, with the Member role. Example: `2b4d6f8a-0c1e-4a3b-9d5f-7b9d1f3a5c7e`. - `tenantId` (string, required): The Directory (tenant) ID of your Microsoft Entra tenant, shown next to the Application ID on the app registration's Overview page. Example: `4d6f8a0c-2e3a-4b5c-8d7e-9f1a3b5c7d9e`. - `secretValue` (string, required): The Value of a client secret of the app registration, created in the Azure Portal under Certificates & secrets > New client secret. Example: `your-client-secret-value`. - `userEmail` (string or null): Your email in Power BI, used with `per_user` authorization: your access to the connection then shows only the Power BI reports this account can see, and each other member's access only those their own Power BI account, found by their Rollstack email, can see. If `null` or omitted when creating the connection, no member's Power BI permissions apply, even with `per_user`: everyone sees what the app registration can see. Replacing it later only affects members who get access afterward. When replacing credentials, omitting it keeps the connection's current value. Example: `jane@acme.com`. - `authorizationMode` (string, required): Whose Power BI permissions apply. `per_user`: each member only sees the Power BI reports their own Power BI account can access, found by their email, as long as `userEmail` is set; the app registration needs read-only Admin API access. `shared`: every member sees everything the app registration can see, whatever their Power BI permissions. One of `shared`, `per_user`. - `type` (`PowerBI`, required): Set to `PowerBI` to connect Power BI. When replacing credentials, it must match the `type` in the path. - When `type` is `Omni` - `instanceSlug` (string, required): Your Omni account name, the subdomain of your Omni URL (`acme` in `https://acme.omniapp.co`). It can't change when replacing credentials: send the connection's current `config.instanceSlug`. Example: `acme`. - `externalUserEmail` (string, required): The email of your Omni user, usually your own email; the test fails unless an Omni user has it. When the connection is created, your access opens dashboards as this Omni user, with that user's groups, user attributes and dashboards, and each other member's access as the Omni user with their Rollstack email. Example: `jane@acme.com`. - `apiKey` (string, required): An Omni organization API key, which every member's access uses. In Omni, go to Settings > API Access > Organization keys and click Generate New Key. Example: `your-omni-api-key`. - `embedSecret` (string, required): The embed secret Rollstack signs Omni embed URLs with to open your dashboards. In Omni, find it under Settings > Embed > Admin; if there's no Embed section, ask Omni support to enable it. Example: `your-omni-embed-secret`. - `type` (`Omni`, required): Set to `Omni` to connect an Omni account. When replacing credentials, it must match the `type` in the path. - When `type` is `Sigma` - `baseUrl` (string, required): The API base URL of your Sigma organization, which depends on the cloud and region it runs in. In Sigma, find it under Administration > Developer access. It can't change when replacing credentials: send the connection's current `config.baseUrl`. One of `https://aws-api.sigmacomputing.com`, `https://api.us-a.aws.sigmacomputing.com`, `https://api.ca.aws.sigmacomputing.com`, `https://api.eu.aws.sigmacomputing.com`, `https://api.ch.aws.sigmacomputing.com`, `https://api.uk.aws.sigmacomputing.com`, `https://api.au.aws.sigmacomputing.com`, `https://api.in.aws.sigmacomputing.com`, `https://api.us.azure.sigmacomputing.com`, `https://api.eu.azure.sigmacomputing.com`, `https://api.ca.azure.sigmacomputing.com`, `https://api.uk.azure.sigmacomputing.com`, `https://api.au.azure.sigmacomputing.com`, `https://api.sigmacomputing.com`, `https://api.sa.gcp.sigmacomputing.com`. Example: `https://aws-api.sigmacomputing.com`. - `organizationSlug` (string, required): Your Sigma organization, as your Sigma URLs name it after `app.sigmacomputing.com/` (`acme` in `https://app.sigmacomputing.com/acme/workbook/...`). Any Sigma URL of the organization works too. It can't change when replacing credentials: send the connection's current `config.organizationSlug`. Example: `acme`. - `serviceClientId` (string, required): The client ID of Sigma client credentials with the REST API and Embedding scopes, which every member's access uses. The Embedding scope is part of Sigma's secure embedding add-on. Their owner must be an active Sigma Admin. In Sigma, go to Administration > Developer access and click Create new. Example: `your-sigma-client-id`. - `serviceClientSecret` (string, required): The client secret Sigma shows once, when it creates the client credentials. Rollstack stores it encrypted and never returns it. Example: `your-sigma-client-secret`. - `externalUserEmail` (string, required): The email of your Sigma member, usually your own email; the test fails unless a Sigma member has it. When the connection is created, your access opens workbooks as this Sigma member, and each other member's access as the Sigma member with their Rollstack email. Example: `jane@acme.com`. - `type` (`Sigma`, required): Set to `Sigma` to connect a Sigma organization. When replacing credentials, it must match the `type` in the path. - Option 9: Not supported: Snowflake and Databricks connections are created, and their credentials changed, only in the Rollstack app. A request with either type returns a `400` error. - `type` (string, required): `Snowflake` or `Databricks`. Create these connections, and change their credentials, in the Rollstack app. One of `Snowflake`, `Databricks`. #### Response `204` Success, no content ## Connection users Who can use a connection. Each user reads data with their own access to the connection; a user without one uses the default user's, when the connection has one. With `autoProvision` on, new members of the organization get access on their own. Removing a user also deletes the syncs that read through their access. ### List connection users `GET https://api.rollstack.com/public/v1/connections/{type}/{id}/users` The users with access to a connection, with whether each is the default user and whether their access works. Only its admins may. Requires the `connections:read` scope. Operation ID: `listConnectionUsers`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Response `200` Success `application/json`: array of object - `userId` (number, required): Identifies the user, as their `id` in `listMembers`. Pass it as `userId` to `removeConnectionUser`, or as `defaultUserId` to `updateConnection` to make them the default user. - `email` (string, required): The email address of the user's Rollstack account. - `isDefault` (boolean, required): Whether this user is the connection's default user, called its service account in the app. While a connection has a default user, Rollstack reads data through the default user's access for everyone with access to the connection, instead of through their own. A connection has at most one, set with `defaultUserId` in `updateConnection`; Databricks connections can't have one. - `isActive` (boolean, required): Whether the user's access to the connection is set up and working, shown as Active or Inactive in the connection's list of users in the app. It is `false`, for example, until a Lightdash user enters their personal access token in the app, or when Rollstack couldn't connect to Tableau as that user. It is also `false` while their access is suspended. ### Add connection users `POST https://api.rollstack.com/public/v1/connections/{type}/{id}/users` Gives members of the organization access to a connection. Only its admins may. Answers the users who got access; others are skipped. Requires the `connections:write` scope. Operation ID: `addConnectionUsers`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `userIds` (array of integer, required): The members of your organization to give access to the connection, by their `id` from `listMembers`. Depending on the BI tool, some may still have to enter their own credentials in the app, such as a Lightdash personal access token, before their access works: `isActive` in the response tells you which. Members whose access was suspended get it back. Members who already have access, and ids that aren't active members of your organization, are skipped. From 1 to 100 ids. #### Response `201` Success `application/json`: array of object - `userId` (number, required): Identifies a member who got access with this request, as their `id` in `listMembers`. Members who were skipped aren't listed. - `isActive` (boolean, required): Whether the user's access to the connection is set up and working, shown as Active or Inactive in the connection's list of users in the app. It is `false`, for example, until a Lightdash user enters their personal access token in the app, or when Rollstack couldn't connect to Tableau as that user. It is also `false` while their access is suspended. ### Suspend connection user `DELETE https://api.rollstack.com/public/v1/connections/{type}/{id}/users/{userId}` Suspends a user's access to a connection. Their syncs stay but stop updating until `addConnectionUsers` gives them access again or someone takes their reports over. Only its admins may, and never for the default user. Requires the `connections:write` scope. Operation ID: `removeConnectionUser`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. - `userId` (integer, required): The member to act on, by their `id` from `listMembers`. For `removeConnectionUser`, one of the connection's users, as listed by `listConnectionUsers`. For `setConnectionAdmin`, any active member of your organization except the connection's owner. For `removeConnectionAdmin`, one of the connection's admins, as listed in `admins` by `getConnection`, except its owner. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Connection admins Who can manage a connection. A connection has one owner and any number of admins. Admins manage the connection's users; only the owner can add or remove admins, or delete the connection. Ownership moves only in the app. ### Add connection admin `PUT https://api.rollstack.com/public/v1/connections/{type}/{id}/admins/{userId}` Makes an active member an admin of a connection. Only its owner may. Requires the `connections:write` scope. Operation ID: `setConnectionAdmin`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. - `userId` (integer, required): The member to act on, by their `id` from `listMembers`. For `removeConnectionUser`, one of the connection's users, as listed by `listConnectionUsers`. For `setConnectionAdmin`, any active member of your organization except the connection's owner. For `removeConnectionAdmin`, one of the connection's admins, as listed in `admins` by `getConnection`, except its owner. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `role` (string, required): The role to give the member on the connection. Only `admin` is accepted: admins manage the connection's users and can change its settings and credentials, while only the owner can delete the connection or add and remove admins. Ownership can be transferred only in the app. Being an admin doesn't make them one of the connection's users: add them with `addConnectionUsers` too if they need access of their own. One of `admin`. #### Response `200` Success `application/json` - `userId` (number, required): The member who is now an admin of the connection, as their `id` in `listMembers`. - `role` (string, required): The member's role on the connection, always `admin` here. Admins manage the connection's users, settings and credentials. The other role, `owner`, belongs to the connection's owner, who can also delete the connection and choose its admins; it can't be given through the API. One of `owner`, `admin`. ### Remove connection admin `DELETE https://api.rollstack.com/public/v1/connections/{type}/{id}/admins/{userId}` Removes an admin of a connection. Only its owner may, and the owner's own role stays. Requires the `connections:write` scope. Operation ID: `removeConnectionAdmin`. #### Path parameters - `type` (string, required): The data source the connection reads from: `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma` or `Salesforce`, or the `Snowflake` or `Databricks` data warehouse. Endpoints that act on a connection take it in their path, with the connection's `id`. One of `Tableau`, `Looker`, `Metabase`, `PowerBI`, `Lightdash`, `Omni`, `Sigma`, `Salesforce`, `Snowflake`, `Databricks`. - `id` (string, required): Unique identifier for the connection, from `listConnections`, which also returns its `type`. - `userId` (integer, required): The member to act on, by their `id` from `listMembers`. For `removeConnectionUser`, one of the connection's users, as listed by `listConnectionUsers`. For `setConnectionAdmin`, any active member of your organization except the connection's owner. For `removeConnectionAdmin`, one of the connection's admins, as listed in `admins` by `getConnection`, except its owner. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Spreadsheets The Google Sheets and Excel files the user added in Rollstack, read with the user's own Google or Microsoft account. Rollstack sees only the files added in the app, not the user's whole Drive or OneDrive. Find a file with `searchSpreadsheets`, list its sheets with `getSpreadsheet`, then add a range of a sheet to a report with `addReportDatasheets`. ### Search spreadsheets `GET https://api.rollstack.com/public/v1/spreadsheets` The Google Sheets and Excel files the user added in the app whose name holds any word of query, in any case, most words first, at most 50. Rollstack can't search the user's whole Google Drive or OneDrive: for another file, ask the user to add it in the app. Confirm the file with the user, then list its sheets with getSpreadsheet. Requires the `connections:read` scope. Operation ID: `searchSpreadsheets`. #### Query parameters - `query` (string): Words to search for in names, separated by spaces: a dashboard, table, model or spreadsheet is returned when its name contains any of them, case-insensitively, a table's full name with its database and schema. If omitted, results aren't filtered by name. At most 50 results are returned either way. Example: `revenue`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the spreadsheet in Rollstack, not the file's id in Google Drive, OneDrive or SharePoint. Pass it as `id` to `getSpreadsheet` to list its sheets, and as `spreadsheetId` to `addReportDatasheets`. - `name` (string, required): The spreadsheet's name, as it was when the file was added to Rollstack: renaming the file afterwards in Google Sheets or Excel doesn't change it here. `searchSpreadsheets` matches `query` against it. - `type` (string, required): Which app the spreadsheet belongs to, and so which of your accounts Rollstack reads it with. `GoogleSheet` is a Google Sheets file, read with your Google account. `MicrosoftExcel` is an Excel workbook in OneDrive or SharePoint, read with your Microsoft account. Excel files stored in Google Drive aren't available through the API. One of `GoogleSheet`, `MicrosoftExcel`. - `url` (string, required): Link that opens the spreadsheet in Google Sheets or in Excel for the web, for example to check it's the right file before you add it to a report. ### Get spreadsheet `GET https://api.rollstack.com/public/v1/spreadsheets/{id}` A Google Sheets or Excel file the user added in the app, with its sheets, read with the user's own Google or Microsoft account. Fails with user-missing-oauth when the user hasn't connected that account in the app. Find the file's id with searchSpreadsheets, then add a range of one of its sheets to a report with addReportDatasheets by the sheet's id. Requires the `connections:read` scope. Operation ID: `getSpreadsheet`. #### Path parameters - `id` (string, required): The spreadsheet whose sheets to list, by its `id` from `searchSpreadsheets`. This is Rollstack's identifier, not the file's id in Google Drive, OneDrive or SharePoint. It must be one of your own spreadsheets in Rollstack: another member's spreadsheet returns `404`, as does an Excel file stored in Google Drive. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the spreadsheet in Rollstack, not the file's id in Google Drive, OneDrive or SharePoint. Pass it as `id` to `getSpreadsheet` to list its sheets, and as `spreadsheetId` to `addReportDatasheets`. - `name` (string, required): The spreadsheet's name, as it was when the file was added to Rollstack: renaming the file afterwards in Google Sheets or Excel doesn't change it here. `searchSpreadsheets` matches `query` against it. - `type` (string, required): Which app the spreadsheet belongs to, and so which of your accounts Rollstack reads it with. `GoogleSheet` is a Google Sheets file, read with your Google account. `MicrosoftExcel` is an Excel workbook in OneDrive or SharePoint, read with your Microsoft account. Excel files stored in Google Drive aren't available through the API. One of `GoogleSheet`, `MicrosoftExcel`. - `url` (string, required): Link that opens the spreadsheet in Google Sheets or in Excel for the web, for example to check it's the right file before you add it to a report. - `sheets` (array of object, required): The sheets (tabs) in the spreadsheet as they are now in Google Sheets or Excel, hidden ones included. Pass a sheet's `id` as `sheetId` to `addReportDatasheets` to add a range of its cells to a report. - `id` (string, required): Unique identifier for the sheet within the spreadsheet. Pass it as `sheetId` to `addReportDatasheets`, with the spreadsheet's `id` as `spreadsheetId` and the cells to read as `range`. In Google Sheets, it is the number after `gid=` in the sheet's URL. - `title` (string, required): The sheet's name, as shown on its tab in Google Sheets or Excel. ## SMTP connections The SMTP connections report emails go out through: an SMTP login or a Google or Microsoft account. A connection is the user's own, or shared with the whole organization by an owner or admin. Pick one in Email settings for a report. Credentials are write-only and checked with a test email before the connection is saved. ### List SMTP connections `GET https://api.rollstack.com/public/v1/smtp-connections` The user's SMTP connections and the ones shared with the organization, without their credentials. Requires the `smtp:read` scope. Operation ID: `listSmtpConnections`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the SMTP connection. Pass it as `smtpServerId` to `updateReportEmailConfig` to send a report's emails through it, or as `id` to `deleteSmtpConnection`. - `from` (string, required): The sender address report emails sent through this connection go out from, as `email@domain.com` or `Name `. - `type` (string, required): How the connection sends report emails. `login` signs in to an SMTP server with a username and password (see `host`, `port` and `username`). `oauth2` sends through a Google or Microsoft account its owner connected to Rollstack (see `service`), with no password stored, and only while that account stays connected with permission to send email. One of `login`, `oauth2`. - `service` (string or null, required): Which account or server the connection sends through: - `gmail`: Gmail, from the owner's Google account with the same email as their Rollstack account. - `gmail_oauth`: Gmail, from another Google account the owner connected for sending. - `outlook`: Outlook, from the owner's Microsoft account. - `manual`: an SMTP server set up by hand with `host`, `port`, `username` and a password (`type` `login`). - `resend`: Rollstack's own sending service, which report emails use when no connection is chosen. No connection created in the app or the API has it. `null` when no service is recorded; the app shows such a connection as Manual. One of `gmail_oauth`, `gmail`, `outlook`, `resend`, `manual`. - `host` (string or null, required): The address of the SMTP server a `login` connection signs in to, such as `smtp.acme.com`. `null` for an `oauth2` connection, which sends through a Google or Microsoft account rather than an SMTP server. - `port` (number or null, required): The port Rollstack connects to on the SMTP server of a `login` connection. `null` for an `oauth2` connection. - `username` (string or null, required): For a `login` connection, the username Rollstack signs in to the SMTP server with. For an `oauth2` connection, the email address recorded when it was created; emails go out through the account `service` points to, which for `gmail_oauth` may be another of the owner's connected Google accounts. Never `null` on connections created in the app or the API. - `organizationShared` (boolean, required): Whether the connection is shared with the organization. When `true`, every member can choose it as the sender of their reports' emails, which then go out through the owner's account or server login. When `false`, only the owner can choose it. A shared connection can't be deleted until an owner or admin unshares it in the app. - `ownerUserId` (number, required): The member who added the connection and owns it, as their `id` in `listMembers`; your own connections carry your `id` from `getMe`. Only the owner can delete the connection, and an `oauth2` connection sends through the owner's account. - `createdAt` (string (date-time), required): When the connection was added. `listSmtpConnections` lists the newest first. ### Create SMTP connection `POST https://api.rollstack.com/public/v1/smtp-connections` Adds an SMTP connection after sending a test email through it. Only owners and admins may share it with the organization. Requires the `smtp:write` scope. Operation ID: `createSmtpConnection`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - When `type` is `oauth2` - `type` (`oauth2`, required): Set to `oauth2` to send report emails through a Google or Microsoft account you connected to Rollstack, chosen with `service`, rather than through an SMTP server. Rollstack stores no password for it, and the connection sends only while that account stays connected with permission to send email. - `service` (string, required): Which of your accounts sends the emails. `gmail` is Gmail, from the Google account with the same email as your Rollstack account. `gmail_oauth` is Gmail, from another Google account you connected for sending. `outlook` is Outlook, from your Microsoft account. The account must already be connected with permission to send email, under Settings > Connected apps > Sending email in the app, or creating the connection fails. Connecting an account there already creates an SMTP connection for it, which `listSmtpConnections` returns. One of `gmail`, `outlook`, `gmail_oauth`. - `username` (string, required): The email address of the Google or Microsoft account the connection is for, recorded to tell your connections apart. It doesn't choose the account that sends: emails go out through the account `service` points to, and with `gmail_oauth` and several Google accounts connected for sending, that may not be this one. If you already have a connection with the same `service` and `username`, Rollstack returns it instead of creating another, keeping its `from`; with `organizationSmtpConfig` `true`, it also shares it. Example: `reports@acme.com`. - `from` (string, required): The sender address report emails sent through this connection go out from, as `email@domain.com` or `Name `. Rollstack sends a test email from it before saving the connection; if that email fails, the connection isn't created. Example: `Acme Reports `. - `organizationSmtpConfig` (boolean): Whether to share the connection with your organization, so every member can choose it as the sender of their reports' emails; their emails then go out through your account or server login. Only owners and admins can share a connection: anyone else passing `true` gets a `403`. If omitted or `false`, only you can choose it as a sender. - When `type` is `login` - `type` (`login`, required): Set to `login` to send report emails through an SMTP server that Rollstack signs in to with `username` and `password`, such as your company's mail server or an email provider's SMTP service. - `service` (string, required): Always `manual`: the SMTP server is set up by hand with `host`, `port`, `username` and `password`, like the Manual option in the app. One of `manual`. - `host` (string, required): The address of the SMTP server to send through, as your email provider or IT team gives it. Example: `smtp.acme.com`. - `port` (number, required): The port Rollstack connects to on the SMTP server. Rollstack starts TLS as soon as it connects (implicit TLS, usually on port `465`), so the server must accept TLS on that port from the start, not only after STARTTLS. One of `25`, `465`, `587`, `2525`. - `username` (string, required): The username Rollstack signs in to the SMTP server with, often the mailbox's email address. Example: `reports@acme.com`. - `password` (string, required): The password Rollstack signs in to the SMTP server with. For a Gmail or Outlook mailbox, this is usually an app password. The API never returns it. Example: `your-smtp-password`. - `from` (string, required): The sender address report emails sent through this connection go out from, as `email@domain.com` or `Name `. Rollstack sends a test email from it before saving the connection; if that email fails, the connection isn't created. Example: `Acme Reports `. - `organizationSmtpConfig` (boolean): Whether to share the connection with your organization, so every member can choose it as the sender of their reports' emails; their emails then go out through your account or server login. Only owners and admins can share a connection: anyone else passing `true` gets a `403`. If omitted or `false`, only you can choose it as a sender. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the SMTP connection. Pass it as `smtpServerId` to `updateReportEmailConfig` to send a report's emails through it, or as `id` to `deleteSmtpConnection`. - `from` (string, required): The sender address report emails sent through this connection go out from, as `email@domain.com` or `Name `. - `type` (string, required): How the connection sends report emails. `login` signs in to an SMTP server with a username and password (see `host`, `port` and `username`). `oauth2` sends through a Google or Microsoft account its owner connected to Rollstack (see `service`), with no password stored, and only while that account stays connected with permission to send email. One of `login`, `oauth2`. - `service` (string or null, required): Which account or server the connection sends through: - `gmail`: Gmail, from the owner's Google account with the same email as their Rollstack account. - `gmail_oauth`: Gmail, from another Google account the owner connected for sending. - `outlook`: Outlook, from the owner's Microsoft account. - `manual`: an SMTP server set up by hand with `host`, `port`, `username` and a password (`type` `login`). - `resend`: Rollstack's own sending service, which report emails use when no connection is chosen. No connection created in the app or the API has it. `null` when no service is recorded; the app shows such a connection as Manual. One of `gmail_oauth`, `gmail`, `outlook`, `resend`, `manual`. - `host` (string or null, required): The address of the SMTP server a `login` connection signs in to, such as `smtp.acme.com`. `null` for an `oauth2` connection, which sends through a Google or Microsoft account rather than an SMTP server. - `port` (number or null, required): The port Rollstack connects to on the SMTP server of a `login` connection. `null` for an `oauth2` connection. - `username` (string or null, required): For a `login` connection, the username Rollstack signs in to the SMTP server with. For an `oauth2` connection, the email address recorded when it was created; emails go out through the account `service` points to, which for `gmail_oauth` may be another of the owner's connected Google accounts. Never `null` on connections created in the app or the API. - `organizationShared` (boolean, required): Whether the connection is shared with the organization. When `true`, every member can choose it as the sender of their reports' emails, which then go out through the owner's account or server login. When `false`, only the owner can choose it. A shared connection can't be deleted until an owner or admin unshares it in the app. - `ownerUserId` (number, required): The member who added the connection and owns it, as their `id` in `listMembers`; your own connections carry your `id` from `getMe`. Only the owner can delete the connection, and an `oauth2` connection sends through the owner's account. - `createdAt` (string (date-time), required): When the connection was added. `listSmtpConnections` lists the newest first. ### Delete SMTP connection `DELETE https://api.rollstack.com/public/v1/smtp-connections/{id}` Deletes one of your SMTP connections. One shared with the organization must be unshared in the app first. Requires the `smtp:write` scope. Operation ID: `deleteSmtpConnection`. #### Path parameters - `id` (string, required): The SMTP connection to delete, by its `id` from `listSmtpConnections`. It must be one you added: another member's connection returns `404`, even when shared with the organization. Reports set to send through it then send their emails from Rollstack instead. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Folders The folders that organize reports, as nested in the app. Each folder answers the permission the user has on it: `view`, `edit` or `manage`. Sharing a folder gives access to everything in it, including the folders nested in it. Pass a folder id as `folderId` to list the reports in it, or to create or move a report into it. To file reports, create a folder with `createFolder`, then move each report into it with `updateReport`. Rename or move a folder with `updateFolder`, See who it is shared with in `getFolder`, and change it with `shareFolder` and `unshareFolder`. ### List folders `GET https://api.rollstack.com/public/v1/folders` The folders the user can see, each with its parent, null at the top level, and the user's permission on it: null, view, edit or manage. Pass a folder's id as folderId to listReports or createReport, or to getFolder to see who it's shared with. Requires the `slide_decks:read` scope. Operation ID: `listFolders`. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the folder. Pass it as `folderId` to `listReports` to list the reports in it, or to `createReport` or `updateReport` to put a report in it. - `name` (string, required): The folder's name, as shown in Rollstack. - `parentFolderId` (string or null, required): The folder this one is nested in. `null` for a folder at the top level. The parent is missing from the list when you can see this folder but not its parent. - `permission` (string or null, required): What you can do in the folder. `view` lets you open the reports in it, `edit` also lets you change them, and `manage` also lets you share the folder and change who has access to it. It is the highest of what the folder is shared with you directly and what you get from the folders it is nested in, where owning one of those gives `manage`. `null` when you own the folder and get nothing from a parent folder, as with a top-level folder you created: as its owner, you can do everything in it. One of `view`, `edit`, `manage`. ### Create folder `POST https://api.rollstack.com/public/v1/folders` Creates a folder owned by the user: at the top level, which only owners and admins of the organization may, or inside a folder the user owns or has manage on. Then file reports in it with updateReport's folderId, or create them there with createReport. Each call creates another folder, even with the same name. Requires the `slide_decks:write` scope. Operation ID: `createFolder`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string, required): The folder's name, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. Example: `Q3 business reviews`. - `parentFolderId` (string or null): The folder to create it in, by its `id` from `listFolders`: one you own or have `manage` on. Omit it or pass `null` to create it at the top level, which only owners and admins of the organization may. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. #### Response `201` Success `application/json` - `id` (string, required): Unique identifier for the folder. - `name` (string, required): The folder's name, as shown in Rollstack. - `parentFolderId` (string or null, required): The folder this one is nested in. `null` for a folder at the top level. - `permission` (string or null, required): What you can do in the folder: `view`, `edit` or `manage`, as in `listFolders`. `manage` when you own it. `null` when you see it only because a report in it is shared with you. One of `view`, `edit`, `manage`. - `access` (array of object, required): Everyone with access to the folder, the owner first. - `userId` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `permission` (string, required): What they can do in the folder. The owner has `manage`. One of `view`, `edit`, `manage`. - `source` (string, required): `owner` for the member who owns the folder, `direct` when it is shared with them, `folder` when they reach it through a folder it is nested in, which `unshareFolder` on this folder leaves as it is. One of `owner`, `direct`, `folder`. - `folder` (string): With `folder`: the name of the parent folder they reach it through, when you can see that folder. ### Get folder `GET https://api.rollstack.com/public/v1/folders/{id}` A folder the user can see, with its parent and everyone who has access to it: its owner, the members it is shared with directly, and those who reach it through the folder it is nested in, each with their permission. Requires the `slide_decks:read` scope. Operation ID: `getFolder`. #### Path parameters - `id` (string, required): The folder to act on, by its `id` from `listFolders` or `createFolder`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the folder. - `name` (string, required): The folder's name, as shown in Rollstack. - `parentFolderId` (string or null, required): The folder this one is nested in. `null` for a folder at the top level. - `permission` (string or null, required): What you can do in the folder: `view`, `edit` or `manage`, as in `listFolders`. `manage` when you own it. `null` when you see it only because a report in it is shared with you. One of `view`, `edit`, `manage`. - `access` (array of object, required): Everyone with access to the folder, the owner first. - `userId` (number, required): The member's user id, the same as their `id` in `listMembers`. - `name` (string, required): The member's name, as shown in Rollstack. - `email` (string, required): The member's email address. - `permission` (string, required): What they can do in the folder. The owner has `manage`. One of `view`, `edit`, `manage`. - `source` (string, required): `owner` for the member who owns the folder, `direct` when it is shared with them, `folder` when they reach it through a folder it is nested in, which `unshareFolder` on this folder leaves as it is. One of `owner`, `direct`, `folder`. - `folder` (string): With `folder`: the name of the parent folder they reach it through, when you can see that folder. ### Update folder `PATCH https://api.rollstack.com/public/v1/folders/{id}` Renames a folder, or moves it into another folder or to the top level, with everything in it. Members of the folder it moves into get access to its reports. Needs manage on the folder, or owning it, and the same on the one it moves into. Answers the name and parent of the folder: getFolder gives who has access. Requires the `slide_decks:write` scope. Operation ID: `updateFolder`. #### Path parameters - `id` (string, required): The folder to act on, by its `id` from `listFolders` or `createFolder`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): The folder's name, as members will see it in Rollstack. Leading and trailing spaces are removed, and it can't be blank. Example: `Q3 business reviews`. - `parentFolderId` (string or null): The folder to move it into, by its `id` from `listFolders`, one you own or have `manage` on, and not the folder itself or one nested in it. Pass `null` to move it to the top level. Its reports, bursts and subfolders move with it. Example: `a3d5e7f9-1b2c-4d6e-8f0a-1b2c3d4e5f6a`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the folder. - `name` (string, required): The folder's name, as shown in Rollstack. - `parentFolderId` (string or null, required): The folder this one is nested in. `null` for a folder at the top level. ### Delete folder `DELETE https://api.rollstack.com/public/v1/folders/{id}` Deletes a folder, as Delete in the app does: its reports, bursts and subfolders stay and show at the top level. Only its owner may. Requires the `slide_decks:write` scope. Operation ID: `deleteFolder`. #### Path parameters - `id` (string, required): The folder to act on, by its `id` from `listFolders` or `createFolder`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ### Share folder `PUT https://api.rollstack.com/public/v1/folders/{id}/shares/{userId}` Shares a folder and everything in it with a member of the organization, or changes their permission, as Share in the app does. A member new to the folder gets an email. Needs manage on the folder, or owning it. Requires the `slide_decks:write` scope. Operation ID: `shareFolder`. #### Path parameters - `id` (string, required): The folder to act on, by its `id` from `listFolders` or `createFolder`. - `userId` (integer, required): The member to share the folder with, or to unshare it from: their `id` from `listMembers`, which only owners and admins can call, or their `userId` in `access` from `getFolder`. Only active members of the organization. Anyone the folder is shared with can unshare it from themselves. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `permission` (string, required): What the member can do with the folder and everything in it. `view` lets them open its reports, `edit` also lets them change them, and `manage` also lets them rename, move and share the folder and add folders to it. If the folder is already shared with the member, this replaces their permission and they aren't notified again. Rollstack also shares the files of its reports that update a Google Drive or OneDrive file with them, as the app does. One of `view`, `edit`, `manage`. #### Response `200` Success `application/json` - `userId` (number, required): The member the folder is now shared with: the `userId` from the path. - `permission` (string, required): What the member can now do with the folder: the `permission` you sent. One of `view`, `edit`, `manage`. ### Unshare folder `DELETE https://api.rollstack.com/public/v1/folders/{id}/shares/{userId}` Removes a member's direct share of a folder, and their access to its reports' files in Drive unless they still reach the folder through a parent folder, as the app does. Access through a parent folder stays: unshare that folder instead. Needs manage on the folder, or owning it, except to unshare it from yourself. Requires the `slide_decks:write` scope. Operation ID: `unshareFolder`. #### Path parameters - `id` (string, required): The folder to act on, by its `id` from `listFolders` or `createFolder`. - `userId` (integer, required): The member to share the folder with, or to unshare it from: their `id` from `listMembers`, which only owners and admins can call, or their `userId` in `access` from `getFolder`. Only active members of the organization. Anyone the folder is shared with can unshare it from themselves. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Organization The API key's organization and its settings: its name and default timezone, the email domains members may be invited from, how reports update and link to their sources, and which features are on, such as insights, memories, spreadsheets and email analytics. Anyone with `organization:read` can read the settings. Changing them needs `organization:write`, which only owners and admins can grant a key. ### Get organization `GET https://api.rollstack.com/public/v1/organization` The API key's organization and its settings: its name and default timezone, the email domains members may be invited from, how reports update and link to their sources, and which features are on. Requires the `organization:read` scope. Operation ID: `getOrganization`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the organization: the same `id` that `getMe` returns in `organization`. - `name` (string, required): The organization's name, as shown in Rollstack. - `timezone` (string or null, required): The organization's default timezone for reports. Reports created while it is set, including with `createReport`, start with it as their `timezone`; changing it doesn't change the `timezone` of existing reports. For reports that update a file in your drive, such as Google Slides presentations, it also replaces each report's own timezone for its date variables. `null` means no default. An IANA timezone name, such as `America/New_York`. - `allowedDomains` (array of string or null, required): The organization's domain allowlist, such as `acme.com`: the email domains people can be invited to the organization from. While it is empty or `null`, invites from the app aren't limited by domain, but `createInvites` fails with `invites-require-allowed-domains`. Owners and admins edit it in the organization settings in Rollstack; the API can't change it. A domain matches exactly, ignoring case, so `acme.com` doesn't cover `eu.acme.com`. - `updateMethod` (string or null, required): How reports that update a file in your drive, such as Google Slides or PowerPoint presentations, change that file when they run. The reports this API manages don't use it. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original; runs that update only some of the report's visualizations skip the copy. `updateVisualizations` is the method email reports are created with; the app doesn't offer it as an organization setting. While set, every such report uses it instead of its own update method; `null` lets each report use its own. One of `update`, `archive`, `updateVisualizations`. - `linkOption` (string or null, required): Where a click on a visualization's image leads, in reports that update a file in your drive, such as Google Slides presentations. The reports this API manages don't use it. `rollstack` opens the visualization's page in Rollstack, `external` opens the dashboard or spreadsheet it comes from, and `nolink` leaves images without a link. While set, every such report uses it instead of its own link option; `null` lets each report use its own. One of `nolink`, `rollstack`, `external`. - `llmProvider` (string, required): The AI provider Rollstack tries first when it writes the organization's Insights, such as `openai`, `azure_openai` or `amazon_bedrock`; another provider may write them as a fallback. It isn't the custom LLM provider the slides agent runs on, which `getLLMProvider` returns. The API can't change it. `custom_provider` is a legacy value. One of `openai`, `azure_openai`, `google_gemini`, `amazon_bedrock`, `google_ai_studio`, `google_vertex_ai`, `anthropic`, `custom_provider`. - `insightsEnabled` (boolean, required): Whether the organization's reports can have Insights: AI-written commentary on the data in a report's visualizations. While off, no one can add or edit Insights, and runs leave existing ones unchanged. - `memoriesEnabled` (boolean, required): Whether members can use AI Memories: personal notes the AI draws on when it writes their Insights, such as to write large numbers with K, M or B. Each member keeps theirs, grouped in profiles, on the Insight Memories settings page, which is hidden while AI Memories are off. - `spreadsheetsEnabled` (boolean, required): Whether Rollstack offers Google Sheets and Microsoft Excel spreadsheets as data sources. While off, the app no longer offers them when someone adds a data source. Only the app checks this setting. - `emailAnalyticsEnabled` (boolean, required): Whether Rollstack can track when report emails are opened. While on, a report's emails are tracked once its email settings turn email analytics on (`emailAnalyticsEnabled`). While off, no report email is tracked, whatever its settings say. ### Update organization `PATCH https://api.rollstack.com/public/v1/organization` Changes the API key's organization settings. Send only the fields to change, at least one; null clears the timezone, update method or link option. Requires the `organization:write` scope. Only owners and admins of the organization may call it. Operation ID: `updateOrganization`. Only owners and admins can call it. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `name` (string): The organization's new name, as shown to its members in Rollstack. Example: `Acme`. - `timezone` (string or null): The organization's default timezone for reports. Reports created while it is set, including with `createReport`, start with it as their `timezone`; changing it doesn't change the `timezone` of existing reports. For reports that update a file in your drive, such as Google Slides presentations, it also replaces each report's own timezone for its date variables. `null` means no default. An IANA timezone name, such as `America/New_York`. Example: `America/New_York`. - `updateMethod` (string or null): How reports that update a file in your drive, such as Google Slides or PowerPoint presentations, change that file when they run. The reports this API manages don't use it. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original; runs that update only some of the report's visualizations skip the copy. `updateVisualizations` is the method email reports are created with; the app doesn't offer it as an organization setting. While set, every such report uses it instead of its own update method; `null` lets each report use its own. One of `update`, `archive`, `updateVisualizations`. - `linkOption` (string or null): Where a click on a visualization's image leads, in reports that update a file in your drive, such as Google Slides presentations. The reports this API manages don't use it. `rollstack` opens the visualization's page in Rollstack, `external` opens the dashboard or spreadsheet it comes from, and `nolink` leaves images without a link. While set, every such report uses it instead of its own link option; `null` lets each report use its own. One of `nolink`, `rollstack`, `external`. - `insightsEnabled` (boolean): Whether the organization's reports can have Insights: AI-written commentary on the data in a report's visualizations. While off, no one can add or edit Insights, and runs leave existing ones unchanged. Only owners can change it, not admins. - `restrictInsightUsers` (boolean): Whether only the members you pick can use Insights, rather than everyone in the organization. Pick them with each member's `insightsEnabled` in `updateMember`. `getOrganization` doesn't return this setting. Only owners can change it, not admins. - `memoriesEnabled` (boolean): Whether members can use AI Memories: personal notes the AI draws on when it writes their Insights, such as to write large numbers with K, M or B. Each member keeps theirs, grouped in profiles, on the Insight Memories settings page, which is hidden while AI Memories are off. Only owners can change it, not admins. - `spreadsheetsEnabled` (boolean): Whether Rollstack offers Google Sheets and Microsoft Excel spreadsheets as data sources. While off, the app no longer offers them when someone adds a data source. Only the app checks this setting. Only owners can change it, not admins. - `emailAnalyticsEnabled` (boolean): Whether Rollstack can track when report emails are opened. While on, a report's emails are tracked once its email settings turn email analytics on (`emailAnalyticsEnabled`). While off, no report email is tracked, whatever its settings say. Only owners can change it, not admins. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the organization: the same `id` that `getMe` returns in `organization`. - `name` (string, required): The organization's name, as shown in Rollstack. - `timezone` (string or null, required): The organization's default timezone for reports. Reports created while it is set, including with `createReport`, start with it as their `timezone`; changing it doesn't change the `timezone` of existing reports. For reports that update a file in your drive, such as Google Slides presentations, it also replaces each report's own timezone for its date variables. `null` means no default. An IANA timezone name, such as `America/New_York`. - `allowedDomains` (array of string or null, required): The organization's domain allowlist, such as `acme.com`: the email domains people can be invited to the organization from. While it is empty or `null`, invites from the app aren't limited by domain, but `createInvites` fails with `invites-require-allowed-domains`. Owners and admins edit it in the organization settings in Rollstack; the API can't change it. A domain matches exactly, ignoring case, so `acme.com` doesn't cover `eu.acme.com`. - `updateMethod` (string or null, required): How reports that update a file in your drive, such as Google Slides or PowerPoint presentations, change that file when they run. The reports this API manages don't use it. `update` updates the same file with the latest data. `archive` first saves a copy of the file, named with the date of its previous run, then updates the original; runs that update only some of the report's visualizations skip the copy. `updateVisualizations` is the method email reports are created with; the app doesn't offer it as an organization setting. While set, every such report uses it instead of its own update method; `null` lets each report use its own. One of `update`, `archive`, `updateVisualizations`. - `linkOption` (string or null, required): Where a click on a visualization's image leads, in reports that update a file in your drive, such as Google Slides presentations. The reports this API manages don't use it. `rollstack` opens the visualization's page in Rollstack, `external` opens the dashboard or spreadsheet it comes from, and `nolink` leaves images without a link. While set, every such report uses it instead of its own link option; `null` lets each report use its own. One of `nolink`, `rollstack`, `external`. - `llmProvider` (string, required): The AI provider Rollstack tries first when it writes the organization's Insights, such as `openai`, `azure_openai` or `amazon_bedrock`; another provider may write them as a fallback. It isn't the custom LLM provider the slides agent runs on, which `getLLMProvider` returns. The API can't change it. `custom_provider` is a legacy value. One of `openai`, `azure_openai`, `google_gemini`, `amazon_bedrock`, `google_ai_studio`, `google_vertex_ai`, `anthropic`, `custom_provider`. - `insightsEnabled` (boolean, required): Whether the organization's reports can have Insights: AI-written commentary on the data in a report's visualizations. While off, no one can add or edit Insights, and runs leave existing ones unchanged. - `memoriesEnabled` (boolean, required): Whether members can use AI Memories: personal notes the AI draws on when it writes their Insights, such as to write large numbers with K, M or B. Each member keeps theirs, grouped in profiles, on the Insight Memories settings page, which is hidden while AI Memories are off. - `spreadsheetsEnabled` (boolean, required): Whether Rollstack offers Google Sheets and Microsoft Excel spreadsheets as data sources. While off, the app no longer offers them when someone adds a data source. Only the app checks this setting. - `emailAnalyticsEnabled` (boolean, required): Whether Rollstack can track when report emails are opened. While on, a report's emails are tracked once its email settings turn email analytics on (`emailAnalyticsEnabled`). While off, no report email is tracked, whatever its settings say. ## Members Members of the organization, their roles and access. A member's role is `owner`, `admin` or `member`; their authentication role, `viewer` or `editor`, lets them see or change the organization's SSO settings. Call `GET /me` first to check a key works: it answers the user the key acts as, the organization it belongs to, the role it acts with and the scopes it carries, with any valid key, whatever its scopes. Only owners and admins may call the other endpoints, with a key carrying `users:read` or `users:write`. A key can make a member an admin or a member, never an owner. Deactivating a member removes them from the organization, revokes their API keys and deletes their invites; reactivating them brings them back, but not their keys. ### Get current user `GET https://api.rollstack.com/public/v1/me` The user and API key making the request: the user's id, name and email, the organization the key belongs to with the role the key acts with, and the key's id and scopes. Call it to check that a key works. Works with any valid API key. Operation ID: `getMe`. #### Response `200` Success `application/json` - `id` (number, required): Unique identifier for the user the API key belongs to: the same `id` that `listMembers` returns for them. - `email` (string, required): The email address of the user the API key belongs to. - `name` (string, required): The name of the user the API key belongs to, as shown in Rollstack. - `organization` (object, required): The organization the API key belongs to. A key works only in the organization it was created in. - `id` (string, required): Unique identifier for the organization: the same `id` that `getOrganization` returns. - `name` (string, required): The organization's name, as shown in Rollstack. - `role` (string, required): The role the API key acts with in the organization, which limits what it can do on top of its scopes. As an `owner` or `admin`, the key can call the endpoints limited to owners and admins, but only as an `owner` can it turn the organization's features on or off or change who can access its Authentication settings. As a `member`, it can do neither. It is the user's current role, but never higher than the one they had when the key was created or its scopes were last edited, so promoting the user doesn't raise it. One of `owner`, `admin`, `member`. - `apiKey` (object, required): The API key that made the request. - `id` (string, required): Unique identifier for the API key that made the request. It identifies the key without revealing its secret. - `scopes` (array of string, required): The scopes the API key carries, which decide the endpoints it can call: each endpoint states the scope it needs, and the Scopes section of the introduction lists what each one allows. While the key acts as a `member`, it loses `users:read`, `users:write` and `organization:write`, the scopes only owners and admins may grant, even if it was created with them. ### List members `GET https://api.rollstack.com/public/v1/members` The members of the organization, with their role, authentication role, insights access and whether they are active. Optionally only those with a status, active or deactivated, or with an email. Requires the `users:read` scope. Only owners and admins of the organization may call it. Operation ID: `listMembers`. Only owners and admins can call it. #### Query parameters - `status` (string): Only return `active` members, or only `deactivated` ones. If omitted, returns both. One of `active`, `deactivated`. - `email` (string): Only return the member with exactly this email address, ignoring case. Returns an empty list if no member has it, or if they don't match `status`. Example: `jane@acme.com`. #### Response `200` Success `application/json`: array of object - `id` (number, required): Unique identifier for the member. Pass it as `userId` to `updateMember`, `deactivateMember` or `reactivateMember`. - `email` (string, required): The email address of the member's Rollstack account. - `name` (string, required): The member's name, as shown in Rollstack. - `role` (string, required): The member's role in the organization. `owner` can do everything, including turning the organization's features on or off, choosing who can access its Authentication settings and, in the app, making other members owners. `admin` manages the organization's settings, members and invites, but can't turn features such as Insights or email analytics on or off, or change, deactivate or reactivate owners. `member` uses Rollstack without managing the organization. One of `owner`, `admin`, `member`. - `authenticationRole` (string or null, required): The member's access to the organization's Authentication settings, where Single Sign-On (SSO) and SCIM provisioning are set up: `viewer` can see them, `editor` can also change them, and `null` gives no access. Owners always have full access, whatever this value. One of `viewer`, `editor`. - `insightsEnabled` (boolean, required): Whether the member can use Insights while the organization restricts them to the members it picks (`restrictInsightUsers` in `updateOrganization`). It has no effect while Insights are open to every member or turned off. - `status` (string, required): Whether the member has access to the organization. `active` members do. `deactivated` members were removed from it, which revoked their API keys; `reactivateMember` restores their access, but not their keys. One of `active`, `deactivated`. - `deactivatedAt` (string (date-time) or null, required): When the member was deactivated. `null` while they're active. - `deactivationReason` (string or null, required): Why the member was deactivated: the reason an admin gave, or `sso_deprovisioned` when SSO removed them. `null` while they're active, or when no reason was given. One of `left_company`, `no_longer_needs_access`, `not_using_enough`, `too_expensive`, `switching_tool`, `duplicate_account`, `sso_deprovisioned`, `other`. - `deactivationReasonDetails` (string or null, required): What the admin wrote when `deactivationReason` is `other`. `null` otherwise. ### Update member `PATCH https://api.rollstack.com/public/v1/members/{userId}` Changes a member's role, authentication role or insights access. Send only the fields to change, at least one. The role can be admin or member: a key never makes anyone an owner. Requires the `users:write` scope. Only owners and admins of the organization may call it. Operation ID: `updateMember`. Only owners and admins can call it. #### Path parameters - `userId` (integer, required): The member to act on, by the `id` from `listMembers`. An id that is not a member of the organization returns `user-not-in-organization`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `role` (string): The member's new role: `admin` to let them manage the organization's settings, members and invites, or `member` to take that away. A key can't make anyone an owner, admins can't change an owner's role, and you can't change your own. One of `admin`, `member`. - `authenticationRole` (string or null): The member's access to the organization's Authentication settings, where Single Sign-On (SSO) and SCIM provisioning are set up: `viewer` can see them, `editor` can also change them, and `null` gives no access. Owners always have full access, whatever this value. Only owners can change it, not admins. One of `viewer`, `editor`. - `insightsEnabled` (boolean): Whether the member can use Insights while the organization restricts them to the members it picks (`restrictInsightUsers` in `updateOrganization`). It has no effect while Insights are open to every member or turned off. #### Response `200` Success `application/json` - `id` (number, required): Unique identifier for the member. Pass it as `userId` to `updateMember`, `deactivateMember` or `reactivateMember`. - `email` (string, required): The email address of the member's Rollstack account. - `name` (string, required): The member's name, as shown in Rollstack. - `role` (string, required): The member's role in the organization. `owner` can do everything, including turning the organization's features on or off, choosing who can access its Authentication settings and, in the app, making other members owners. `admin` manages the organization's settings, members and invites, but can't turn features such as Insights or email analytics on or off, or change, deactivate or reactivate owners. `member` uses Rollstack without managing the organization. One of `owner`, `admin`, `member`. - `authenticationRole` (string or null, required): The member's access to the organization's Authentication settings, where Single Sign-On (SSO) and SCIM provisioning are set up: `viewer` can see them, `editor` can also change them, and `null` gives no access. Owners always have full access, whatever this value. One of `viewer`, `editor`. - `insightsEnabled` (boolean, required): Whether the member can use Insights while the organization restricts them to the members it picks (`restrictInsightUsers` in `updateOrganization`). It has no effect while Insights are open to every member or turned off. - `status` (string, required): Whether the member has access to the organization. `active` members do. `deactivated` members were removed from it, which revoked their API keys; `reactivateMember` restores their access, but not their keys. One of `active`, `deactivated`. - `deactivatedAt` (string (date-time) or null, required): When the member was deactivated. `null` while they're active. - `deactivationReason` (string or null, required): Why the member was deactivated: the reason an admin gave, or `sso_deprovisioned` when SSO removed them. `null` while they're active, or when no reason was given. One of `left_company`, `no_longer_needs_access`, `not_using_enough`, `too_expensive`, `switching_tool`, `duplicate_account`, `sso_deprovisioned`, `other`. - `deactivationReasonDetails` (string or null, required): What the admin wrote when `deactivationReason` is `other`. `null` otherwise. ### Deactivate member `POST https://api.rollstack.com/public/v1/members/{userId}/deactivate` Deactivates a member, revokes their API keys and deletes their invites. Send the reason when you know it, so admins see why in the members list. Requires the `users:write` scope. Only owners and admins of the organization may call it. Operation ID: `deactivateMember`. Only owners and admins can call it. #### Path parameters - `userId` (integer, required): The member to act on, by the `id` from `listMembers`. An id that is not a member of the organization returns `user-not-in-organization`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body `application/json` - `reason` (string, required): Why the member is deactivated. `other` needs `reasonDetails`. One of `left_company`, `no_longer_needs_access`, `not_using_enough`, `too_expensive`, `switching_tool`, `duplicate_account`, `other`. - `reasonDetails` (string): Why the member is deactivated, in your words. Required and kept only when `reason` is `other`. #### Response `204` Success, no content ### Reactivate member `POST https://api.rollstack.com/public/v1/members/{userId}/reactivate` Reactivates a deactivated member. Their revoked API keys stay revoked. Requires the `users:write` scope. Only owners and admins of the organization may call it. Operation ID: `reactivateMember`. Only owners and admins can call it. #### Path parameters - `userId` (integer, required): The member to act on, by the `id` from `listMembers`. An id that is not a member of the organization returns `user-not-in-organization`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## Invites Pending invites to join the organization, each with the role and authentication role the user joins with. Only emails in the organization's allowed domains can be invited, so set its allowed domains first. Emails outside them, of existing members or already invited come back as rejected, with the reason, while the others are invited. ### List invites `GET https://api.rollstack.com/public/v1/invites` The pending invites of the organization, with the role and authentication role each user joins with, and when they were invited. Requires the `users:read` scope. Only owners and admins of the organization may call it. Operation ID: `listInvites`. Only owners and admins can call it. #### Response `200` Success `application/json`: array of object - `id` (string, required): Unique identifier for the invite. Pass it as `inviteId` to `deleteInvite` to cancel the invite. - `email` (string, required): The email address invited to join the organization. - `role` (string, required): The role the person gets when they accept the invite. `owner` can do everything in the organization, `admin` manages its settings, members and invites, and `member` uses Rollstack without managing the organization. One of `owner`, `admin`, `member`. - `authenticationRole` (string or null, required): The access to the organization's Authentication settings (Single Sign-On and SCIM provisioning) the person gets when they accept the invite: `viewer` can see them, `editor` can also change them, and `null` gives none. One of `viewer`, `editor`. - `createdAt` (string (date-time), required): When the person was invited. ### Create invites `POST https://api.rollstack.com/public/v1/invites` Invites up to 50 users as admins or members. Only emails in the organization's allowed domains are invited, and it fails with a 400 while the organization has none. Returns the invites it created and the emails it rejected, with the reason: outside the allowed domains, already a member or already invited. Requires the `users:write` scope. Only owners and admins of the organization may call it. Operation ID: `createInvites`. Only owners and admins can call it. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - `emails` (array of string (email), required): The email addresses to invite. Each one on the organization's domain allowlist (`allowedDomains`) that doesn't belong to a member and isn't already invited gets an invite and an invitation email; the others come back in `rejected`. From 1 to 50 addresses, each listed once, ignoring case. - `role` (string, required): The role the invited people get when they join: `admin` lets them manage the organization's settings, members and invites, and `member` lets them use Rollstack without managing the organization. A key can't invite owners. One of `admin`, `member`. - `authenticationRole` (string): Gives the invited people access to the organization's Authentication settings (Single Sign-On and SCIM provisioning) once they join: `viewer` can see them, `editor` can also change them. If omitted, they join without access. Only owners can set it, not admins. One of `viewer`, `editor`. #### Response `201` Success `application/json` - `invited` (array of object, required): The invites created, one for each email that passed the checks. Rollstack emails each person an invitation to join. - `id` (string, required): Unique identifier for the invite. Pass it as `inviteId` to `deleteInvite` to cancel the invite. - `email` (string, required): The email address invited to join the organization. - `role` (string, required): The role the person gets when they accept the invite. `owner` can do everything in the organization, `admin` manages its settings, members and invites, and `member` uses Rollstack without managing the organization. One of `owner`, `admin`, `member`. - `authenticationRole` (string or null, required): The access to the organization's Authentication settings (Single Sign-On and SCIM provisioning) the person gets when they accept the invite: `viewer` can see them, `editor` can also change them, and `null` gives none. One of `viewer`, `editor`. - `createdAt` (string (date-time), required): When the person was invited. - `rejected` (array of object, required): The emails that were not invited, each with the reason. The other emails in the request were still invited. - `email` (string, required): An email from your request that was not invited, in lowercase. - `reason` (string, required): Why the email was not invited. `domain_not_allowed`: its domain isn't on the organization's `allowedDomains`. `already_member`: it belongs to a member of the organization, active or deactivated; reactivate a deactivated one with `reactivateMember`. `already_invited`: it already has a pending invite, listed by `listInvites`. One of `domain_not_allowed`, `already_member`, `already_invited`. ### Delete invite `DELETE https://api.rollstack.com/public/v1/invites/{inviteId}` Deletes a pending invite. Requires the `users:write` scope. Only owners and admins of the organization may call it. Operation ID: `deleteInvite`. Only owners and admins can call it. #### Path parameters - `inviteId` (string, required): The invite to delete, by the `id` from `listInvites` or `createInvites`. An unknown invite, or one from another organization, returns `invite-not-found`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content ## LLM provider The organization's own LLM provider for the slides agent: its Anthropic, OpenAI, Azure AI Foundry, Amazon Bedrock or Google Vertex AI account, used instead of Rollstack's. Credentials are write-only: reads answer the provider's settings and status, never its keys. Setting one up is part of the Enterprise plan. Saving tests every model on the new keys first, so a provider that cannot answer is never saved. ### Get LLM provider `GET https://api.rollstack.com/public/v1/organization/llm-provider` The organization's custom LLM provider, without its credentials. Only owners, and members an owner allowed to manage the AI provider, may call it. Requires the `organization:read` scope. Operation ID: `getLLMProvider`. #### Response `200` Success `application/json` - `id` (string, required): Unique identifier for the organization's LLM provider. It stays the same when you replace the provider with `setLLMProvider`; setting one up again after `deleteLLMProvider` gives a new one. - `type` (string, required): The provider the organization's slides agent runs on, instead of Rollstack's own AI providers: `anthropic` (the Anthropic API), `openai` (the OpenAI API), `azure_foundry` (an Azure AI Foundry resource), `amazon_bedrock` (Amazon Bedrock in an AWS account) or `google_vertex_ai` (Vertex AI in a Google Cloud project). Insights don't use it: they run on the organization's `llmProvider`, from `getOrganization`. One of `anthropic`, `openai`, `azure_foundry`, `amazon_bedrock`, `google_vertex_ai`. - `auth` (string, required): How Rollstack signs in to the provider. With `apiKey`, it uses a secret saved with the provider: an API key or, on Google Vertex AI, a service account key. With `oidc`, the setup is keyless: your provider trusts short-lived tokens from Rollstack's OpenID Connect issuer for your organization, so no secret is saved. One of `apiKey`, `oidc`. - `hasCredentials` (`true`, required): Whether the provider has saved credentials: always `true`. Its secrets, `apiKey` or `privateKey`, are never returned, not even in `settings`: to change them, send the whole setup again with `setLLMProvider`. - `settings` (object, required): The provider's saved setup without its secrets: the `credentials` it was last saved with, as in the `setLLMProvider` body, minus `apiKey` and `privateKey`. It contains `auth` and, depending on `type`: `dataResidency` (OpenAI); `resourceName` and `models` (Azure AI Foundry); `region`, `dataLocation` and `models` (Amazon Bedrock); or `projectId`, `region` and `models`, plus `clientEmail` with a service account key (Google Vertex AI). A keyless setup also contains its ids, such as `tenantId` and `clientId`, or `roleArn`. - `updatedAt` (string (date-time), required): When the provider was last saved, with `setLLMProvider` or in the app. Recording or clearing a `failure` doesn't change it. - `updatedBy` (object or null, required): The member who last saved the provider, with `setLLMProvider` or in the app. When `failure` is set, Rollstack notifies them, or the organization's owners if they're no longer an active member. `null` if that user's account no longer exists. - `name` (string or null, required): The name of the member who last saved the provider, as shown in Rollstack. - `email` (string, required): The email address of the member who last saved the provider. - `failure` (string or null, required): Why the slides agent's calls to the provider are failing, when only a change on your provider's side can fix it. `null` while calls work. `key_invalid`: the provider doesn't accept the API key or the keyless sign-in. `forbidden`: the key or sign-in isn't allowed to use `failedModel`. `model_not_found`: `failedModel` isn't available to the account; on Azure AI Foundry, it isn't deployed under its own name, and on Amazon Bedrock or Google Vertex AI, it isn't enabled. `out_of_credit`: the provider account is out of credit. When it's set, Rollstack notifies the member in `updatedBy`, or the owners if they're no longer an active member. It's cleared once a call to `failedModel` works again or the provider is saved again. One of `key_invalid`, `forbidden`, `model_not_found`, `out_of_credit`. - `failedAt` (string (date-time) or null, required): When a slides agent call to the provider first failed with the current `failure`. `null` while calls work. - `failedModel` (string or null, required): The model whose call failed, such as `claude-haiku-5-5`. Until the provider is saved again, only a working call to this model clears `failure`, so a failing `fast` model stays flagged even while the `smart` one works. `null` while calls work. ### Replace LLM provider `PUT https://api.rollstack.com/public/v1/organization/llm-provider` Creates or replaces the organization's custom LLM provider, on the Enterprise plan only. Only owners, and admins an owner allowed to manage the AI provider, may call it: members' keys can't carry organization:write. The keys are saved only once one short call on each of their models works: otherwise nothing is saved and the call fails with a 400 (code ai-provider-test-failed); the AI provider setting in the app says which model failed and why. Calls are limited to 10 a minute for each organization. Every owner gets an email when the provider is set up, replaced or deleted. Web search uses OpenAI, so saving a provider that moves it to Rollstack's OpenAI account (any provider but OpenAI on its global host) turns web search off, unless the organization already had that kind of provider; an owner can turn it back on. Requires the `organization:write` scope. Operation ID: `setLLMProvider`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Request body, required `application/json` - When `type` is `anthropic` - `type` (`anthropic`, required): Runs the slides agent on your own Anthropic organization, through the Anthropic API, with Claude Opus 5.5 (`claude-opus-5-5`) for its main work and Claude Haiku 5.5 (`claude-haiku-5-5`) for its quick steps. There are no models to pick or deploy. - `credentials` (object, required): How Rollstack signs in to your Anthropic organization: with an API key (`apiKey`), or without a key, through Anthropic's workload identity federation (`oidc`). - When `auth` is `apiKey` - `auth` (`apiKey`, required): Rollstack signs in to the provider with a secret you send in this request: an API key or, on Google Vertex AI, a service account key (`clientEmail` and `privateKey`). Rollstack saves the secret and never returns it, so to change it, send the whole setup again. - `apiKey` (string, required): An Anthropic API key, created in the Claude Console under API keys, in a workspace for Rollstack where you can also set a spend limit. Rollstack never returns it. Example: `your-anthropic-api-key`. - When `auth` is `oidc` - `auth` (`oidc`, required): Rollstack signs in without a saved secret: its OpenID Connect issuer signs a short-lived token for the subject `rollstack:org:`, where `` is your organization's `id` from `getOrganization`, and your provider exchanges the token for temporary credentials. Set up your provider to trust that issuer and to check that subject, so it accepts only your organization: `setLLMProvider` fails if the setup also accepts another organization's token. The AI provider setting in the app, under Settings › Features, shows the issuer, subject and audience to trust. - `anthropicOrganizationId` (string (uuid), required): The ID of your Anthropic organization, the one where you added Rollstack's issuer in the Claude Console under Settings › Workload identity federation. Example: `7c9e1f3a-5b7d-4e9f-8a1c-3e5a7c9e1f3a`. - `federationRuleId` (string, required): The ID of the federation rule that lets Rollstack act as `serviceAccountId`. Create it in the Claude Console under Settings › Workload identity federation, once Rollstack's issuer is added there: set its subject to your organization's (see `auth`), add a claim condition that the audience (`aud`) is `https://api.anthropic.com`, and enable it only in `workspaceId`. Starts with `fdrl_`. Example: `fdrl_01example`. - `serviceAccountId` (string, required): The ID of the service account Rollstack acts as in your Anthropic organization, created in the Claude Console in the workspace the slides agent should use (`workspaceId`). Starts with `svac_`. Example: `svac_01example`. - `workspaceId` (string, required): The ID of the Claude Console workspace the slides agent's calls run in: the workspace of `serviceAccountId`, where the federation rule is enabled. Starts with `wrkspc_`. Example: `wrkspc_01example`. - When `type` is `openai` - `type` (`openai`, required): Runs the slides agent on your own OpenAI project, through the OpenAI API, with GPT-6.1 Sol (`gpt-6.1-sol`) for its main work and GPT-6 Luna (`gpt-6-luna`) for its quick steps. There are no models to pick or deploy. - `credentials` (object, required): Your OpenAI project's data residency, and how Rollstack signs in to the project: with an API key (`apiKey`), or without a key, through an OpenAI workload identity provider (`oidc`). - When `auth` is `apiKey` - `dataResidency` (string, required): The data residency of the OpenAI project Rollstack uses, which decides the OpenAI host Rollstack calls: `global` for OpenAI's global host, `us` or `eu` for its US or EU host. With `global`, the slides agent's web search also uses your OpenAI project. With `us` or `eu`, it uses Rollstack's OpenAI account instead, so saving turns web search off, unless the organization's provider was already OpenAI with `us` or `eu`; an owner can turn it back on in the app. One of `global`, `us`, `eu`. - `auth` (`apiKey`, required): Rollstack signs in to the provider with a secret you send in this request: an API key or, on Google Vertex AI, a service account key (`clientEmail` and `privateKey`). Rollstack saves the secret and never returns it, so to change it, send the whole setup again. - `apiKey` (string, required): An API key for the OpenAI project Rollstack uses, created on the OpenAI platform. The project must allow `gpt-6.1-sol` and `gpt-6-luna`, the models the slides agent runs on, in Project settings › Limits › Model usage. You can also give the project a monthly budget. Rollstack never returns the key. Example: `your-openai-api-key`. - When `auth` is `oidc` - `dataResidency` (string, required): The data residency of the OpenAI project Rollstack uses, which decides the OpenAI host Rollstack calls: `global` for OpenAI's global host, `us` or `eu` for its US or EU host. With `global`, the slides agent's web search also uses your OpenAI project. With `us` or `eu`, it uses Rollstack's OpenAI account instead, so saving turns web search off, unless the organization's provider was already OpenAI with `us` or `eu`; an owner can turn it back on in the app. One of `global`, `us`, `eu`. - `auth` (`oidc`, required): Rollstack signs in without a saved secret: its OpenID Connect issuer signs a short-lived token for the subject `rollstack:org:`, where `` is your organization's `id` from `getOrganization`, and your provider exchanges the token for temporary credentials. Set up your provider to trust that issuer and to check that subject, so it accepts only your organization: `setLLMProvider` fails if the setup also accepts another organization's token. The AI provider setting in the app, under Settings › Features, shows the issuer, subject and audience to trust. - `identityProviderId` (string, required): The ID of the identity provider you create on the OpenAI platform, under Settings › Security › Workload Identity Provider, with Rollstack's issuer and the audience `https://api.openai.com`. Map it to the service account in `serviceAccountId`, with `sub` set to your organization's subject (see `auth`) and `aud` to that audience. Example: `idp_example`. - `serviceAccountId` (string, required): The User ID of the OpenAI service account Rollstack acts as. Create the service account with Restricted permissions and Model capabilities set to Write, in a project with the data residency in `dataResidency` that allows `gpt-6.1-sol` and `gpt-6-luna`. Example: `user-example`. - When `type` is `azure_foundry` - `type` (`azure_foundry`, required): Runs the slides agent on Claude or GPT models deployed in your Azure AI Foundry resource, the ones you pick in `credentials.models`. - `credentials` (object, required): Your Azure AI Foundry resource, the models on it the slides agent runs on, and how Rollstack signs in: with the resource's API key (`apiKey`), or without a key, as an app registered in Microsoft Entra ID (`oidc`). - When `auth` is `apiKey` - `resourceName` (string, required): The name of your Azure AI Foundry resource, which Rollstack calls at `https://.services.ai.azure.com`. It's the first part of the host in any deployment's Target URI, such as `acme-ai` in `https://acme-ai.services.ai.azure.com`. 2 to 63 lowercase letters, digits and hyphens, starting with a letter or digit. Example: `acme-ai`. - `models` (object, required): The models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Make them available first: on Azure AI Foundry, deploy each under its model's name (Foundry's default), such as `claude-opus-5-5`; on Amazon Bedrock, enable them in Model access in `region`. - `smart` (string, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries: `claude-opus-5-5` (Claude Opus 5.5) or `gpt-6.1-sol` (GPT-6.1 Sol). One of `claude-opus-5-5`, `gpt-6.1-sol`. - `fast` (string): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5) or `gpt-6-luna` (GPT-6 Luna). It can be from a different family than `smart`. If omitted, the `smart` model runs these steps too. One of `claude-haiku-5-5`, `gpt-6-luna`. - `auth` (`apiKey`, required): Rollstack signs in to the provider with a secret you send in this request: an API key or, on Google Vertex AI, a service account key (`clientEmail` and `privateKey`). Rollstack saves the secret and never returns it, so to change it, send the whole setup again. - `apiKey` (string, required): An API key of your Azure AI Foundry resource. Rollstack uses it for every model it calls on the resource, Claude and GPT alike, and never returns it. Example: `your-azure-api-key`. - When `auth` is `oidc` - `resourceName` (string, required): The name of your Azure AI Foundry resource, which Rollstack calls at `https://.services.ai.azure.com`. It's the first part of the host in any deployment's Target URI, such as `acme-ai` in `https://acme-ai.services.ai.azure.com`. 2 to 63 lowercase letters, digits and hyphens, starting with a letter or digit. Example: `acme-ai`. - `models` (object, required): The models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Make them available first: on Azure AI Foundry, deploy each under its model's name (Foundry's default), such as `claude-opus-5-5`; on Amazon Bedrock, enable them in Model access in `region`. - `smart` (string, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries: `claude-opus-5-5` (Claude Opus 5.5) or `gpt-6.1-sol` (GPT-6.1 Sol). One of `claude-opus-5-5`, `gpt-6.1-sol`. - `fast` (string): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5) or `gpt-6-luna` (GPT-6 Luna). It can be from a different family than `smart`. If omitted, the `smart` model runs these steps too. One of `claude-haiku-5-5`, `gpt-6-luna`. - `auth` (`oidc`, required): Rollstack signs in without a saved secret: its OpenID Connect issuer signs a short-lived token for the subject `rollstack:org:`, where `` is your organization's `id` from `getOrganization`, and your provider exchanges the token for temporary credentials. Set up your provider to trust that issuer and to check that subject, so it accepts only your organization: `setLLMProvider` fails if the setup also accepts another organization's token. The AI provider setting in the app, under Settings › Features, shows the issuer, subject and audience to trust. - `tenantId` (string (uuid), required): The Directory (tenant) ID of your Microsoft Entra ID tenant, where you register the app Rollstack signs in as. Example: `4d6f8a0c-2e3a-4b5c-8d7e-9f1a3b5c7d9e`. - `clientId` (string (uuid), required): The Application (client) ID of the app you register for Rollstack in Microsoft Entra ID, with no client secret. Give it a federated credential that trusts Rollstack's issuer for your organization's subject (see `auth`), with the audience `api://AzureADTokenExchange`, and the Cognitive Services User role on the resource. A new trust can take a few minutes to apply. Example: `2b4d6f8a-0c1e-4a3b-9d5f-7b9d1f3a5c7e`. - When `type` is `amazon_bedrock` - `type` (`amazon_bedrock`, required): Runs the slides agent on Claude or GPT models in Amazon Bedrock, in your AWS account, the ones you pick in `credentials.models`. - `credentials` (object, required): Where Rollstack calls Amazon Bedrock, the models the slides agent runs on, and how Rollstack signs in: with a Bedrock API key (`apiKey`), or without a key, by assuming an IAM role (`oidc`). - When `auth` is `apiKey` - `region` (string, required): The AWS region Rollstack calls Amazon Bedrock in, such as `us-east-1`. It must be in `dataLocation`: a `us-` region for `us`, an `eu-` region for `eu`, `ap-southeast-2` or `ap-southeast-4` for `au`, `ap-northeast-1` or `ap-northeast-3` for `jp`, and any region for `global`. Example: `us-east-1`. - `dataLocation` (string, required): Where Amazon Bedrock may process the slides agent's requests to Claude models: `us` (United States), `eu` (Europe), `au` (Australia), `jp` (Japan) or `global`. Rollstack calls Claude through this location's cross-region inference profile, such as `us.anthropic.claude-opus-5-5` or `global.anthropic.claude-opus-5-5`, and GPT models in `region` directly. One of `us`, `eu`, `au`, `jp`, `global`. - `models` (object, required): The models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Make them available first: on Azure AI Foundry, deploy each under its model's name (Foundry's default), such as `claude-opus-5-5`; on Amazon Bedrock, enable them in Model access in `region`. - `smart` (string, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries: `claude-opus-5-5` (Claude Opus 5.5) or `gpt-6.1-sol` (GPT-6.1 Sol). One of `claude-opus-5-5`, `gpt-6.1-sol`. - `fast` (string): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5) or `gpt-6-luna` (GPT-6 Luna). It can be from a different family than `smart`. If omitted, the `smart` model runs these steps too. One of `claude-haiku-5-5`, `gpt-6-luna`. - `auth` (`apiKey`, required): Rollstack signs in to the provider with a secret you send in this request: an API key or, on Google Vertex AI, a service account key (`clientEmail` and `privateKey`). Rollstack saves the secret and never returns it, so to change it, send the whole setup again. - `apiKey` (string, required): A long-term Amazon Bedrock API key, created with an expiry for an IAM user whose policy allows only the models in `models`; the AI provider setting in the app shows that policy. Rollstack uses it for Claude and GPT models alike, and never returns it. Example: `your-bedrock-api-key`. - When `auth` is `oidc` - `region` (string, required): The AWS region Rollstack calls Amazon Bedrock in, such as `us-east-1`. It must be in `dataLocation`: a `us-` region for `us`, an `eu-` region for `eu`, `ap-southeast-2` or `ap-southeast-4` for `au`, `ap-northeast-1` or `ap-northeast-3` for `jp`, and any region for `global`. Example: `us-east-1`. - `dataLocation` (string, required): Where Amazon Bedrock may process the slides agent's requests to Claude models: `us` (United States), `eu` (Europe), `au` (Australia), `jp` (Japan) or `global`. Rollstack calls Claude through this location's cross-region inference profile, such as `us.anthropic.claude-opus-5-5` or `global.anthropic.claude-opus-5-5`, and GPT models in `region` directly. One of `us`, `eu`, `au`, `jp`, `global`. - `models` (object, required): The models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Make them available first: on Azure AI Foundry, deploy each under its model's name (Foundry's default), such as `claude-opus-5-5`; on Amazon Bedrock, enable them in Model access in `region`. - `smart` (string, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries: `claude-opus-5-5` (Claude Opus 5.5) or `gpt-6.1-sol` (GPT-6.1 Sol). One of `claude-opus-5-5`, `gpt-6.1-sol`. - `fast` (string): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5) or `gpt-6-luna` (GPT-6 Luna). It can be from a different family than `smart`. If omitted, the `smart` model runs these steps too. One of `claude-haiku-5-5`, `gpt-6-luna`. - `auth` (`oidc`, required): Rollstack signs in without a saved secret: its OpenID Connect issuer signs a short-lived token for the subject `rollstack:org:`, where `` is your organization's `id` from `getOrganization`, and your provider exchanges the token for temporary credentials. Set up your provider to trust that issuer and to check that subject, so it accepts only your organization: `setLLMProvider` fails if the setup also accepts another organization's token. The AI provider setting in the app, under Settings › Features, shows the issuer, subject and audience to trust. - `roleArn` (string, required): The ARN of the IAM role Rollstack assumes to call Amazon Bedrock. Its trust policy must trust Rollstack's issuer, added as an OIDC provider in your AWS account, for your organization's subject (see `auth`) and the audience `sts.amazonaws.com`. Its permissions should allow only the models in `models`. The AI provider setting in the app gives the AWS CLI commands. Example: `arn:aws:iam::123456789012:role/rollstack-agent`. - When `type` is `google_vertex_ai` - `type` (`google_vertex_ai`, required): Runs the slides agent on Claude models in Vertex AI, in your Google Cloud project: Claude Opus 5.5 for its main work and, if you add it in `credentials.models`, Claude Haiku 5.5 for its quick steps. - `credentials` (object, required): Your Google Cloud project and Vertex AI location, the models the slides agent runs on, and how Rollstack signs in: with a service account's JSON key (`apiKey`), or without a key, through workload identity federation (`oidc`). - When `auth` is `apiKey` - `projectId` (string, required): The ID of the Google Cloud project Rollstack calls Vertex AI in, where you enable the models in Model Garden. Use the project ID, such as `acme-ai`, not its name or number. Example: `acme-ai`. - `region` (string, required): Where Vertex AI processes the slides agent's requests: `global` (Vertex AI's global endpoint), `us` (the US multi-region) or `eu` (the EU multi-region). One of `global`, `us`, `eu`. - `models` (object, required): The Claude models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Enable them in Vertex AI's Model Garden for `projectId`. - `smart` (`claude-opus-5-5`, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries. Always `claude-opus-5-5` (Claude Opus 5.5): on Google Vertex AI, the slides agent runs on Claude only. - `fast` (`claude-haiku-5-5`): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5). If omitted, `claude-opus-5-5` runs these steps too. - `auth` (`apiKey`, required): Rollstack signs in to the provider with a secret you send in this request: an API key or, on Google Vertex AI, a service account key (`clientEmail` and `privateKey`). Rollstack saves the secret and never returns it, so to change it, send the whole setup again. - `clientEmail` (string (email), required): The email of the Google Cloud service account Rollstack signs in as: `client_email` in its JSON key. The service account needs the Vertex AI User role. Example: `rollstack@acme-ai.iam.gserviceaccount.com`. - `privateKey` (string, required): The service account's private key: `private_key` in its JSON key. Rollstack keeps only this and `clientEmail` from the key, and never returns the private key. Example: `your-private-key`. - When `auth` is `oidc` - `projectId` (string, required): The ID of the Google Cloud project Rollstack calls Vertex AI in, where you enable the models in Model Garden. Use the project ID, such as `acme-ai`, not its name or number. Example: `acme-ai`. - `region` (string, required): Where Vertex AI processes the slides agent's requests: `global` (Vertex AI's global endpoint), `us` (the US multi-region) or `eu` (the EU multi-region). One of `global`, `us`, `eu`. - `models` (object, required): The Claude models the slides agent runs on: `smart` for its main work, `fast` for its quick steps. Enable them in Vertex AI's Model Garden for `projectId`. - `smart` (`claude-opus-5-5`, required): The model that runs the slides agent and does its main work, such as editing slides and writing queries. Always `claude-opus-5-5` (Claude Opus 5.5): on Google Vertex AI, the slides agent runs on Claude only. - `fast` (`claude-haiku-5-5`): The model for the slides agent's quick steps around its main work, such as naming the chat and inspecting slides, to save cost: `claude-haiku-5-5` (Claude Haiku 5.5). If omitted, `claude-opus-5-5` runs these steps too. - `auth` (`oidc`, required): Rollstack signs in without a saved secret: its OpenID Connect issuer signs a short-lived token for the subject `rollstack:org:`, where `` is your organization's `id` from `getOrganization`, and your provider exchanges the token for temporary credentials. Set up your provider to trust that issuer and to check that subject, so it accepts only your organization: `setLLMProvider` fails if the setup also accepts another organization's token. The AI provider setting in the app, under Settings › Features, shows the issuer, subject and audience to trust. - `poolProjectNumber` (string, required): The number of the Google Cloud project that contains the workload identity pool, as `gcloud projects describe` prints it. Digits only: the project number, not its ID. Example: `123456789012`. - `poolId` (string, required): The ID of the workload identity pool that contains the provider in `providerId`, such as `rollstack`. Example: `rollstack`. - `providerId` (string, required): The ID of the OIDC provider in the pool that trusts Rollstack's issuer, such as `rollstack`. Map `google.subject` to `assertion.sub`, and keep Google's default audience, the provider's own resource name, which is the audience Rollstack's token carries. Grant the Vertex AI User role only to your organization's subject (see `auth`) in the pool. Example: `rollstack`. #### Response `204` Success, no content ### Delete LLM provider `DELETE https://api.rollstack.com/public/v1/organization/llm-provider` Deletes the organization's custom LLM provider, on any plan. Only owners, and admins an owner allowed to manage the AI provider, may call it: members' keys can't carry organization:write. Every owner gets an email. Requires the `organization:write` scope. Operation ID: `deleteLLMProvider`. #### Headers - `Idempotency-Key` (string): A unique value, such as a UUID, that makes retrying this call safe. A retry with the same key within 24 hours answers the first call's result instead of running it again. Use a new key for each new call. From 1 to 255 printable ASCII characters. #### Response `204` Success, no content