# Billing
Source: https://docs.summand.com/account/billing
How to manage payment methods, view invoices, and change plans.
Billing is handled by [Stripe](https://stripe.com). Summand surfaces the customer portal directly so you can manage payment methods, see invoices, and update billing details without leaving the product.
## Where to find it
**Settings → Billing**. The page shows your current plan, next invoice date, payment method, and a *Manage billing* button that opens the Stripe customer portal.
For Enterprise customers, billing is invoiced — there's no card on file. Invoices arrive via email and the contact set on the contract; the in-product page shows status and historical invoices.
## Plan changes
| Change | How |
| - | - |
| **Free → Pro** | Click *Upgrade* in **Settings → Billing**, add a payment method, confirm. Upgrade is immediate. |
| **Pro → Enterprise** | Contact [our sales team](https://intelligible.ai/contact). |
| **Enterprise → Pro** | Contact your account manager. Downgrades happen at contract renewal. |
| **Pro → Free** | Click *Cancel subscription* in the Stripe portal. Service continues to the end of the billing period, then drops to Free. |
| **Pause / resume** | Available on Pro via the Stripe portal. Useful for short breaks (≤3 months). |
Education tier (\$0/mo equivalent of Pro) is granted to users with a verified `.edu` email — request it from [support@intelligible.ai](mailto:support@intelligible.ai) and we verify and apply the upgrade. Renewed annually via re-verification.
## Invoices
Pro and Free tiers — invoices are generated monthly by Stripe and delivered to the email on file. Available for download as PDF from the Stripe portal at any time.
Enterprise — invoices follow your contract's cadence (monthly, quarterly, annual). Custom payment terms (net-30, net-60) are supported.
## Payment methods
Pro: any major credit or debit card. ACH (USD only) for accounts with Stripe Treasury enabled. Add or change in the Stripe portal.
Enterprise: ACH, wire, and check accepted. International wire works but adds a \$30 fee per transaction. Set up via your account manager.
## Billing email vs. account email
Your **billing email** is separate from your sign-in email — useful when invoices need to go to a different address (e.g. accounts payable, not your direct address). Configure in the Stripe portal.
## Tax
Tax is calculated automatically based on the billing address:
* **US** — Stripe Tax handles state and local sales tax.
* **EU** — VAT charged based on your address; reverse-charge applies if you provide a valid VAT ID.
* **Other countries** — most major jurisdictions supported via Stripe Tax. See [stripe.com/tax](https://stripe.com/tax) for the full list.
Add or update your tax ID in the Stripe portal under *Tax IDs*.
## Promo codes and credits
If you've been issued a promo code (signup bonus, conference giveaway, partner discount), redeem from **Settings → Billing → Apply promo**. Credits stack with paid plans — you'll see them applied as a discount on the next invoice.
Each promo can be claimed once per account.
## Refunds
Refunds are handled case-by-case via [support@intelligible.ai](mailto:support@intelligible.ai). Enterprise contracts are governed by the contract's termination clause.
## Failed payments
If a payment fails (expired card, insufficient funds, fraud block):
1. Stripe retries automatically over 21 days.
2. You receive email notifications at each retry.
3. After 21 days of failed retries, the account drops to Free until payment is restored.
Datasets and analysis history are preserved during the failed-payment window and the subsequent Free downgrade — no data loss. Restoring payment immediately restores the previous tier's features.
# Data retention
Source: https://docs.summand.com/account/data-retention
How long Summand keeps your data, and how to delete it.
Summand retains data for as long as your account is active, with two exceptions: Free-tier datasets that go inactive, and audit logs (which are retained on a fixed schedule for compliance).
## Active data
| Resource | Retention |
| - | - |
| Datasets (Pro / Enterprise / Education) | Indefinite while subscription is active |
| Datasets (Free) | Indefinite while the account is active and within tier limits |
| Computed-context versions | All versions kept while the dataset is active |
| Connectors | Indefinite while the account is active |
| Conversation history with Summand | 7 / 90 / 365 days (Free / Pro and Education / Enterprise) |
| Comments | Indefinite |
| Saved report templates | Indefinite |
| Generated PDF exports | Indefinite |
## Identity and audit data
Identity and audit data have separate retention and aren't subject to subscription state:
| Resource | Retention |
| - | - |
| Identity audit logs (WorkOS) | 6 years |
| Application audit logs (CloudWatch) | 1 year (Free / Pro), 6 years (Enterprise) |
| Sign-in sessions | Managed by WorkOS AuthKit; configurable per-org (Enterprise) |
| Sign-in attempts (success and failure) | 90 days |
| MFA factors | Until rotated by the user or admin |
Six-year retention satisfies HIPAA's audit requirement.
## On account deletion
When you delete your account from **Settings → Profile**:
* **Within 7 days** — the deletion is reversible. Email support to restore.
* **After 7 days** — all of your owned datasets, connectors, and personal data are deleted. Audit log entries you generated are preserved but anonymized (you're identified by user ID, not email or name, in older entries).
* **Datasets owned by you in Enterprise organizations** — transferred to the org owner unless you've explicitly transferred them first.
* **Datasets shared with you** — your grants are revoked; the datasets remain owned by their owner.
## On organization deletion (Enterprise)
When an organization is deleted:
* All datasets, connectors, and members are scheduled for deletion within 30 days.
* Identity audit logs are retained for the full 6 years (regulatory requirement).
* Active sessions are invalidated immediately.
* Members are notified by email; their personal accounts and data unrelated to the org persist.
Org deletion requires an account manager — there's no self-serve "delete organization" button.
## Data export before deletion
Before any deletion event, you can export:
* **Per-dataset** — PDF reports of every analysis tab from the dataset menu.
* **Per-organization** — full data export via [support@intelligible.ai](mailto:support@intelligible.ai); delivered as a tarball within 5 business days.
* **Identity audit logs** — exported via the WorkOS Admin Portal in CSV or JSON.
Export availability is independent of subscription state — you can always export your data, even if billing has lapsed.
## Backups
All Summand infrastructure is backed up continuously to AWS-managed snapshots:
* **DynamoDB** — point-in-time recovery enabled, 35-day window.
* **S3** — versioning + cross-region replication.
* **Secrets** — managed by AWS Secrets Manager with automatic rotation where supported.
Backup data is retained for the same period as the source data.
## Data locality
All data lives in AWS `us-east-1` (Northern Virginia). For customers with residency requirements outside the US, contact sales — see [Compliance](/enterprise/compliance#data-residency).
## Right-to-be-forgotten requests (GDPR)
For individual users covered by GDPR or CCPA: file a deletion request at [privacy@intelligible.ai](mailto:privacy@intelligible.ai). We confirm receipt within 5 business days and complete the deletion within 30 days. The confirmation includes a record of what was deleted and what (if anything) was retained for legal reasons.
# Profile
Source: https://docs.summand.com/account/profile
Manage your name, email, password, and per-user preferences.
Your profile is independent of any organization you belong to. It travels with you across orgs and is the authoritative source for your name, email, and authentication factors.
## Editing your profile
From **Settings → Profile**, you can update:
* **Display name** — shown in shared datasets, comments, and audit logs.
* **Email** — the primary identifier for sign-in. Changing it requires confirming the new address.
* **Time zone** — used for date formatting in the UI and PDF exports. Detected from your browser by default.
* **Theme** — Light, Dark, or System. Stored locally per browser.
* **Verbose logging** — useful for debugging chart issues. Off by default.
## Password and MFA
For users on the email + password sign-in path:
* **Change password** — current password required. New password must be at least 12 characters, with no length cap.
* **Reset MFA** — removes your TOTP factor. You'll be prompted to re-enroll on next sign-in. Use this if you've changed devices.
* **View active sessions** — list of devices and IP addresses with active sessions. Revoke individually or all-at-once.
If your account is SSO-backed and your IdP doesn't allow self-service password reset, the password fields are hidden — your IdP is the source of truth for credentials.
## Email verification
When you change your email, Summand:
1. Marks the new address as *Pending verification*.
2. Sends a verification code to the new address.
3. Until you enter the code, your old address is still your primary identifier.
4. After verification, the new address becomes primary.
Verification codes expire after 15 minutes. Resend from the **Settings → Profile** page if you miss it.
## Deleting your account
Self-serve account deletion is in **Settings → Profile → Delete account**. Effects:
* **All datasets you own** are transferred to your organization's owner (Enterprise) or deleted (Free / Pro).
* **Grants you've made** are revoked.
* **Audit history of your actions** is preserved (you're identified by user ID, not email, in old logs).
* **Your email** is freed; another user can sign up with it later.
Account deletion is reversible only within 7 days via [support@intelligible.ai](mailto:support@intelligible.ai). After 7 days, all references to the user are anonymized and unrecoverable.
## Notification preferences
Per-user notification preferences live in **Settings → Notifications**:
* **Dataset shared with me** — email when someone grants you access.
* **Analysis completed** — email when a long-running analysis finishes.
* **Billing alerts** (org owners only) — email for failed payments, upcoming renewals.
* **Product updates** — opt-in newsletter; off by default.
Email digests are batched — you won't get one notification per share grant if 20 datasets are shared at once.
# API Reference
Source: https://docs.summand.com/api-reference/introduction
Programmatic access to Summand via the Model Context Protocol.
Summand exposes its read-side API through a hosted [Model Context Protocol](https://modelcontextprotocol.io) server. Any MCP-aware client — claude.ai, ChatGPT, or your own — can sign in with OAuth and query your datasets, computed-context components, and surprise findings without writing a line of glue code.
A traditional REST API is on the roadmap, but MCP is the supported integration surface today.
## The Summand MCP server
* **Endpoint:** `https://mcp.summand.com/mcp`
* **Transport:** streamable-HTTP
* **Auth:** OAuth 2.1
* **Access model:** scoped to whatever the signed-in user can already see in the dashboard — owned datasets plus anything explicitly shared with them
What the server is and what it exposes.
Wire up claude.ai, ChatGPT, or any OAuth-aware MCP client.
Parameters and example prompts for every tool.
## What about a REST API?
A public REST API is on our roadmap and will follow the same authorization model (OpenFGA-backed, per-resource grants and visibility) with bearer-token authentication. Enterprise customers with a concrete use case — backend integrations, scheduled refresh jobs, custom dashboards — can request early access by emailing [support@intelligible.ai](mailto:support@intelligible.ai) with a one-paragraph description of what you'd build.
# Connect a client
Source: https://docs.summand.com/api-reference/mcp/connect
Add the Summand MCP server to claude.ai, ChatGPT, and other OAuth-aware MCP clients.
The Summand MCP server is a remote, OAuth-authenticated streamable-HTTP endpoint. There is nothing to install — every client uses the same URL and follows the standard OAuth discovery flow.
## Endpoint
```
https://mcp.summand.com/mcp
```
The endpoint is stateless: each request constructs a fresh server instance scoped to the bearer token in the `Authorization` header.
## Add to claude.ai
Go to [claude.ai/settings/connectors](https://claude.ai/settings/connectors), or from claude.ai navigate to **Settings → Connectors**.
Click **Add custom connector**.
* **Name:** anything you want (e.g. `Summand MCP`)
* **Remote MCP server URL:** `https://mcp.summand.com/mcp`
Then click **Add**.
Click **Connect** on the new entry.
You'll be redirected to `login.summand.com`. Sign in with the same account you use at summand.com.
Back in claude.ai, start a new conversation and ask about your data — for example, "What data connectors do I have in Summand?" Claude will request permission to call the relevant tool.
## Add to ChatGPT
Go to [chatgpt.com/#settings/Connectors](https://chatgpt.com/#settings/Connectors), or from chatgpt.com navigate to **Settings → Apps**.
Open **Advanced settings** and toggle **Developer mode** on. This is required to connect to external MCP servers.
Click **Create app** at the top of the modal.
* **Name:** anything you want (e.g. `Summand MCP`)
* **MCP server URL:** `https://mcp.summand.com/mcp`
Check **I understand and want to continue**, then submit.
You'll be redirected to `login.summand.com` with the prompt "ChatGPT would like access to your account". Click **Allow access**.
Open a new ChatGPT chat and type `/summand` — you'll see the connector you just added, and the tools it exposes.
## Troubleshooting
* **Client can't discover the MCP server** — make sure you're using the full endpoint URL with `/mcp` at the end. `https://mcp.summand.com` on its own will not work — it must be `https://mcp.summand.com/mcp`.
* **`401` on every call** — your token expired or was revoked. Disconnect and reconnect the integration in your client.
* **`403 Forbidden`** — the resource isn't owned by or shared with your user. Check sharing in the dashboard.
# MCP server overview
Source: https://docs.summand.com/api-reference/mcp/overview
What the Summand MCP server is and what it exposes.
The Summand MCP server implements the [Model Context Protocol](https://modelcontextprotocol.io) and gives any MCP-aware client read access to your Summand connectors, datasets, and their computed-context layer.
It's hosted by Summand at `https://mcp.summand.com/mcp` and uses the streamable-HTTP transport with OAuth 2.1 authentication. There's nothing to install — point your client at the URL, sign in, and start asking questions.
Wire up claude.ai, ChatGPT, or any other OAuth-aware MCP client.
## What the server exposes
The server registers seven tools. All of them are read-only — the MCP server cannot mutate connectors or datasets, run pipelines, or change settings.
| Tool | Purpose |
| - | - |
| `list_data_connectors` | Discover the data connectors (databases, file uploads, integrations) the caller can see. |
| `list_datasets` | Discover what datasets the caller can see. Each dataset carries a `connectorId`. |
| `describe_dataset` | Full metadata for a dataset, including which semantic components are available. |
| `get_columns` | Column names and statistics. |
| `get_semantic_data` | Specific semantic components: EBM graphs, feature metadata, embeddings, etc. |
| `get_surprises` | ML-generated surprise findings with explanations. |
| `compare_schemas` | Side-by-side column comparison between two datasets. |
See the [tools reference](/api-reference/mcp/tools) for parameters and example outputs.
## Authentication model
Access is scoped to whatever the caller already has in Summand — owned resources plus anything explicitly shared with them. There is no way to access a connector or dataset over MCP that you couldn't access in the dashboard.
Authentication uses OAuth 2.1 bearer tokens issued by Summand's identity provider. Standard MCP discovery is supported, so clients auto-discover the authorization server on a `401` and register themselves dynamically — no pre-registration required.
You'll typically only need to paste the endpoint URL into your client; everything else happens in the OAuth redirect.
## What's next
Step-by-step setup for claude.ai and ChatGPT.
Parameters and example prompts for every tool.
# Tools reference
Source: https://docs.summand.com/api-reference/mcp/tools
The seven tools the Summand MCP server exposes, with parameters and example prompts.
All tools are read-only. Most of them take a `datasetId` of the form `ds_019…`. Use `list_datasets` to discover dataset IDs and `list_data_connectors` to discover connector IDs.
## list\_data\_connectors
List every data connector the caller can see — owned connectors plus anything shared with them. A data connector is a database, file upload, or third-party integration that contains one or more datasets.
**Parameters:** none.
**Returns:** an array of `{ id, displayName, kind, visibility, accessLevel, database, createdAt, updatedAt }` plus a `count`. `kind` is one of `postgres`, `mysql`, `snowflake`, `csv`, `fivetran`, etc. `accessLevel` is `owner` or `read`.
Pair with `list_datasets` — each dataset carries a `connectorId` — to navigate from a connector to its datasets.
> "What data connectors do I have in Summand?"
## list\_datasets
List every dataset the caller can see — owned datasets plus anything shared with them.
**Parameters:** none.
**Returns:** an array of `{ id, name, kind, status, targetColumn, latestVersion, accessLevel, updatedAt }` plus a `count`. Each dataset includes a `connectorId` linking back to its parent data connector.
> "List my Summand datasets."
## describe\_dataset
Full metadata for a dataset, including its computed-context manifest. The `semanticLayer.manifest.components` field tells you which components are valid inputs to `get_columns` and `get_semantic_data` (e.g. `column_stats`, `ebm_graphs`, `feature_metadata`, `umap_embedding`).
The dataset ID (e.g. `ds_019abc…`).
> "Describe `ds_019abc…` — what analysis components are available?"
## get\_columns
Column information for a dataset. Returns rich statistics from the `column_stats` component when available (type, mean, min, max, null count, distinct count), or falls back to feature names from `feature_metadata`.
The dataset ID.
> "What columns does `ds_019abc…` have, and what are their distributions?"
## get\_semantic\_data
Retrieve a specific computed-context component. This is the workhorse tool — call `describe_dataset` first to see what's available, then pull the component you want.
The dataset ID.
Component name from the manifest. Common values: `column_stats`, `ebm_graphs`, `feature_metadata`, `umap_embedding`, `data_quality`.
Optional filter params. For example, pass `{ "feature": "price" }` with `ebm_graphs` to retrieve only that feature's contribution data instead of the full graph payload.
> "Get the EBM graphs for `JobLevel` in `ds_019abc…`."
## get\_surprises
Surprise findings for a dataset — ML-generated unexpected statistical patterns with confidence scores and natural-language explanations. Returned in display order, with deleted items filtered out.
The dataset ID.
> "What are the surprising findings in my HR attrition dataset?"
## compare\_schemas
Side-by-side column comparison between two datasets. Returns columns in both, columns only in A, and columns only in B.
First dataset ID.
Second dataset ID.
> "Compare the schemas of `ds_019abc…` and `ds_019def…`."
# Use cases
Source: https://docs.summand.com/api-reference/mcp/use-cases
Talk to your Summand data in natural language from any MCP-aware AI client.
Once the Summand MCP server is connected, you can talk to your data the same way you talk to any AI assistant. There's no query language, no API to learn, and no dashboard to navigate — just ask. The client picks the right tool, calls it on your behalf, and folds the results back into the conversation.
This works in any OAuth-aware MCP client, for example [claude.ai](/api-reference/mcp/connect#add-to-claude-ai) or [ChatGPT](/api-reference/mcp/connect#add-to-chatgpt),
## Example conversation
A typical first session walks from "what do I have?" to "what does it tell me?" in three turns.
### 1. List your datasets
Start by asking what's available. The client calls `list_datasets` (and/or `list_data_connectors`) and shows you everything you own or have been shared.
> "List my datasets."
### 2. Dig into one of them
Pick something interesting and ask for more. The client pulls metadata, columns, and the available computed-context components in a single turn.
> "Tell me more about my superstore sales dataset."
### 3. Pull a specific analysis component
Once you know what's available, ask for the analysis you actually want — feature importance, surprise findings, column distributions, embeddings, anything in the computed-context layer.
> "Show me the feature importance graph for that dataset."
## Other things to try
* **Compare two datasets.** *"What columns are in my Q3 sales data but not in Q2?"*
* **Surface surprises.** *"What surprising findings did Summand pick up in the attrition dataset?"*
* **Investigate a single feature.** *"How does `JobLevel` affect attrition? Show me the EBM contribution."*
* **Audit your sources.** *"Which data connectors do I have, and what kind of database is each one?"*
The MCP server is read-only, so anything you ask is bounded by what you can already see in the Summand dashboard — owned resources plus anything explicitly shared with you.
# Changelog
Source: https://docs.summand.com/changelog
What's shipped recently in Summand.
User-facing changes worth knowing about, newest first.
For real-time deploys and infra status, see [status.summand.com](https://status.summand.com).
## May 2026
* **V2 sharing model** — sharing now splits into two distinct concepts: **filing** (single-parent ownership inside a workspace) and **publication** (multi-target read access for users, workspace members, or showcase audiences). All authorization is enforced through OpenFGA. See [Sharing](/concepts/sharing).
* **Workspace as the share target for connectors and datasets** — the grant model now consistently treats the workspace as the primary owner, with publications layered on top.
## April 2026
* **Workspace detail pages** — drill into a workspace to see all of its connectors and datasets in one view.
* **Workspace listing redesign** — clearer cards, faster load.
## March 2026
* **Fivetran connector** — analyze any Fivetran-supported source (Databricks, Redshift, Oracle, SaaS APIs) without writing a native driver. See [Fivetran](/data-sources/fivetran).
* **Iceberg-native reads** — for Iceberg tables, Summand now reads via Athena `$files` and `$snapshots` instead of bundling pyiceberg in Lambda. Faster, lighter, more accurate.
* **MFA enforcement for shared private datasets** — accessing a private dataset shared with you now requires a fresh MFA challenge. See [MFA](/enterprise/mfa).
## Earlier in 2026
* **Experiments and components** — analysis is now configured as scheduled component runs against a dataset or view, replacing the older "pick a target column at upload" model. Target column moved from being a dataset field to being a typed input on the **Predictors** component. See [Experiments](/concepts/experiments) and [Components](/concepts/components).
* **Views** — saved SQL transformations with a visual builder, hand-edit code mode, and live Athena preview. Cross-dataset joins supported. Summand can also draft views from chat. See [Views](/concepts/views).
* **Delta Sharing connector** — Databricks UniForm shares with Iceberg-backed incremental refresh. See [Delta Sharing](/data-sources/delta-sharing).
* **Azure SQL connector** — Azure SQL Database and Managed Instance via TDS.
## February 2026
* **Multi-runtime computed-context pipeline** — analysis components dispatch to Lambda or ECS based on workload size, cutting cold-start latency on small datasets.
* **SUM-140 Distributed Map** — Step Functions Distributed Map for parallelizing per-component work across large datasets.
## January 2026
* **v1.0.0 GA** — Summand exits beta. Pricing solidified to Free / Pro \$99 / Education / Enterprise. See [Pricing](/pricing).
* **Per-account Pro pricing** — flat \$99/month, not per-seat.
* **Education tier** — full Pro features for verified `.edu` users.
* **Enterprise SSO** — WorkOS-based SAML 2.0 / OIDC, replacing the prior Cognito-based implementation.
## Earlier
* **Surprise finding** — flag rows the predictor model considers unusual, ranked by confidence.
* **Summand assistant** — the in-product AI assistant, powered by Claude with grounding from the computed-context layer.
* **Database connectors** — direct PostgreSQL, MySQL, Snowflake.
* **EBM-based predictor component** — Explainable Boosting Machines as the default model class, replacing earlier black-box gradient boosting.
***
For a complete commit-level history, see the [GitHub repository](https://github.com/intelligible-ai/summand) (private; access on request).
# Components
Source: https://docs.summand.com/concepts/components
The unit of analysis Summand runs. Six user-visible components in the catalog today, all stable, plus internal-only dependencies.
A **component** is a self-contained piece of analysis with typed inputs and outputs. Components are the things experiments run; they're also what the dataset's **Components** tab assigns and configures. You don't write components — they're built by Summand and exposed through a **catalog** the in-product editor reads to render forms, validate inputs, and dispatch runs.
## The catalog
Six components are visible in the experiment editor:
Per-column distributions, missingness, cardinality, and basic numeric statistics. Runs automatically on first ingest.
Fits an Explainable Boosting Machine and writes feature importance, shape functions, and pairwise interactions.
Correlations and other measures of association for every column pair.
Beta
Time-series projection with 95% prediction intervals, using a Holt-Winters model under the hood.
Identifies unusual values and anomalous rows.
Beta
LLM-generated, business-friendly descriptions for every dataset column. Powers chat grounding.
A 2-D projection of feature space for cluster visualization and "similar rows" queries.
Identifies patterns in the missing data.
Beta
Per-column information about the shape of the data distribution.
Beta
Two other components (`ebm_model`, `forecast_model`) exist behind the scenes as **dependencies** — they hold the heavy fitted state and are consumed by the user-visible ones. You don't pick them in the editor; they auto-run when their dependent component is selected.
## Anatomy of a component
Every component declares the same metadata:
| Field | Purpose |
| - | - |
| `name` | Catalog ID (e.g. `column_stats`, `ebm_graphs`). Stable across versions. |
| `display.label` | Human-readable name shown in the UI. |
| `description` | One-sentence summary. |
| `dependencies` | Other components that must run first. The dispatcher topologically orders them. |
| `inputs` | Typed parameters the user fills in (column references, numeric thresholds, etc.). |
| `compute_profile` | `LambdaProfile` for fast steps; `EcsProfile(tier)` for the heavier ones (EBM fitting, UMAP). |
| `agent_config` | What the Summand chat agent can read and filter. |
| `display.blocks` | How the artifact renders in the UI — tables, charts, key/value pairs. Some components ship with bespoke React viewers instead. |
When you select a component in the experiment editor, the catalog is what tells the form which inputs to render and how to validate them.
## How components run
```
Experiment fires (manual / scheduled)
│
▼
trigger-semantic-layer (Lambda)
│
▼
Step Functions dispatcher
│
├─ ResolveComponentPlan (topological sort → waves)
│
├─ For each wave (in order):
│ └─ Distributed Map fan-out (parallel within wave)
│ ├─ Lambda components → component-runner Lambda
│ └─ Fargate components → ECS task
│
├─ WriteManifest (consolidates results → manifest.json)
│
└─ UpdateSemanticLayerRecord (marks version completed)
Outputs land in:
- S3: semantic-layers/{datasetId}/versions/{N}/{component}.json
- DynamoDB summand-task-outputs (per-run output items)
```
Components within a wave run in parallel; waves run sequentially because of dependencies.
## Reading component outputs
Three places where outputs surface:
* **Dataset detail → Components tab.** Per-component status plus the latest artifact, rendered with either the component's declared blocks or a bespoke React viewer (for EBM, UMAP, and Feature metadata).
* **Summand chat.** The `analyze` tool resolves the latest version of any component and returns its data inline. Filtering by column or feature name is supported through each component's `agent_config`.
* **Downstream views.** Components write to S3 paths and DynamoDB items you can join against in custom SQL views.
## What's not a component
A few analyses run *outside* the component catalog:
* **Surprise finding** has its own Step Functions pipeline that runs alongside the semantic-layer dispatcher. It's not selectable in the experiment editor today — surprises surface through their own page in the product.
* **Sync / curation** (the read-from-source-and-write-to-Parquet step) is part of the connector pipeline, not the component catalog.
* **Chat itself** isn't a component — it's a separate Lambda (`claude-stream`) that *consumes* component outputs via the `analyze` tool.
## Catalog stability
The catalog is small and slow-moving. Most recent commits are bug fixes (cache improvements, edge-case handling) rather than new components. If you have a need for analysis the catalog doesn't cover, custom components are on the roadmap for Enterprise — email [support@intelligible.ai](mailto:support@intelligible.ai) and tell us what you'd build.
## Per-component details
* [**Column stats**](/concepts/components/column-stats) — what runs by default on every dataset.
* [**Predictors (EBM)**](/concepts/components/ebm) — interpretable model fitting, with shape functions and pairwise interactions.
* [**Correlation-association matrix**](/concepts/components/correlation-association-matrix) — meaasures of association between every column pair.
* [**Forecast**](/concepts/components/forecast) — time-series projection with prediction intervals.
* [**Feature metadata**](/concepts/components/feature-metadata) — LLM-generated column descriptions.
* [**UMAP embedding**](/concepts/components/umap) — 2-D projection for clustering and similarity.
# Column stats
Source: https://docs.summand.com/concepts/components/column-stats
Per-column distributions, missingness, cardinality, and numeric summaries. Runs automatically on every dataset.
`column_stats` is the baseline component. It runs on first ingest of any dataset (no experiment configuration needed) and powers the Overview tab, dataset summaries shown to Summand, and the schema-level views the rest of the product builds on.
## What it computes
For every column in the dataset:
* **Common stats** — `name`, `dtype`, `count`, `nullCount`, `nullPct`, `uniqueCount`, `uniquePct`.
* **Numeric columns** — `min`, `max`, `mean`, `median`, `std`, first and third quartiles, `zeroCount`, `zeroPct`.
* **Categorical / string columns** — top 10 distinct values with counts.
Plus dataset-level totals: `totalRows`, `totalColumns`.
## Inputs
None. `column_stats` takes no configuration — it always runs on the full dataset.
## Output shape
```json theme={null}
{
"totalRows": 50000,
"totalColumns": 24,
"columns": [
{
"name": "revenue",
"dtype": "float64",
"count": 49872,
"nullCount": 128,
"nullPct": 0.26,
"uniqueCount": 12451,
"uniquePct": 24.94,
"min": 0.0,
"max": 9842.5,
"mean": 142.7,
"median": 89.5,
"std": 218.3,
"q1": 32.0,
"q3": 184.2,
"zeroCount": 4,
"zeroPct": 0.01
},
{
"name": "tier",
"dtype": "object",
"count": 50000,
"nullCount": 0,
"nullPct": 0.0,
"uniqueCount": 3,
"uniquePct": 0.01,
"topValues": [
{ "value": "free", "count": 38240 },
{ "value": "pro", "count": 9810 },
{ "value": "enterprise", "count": 1950 }
]
}
]
}
```
The artifact is written as `column_stats.json` to the dataset's versioned S3 path.
## Where it shows up
* **Dataset detail → Overview tab** reads the latest `column_stats` to render the column-by-column summary.
* **Summand chat** queries it via the `analyze` tool — *"What's the missingness of `revenue`?"* resolves to a filtered read of the artifact.
* **The Predictors component** uses column stats internally to make feature-engineering decisions (numeric vs. categorical, low- vs. high-cardinality).
## Compute profile
| Profile | Memory | Timeout |
| - | - | - |
| Lambda | 2 GB | 120 s |
For most datasets this finishes in a few seconds. The component reads the curated Parquet, computes the stats in pandas, and writes the JSON.
## Filtering from chat
Summand can ask for a single column instead of the whole stats blob:
```text theme={null}
analyze({ component: "column_stats", target: ..., params: { column_name: "revenue" } })
```
The agent receives just that column's stats — efficient even on wide tables.
# Correlation-association matrix
Source: https://docs.summand.com/concepts/components/correlation-association-matrix
Appropriate measure of association for each column pair — Pearson's correlation coefficient, Cramér's V, or correlation ratio, depending on column types.
This component is currently in beta and may be subject to changes or instability.
The **Correlation-Association Matrix** component answers the question: *which columns move together, and how strongly?* It does **not** answer questions of causation — two things happening together does not mean one causes the other.
For every column pair in the dataset, the component selects one of three association measures based on the column types involved, then assembles a summary table sorted by absolute association strength.
## What it computes
The measure used for a given pair depends on the types of the two columns:
| Column pair | Measure | Range |
| - | - | - |
| Numeric–numeric | Pearson's correlation coefficient | −1 to +1 |
| Categorical–categorical | Cramér's V statistic (with Bergsma's bias-correction) | 0 to +1 |
| Numeric–categorical | Correlation ratio | 0 to +1 |
Notes:
* Columns that are neither numeric nor categorical (e.g. timestamps, timedelays) are skipped.
* Cramér's V bias correction means a value of 0 can mean either no association or one too weak to distinguish from noise at this sample size.
* Cramér's V and the correlation ratio also report how many categories were involved in each categorical column. Together with the sample size, this helps interpret how meaningful the association value is.
## Inputs
None. The component runs on the full dataset with no configuration required.
## Output shape
```json theme={null}
{
"summary_table": [
{
"column_1": "length_of_stay",
"column_2": "insurance_type",
"association": 0.431,
"method": "correlation_ratio"
},
{
"column_1": "heart_rate",
"column_2": "cholesterol",
"association": 0.287,
"method": "correlation_coefficient"
},
{
"column_1": "blood_type",
"column_2": "icd_code",
"association": 0.104,
"method": "cramer_v_statistic"
}
],
"associations": [
{
"column_pair": "length_of_stay & insurance_type",
"column_1": "length_of_stay",
"column_1_type": "numeric",
"column_2": "insurance_type",
"column_2_type": "categorical",
"sample_size": 4821,
"association_is_computed": true,
"association_type": "correlation_ratio",
"association_value": 0.431,
"number_of_categories": 4
},
{
"column_pair": "blood_type & icd_code",
"column_1": "blood_type",
"column_1_type": "categorical",
"column_2": "icd_code",
"column_2_type": "categorical",
"sample_size": 4821,
"association_is_computed": true,
"association_type": "cramer_v_statistic",
"association_value": 0.104,
"number_of_categories_in_column_1": 4,
"number_of_categories_in_column_2": 812
},
...
]
}
```
`summary_table` contains each pair once, sorted by descending absolute association value. `associations` contains each pair **twice** (both orderings of the columns), so that agent lookups filtering on `column_1` alone can find any pair. The artifact is written as `correlation_association_matrix.json`.
## Display
The component renders a **sortable table** of all column pairs where the association could be computed. Each row shows the two column names, the association value, and the method. The table is sorted by absolute association strength by default.
## Filtering from chat
Summand can query associations in two ways:
```text theme={null}
# Association between two specific columns
analyze({
component: "correlation_association_matrix",
params: { association_between_two_columns: "heart_rate & cholesterol" }
})
# All associations involving one column
analyze({
component: "correlation_association_matrix",
params: { all_associations_with_column: "length_of_stay" }
})
```
The `association_between_two_columns` parameter expects the exact column names joined with `&` as separator — the order does not matter since the `associations` list stores both orderings.
## Use cases
* **Preliminary feature selection** — identify columns that vary strongly together and drop redundant ones before training a model.
* **Identify co-occurring groups** — e.g. patients with diagnoses A and B who are statistically likely to also have diagnosis C.
* **Measure group impact on outcomes** — how does insurance type or care setting relate to length of stay?
* **Exploratory data analysis** — surface unexpected relationships in a new dataset.
## Compute profile
| Profile | Profile |
| - | - |
| Fargate | 2 CPU, 8 GB |
The component runs in pandas on the curated Parquet. Pairwise computation scales as O(n\_columns ^ 2); on wide datasets (hundreds of columns) runtime grows accordingly, but the per-pair work is cheap.
## Common gotchas
Two things will cause a column to be excluded: it's neither numeric nor categorical (e.g. a timestamp column) or it's a unique identifier — a column where every value is distinct. Primary-key-style ID columns fall into this last category.
This happens when at least one column in the pair has zero variance (all rows share the same value), when there are no rows where both columns have non-null values simultaneously, when one column's cardinality exactly equals the number of valid rows for that pair (it's trivially, perfectly predictive of the other, so there's nothing informative to measure), or, for a categorical pair, when the contingency table implied by the two columns' cardinalities would be too large to compute safely. The `reason_not_computed` field in the `associations` list explains which case applies.
Correlation, Cramér's V, and the correlation ratio all measure co-movement or predictability, not causation. A high value tells you the columns move together; it says nothing about why.
# Distribution profile
Source: https://docs.summand.com/concepts/components/distribution-profile
Characterises the shape of each column's data distribution: skewness, kurtosis, best-fit parametric distribution, modality, and density plots.
This component is currently in beta and may be subject to changes or instability.
The **Distribution Profile** component answers the question: *what is the shape of each column's data distribution?*
## Use cases
* **Fraud detection preprocessing** — Is the transaction amount column heavy-tailed enough to warrant a log transformation, or is a Normal assumption reasonable?
* **Sensor data validation** — Are the readings from a temperature sensor unimodal as expected, or does a second peak suggest a recurring calibration fault?
* **Feature engineering** — Which columns are highly skewed and would benefit from normalisation before being fed into a model?
## What it computes
* **Skewness and kurtosis**: measures of distributional shape — how lopsided and how heavy-tailed each numeric column is.
* **Best-fit parametric distribution**: the best-fitting distribution from a candidate set, along with its fitted parameters.
* **Shapiro-Wilk normality test**: a $p$-value testing whether each numeric column is normally distributed.
* **Modality**: whether each numeric column's distribution is unimodal, bimodal, or multimodal.
* **Kernel density estimate (KDE)**: a smooth estimate of each numeric column's probability density.
* **Histograms**: a 30-bin histogram for each numeric column, and a proportion histogram for categorical columns with 10 or fewer unique categories.
## Display
The Distribution Profile component displays the following in the Catalog.
* **Distribution profiles table**: skewness, kurtosis, best-fit distribution and its parameters, Shapiro-Wilk $p$-value, modality, and top peaks — one row per numeric column.
* **Fitted distributions**: all candidate parametric distributions ranked by BIC, with fitted parameters and goodness-of-fit $p$-value — one table per numeric column.
* **Numeric histograms**: a 30-bin histogram per numeric column.
* **Categorical histograms**: a proportion histogram per low-cardinality categorical column (10 or fewer unique categories).
* **Kernel density estimates**: a smooth density curve per numeric column.
## Inputs
| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `peak_prominence_cutoff` | number | No | `0.1` | Controls how pronounced a peak in the distribution must be to count toward modality. Increase to ignore minor bumps; decrease to detect subtler ones. |
## Output shape
```json theme={null}
{
"distribution_profiles": [
{
"column": str,
"sample_size": int,
"skewness": float,
"kurtosis": float,
"best_fit_distribution": str | None,
"best_fit_distribution_parameters": [{"name": str, "value": float}] | None,
"best_fit_sample_size": int,
"shapiro_wilk_p_value": float, # present when Shapiro-Wilk was computed
"shapiro_wilk_reason_not_computed": str, # present instead when Shapiro-Wilk was not computed
"shapiro_wilk_sample_size": int,
"modality": "unimodal" | "bimodal" | "multimodal",
"peaks": [
{"location": float, "prominence": float},
# ... top 20 most prominent peaks, ordered by descending prominence
],
},
# ... numeric columns only
],
"fitted_distributions": [
{
"column": str,
"sample_size": int,
"reason_not_computed": str, # present when column has fewer than 2 observed values
"distributions": [
{
"distribution_name": str,
"bayesian_information_criterion": float, # absent when fitting failed for this distribution
"parameters": [{"name": str, "value": float}], # absent when fitting failed for this distribution
"goodness_of_fit_p_value": float, # absent when fitting failed for this distribution
"reason_not_computed": str, # present when fitting failed for this distribution
},
# ... one entry per candidate distribution, ranked by descending BIC
],
},
# ... numeric columns only
],
"numeric_histograms": [
{
"column": str,
"plot_data": [
{
"left": float,
"center": float,
"right": float,
"percentage": float,
},
# ... 30 entries
],
},
# ... numeric columns only
],
"categorical_histograms": [
{
"column": str,
"plot_data": [
{
"category": str,
"percentage": float,
},
# ... one entry per unique category, ordered by descending percentage
],
},
# ... categorical columns with ≤ 10 unique categories only
],
"kernel_density_estimates": [
{
"column": str,
"bandwidth": float,
"plot_data": [
{
"sample_point": float,
"density_estimate": float,
},
# ... 100 entries
],
},
# ... numeric columns only
],
}
```
## Filtering from chat
Summand can query the distribution profile artifact in a variety of ways:
```text theme={null}
# Skewness, kurtosis, best-fit distribution, Shapiro-Wilk p-value, modality, and peaks for a specific column
analyze({
component: "distribution_profile",
params: { distribution_shape_for_column: "transaction_amount" }
})
# All candidate distributions ranked by BIC, with fitted parameters and goodness-of-fit p-value
analyze({
component: "distribution_profile",
params: { list_of_fitted_distributions_for_column: "transaction_amount" }
})
# 30-bin histogram for a specific numeric column
analyze({
component: "distribution_profile",
params: { numeric_histogram_for_column: "transaction_amount" }
})
# Proportion histogram for a specific categorical column
analyze({
component: "distribution_profile",
params: { categorical_histogram_for_column: "product_category" }
})
# KDE plot data and bandwidth for a specific numeric column
analyze({
component: "distribution_profile",
params: { kernel_density_estimate_for_column: "transaction_amount" }
})
```
## Compute profile
| Profile | Value |
| - | - |
| Fargate | 2 CPU, 8 GB |
# Predictors (EBM)
Source: https://docs.summand.com/concepts/components/ebm
Fits an Explainable Boosting Machine and writes feature importance, per-feature shape functions, and pairwise interactions.
The **Predictors** component is a two-piece chain:
* `ebm_model` (internal) — fits the EBM and persists it to S3.
* `ebm_graphs` (user-visible) — extracts the global explanation, serializes shape functions and importance scores, and writes the JSON the dataset page renders.
You pick `ebm_graphs` in the experiment editor; `ebm_model` runs automatically as a dependency. The split exists so changing display-only behavior doesn't refit the model.
## Why EBMs
[Explainable Boosting Machines](https://github.com/interpretml/interpret) sit at the intersection of "interpretable enough to read" and "accurate enough to ship":
* **Per-feature shape functions are exact.** No SHAP approximations. The model literally is the sum of those curves plus a small number of pairwise interaction terms.
* **Predictions decompose row-by-row.** Every prediction has an additive breakdown — *"here's exactly which features pushed this score up or down."*
* **Categorical features handled natively.** EBMs use `feature_types=['nominal']` for categoricals; no one-hot encoding pollution in the explanations.
* **Performance is competitive.** Within a few points of XGBoost on most tabular targets, while remaining fully readable.
## Inputs
| Input | Type | Required | Description |
| - | - | - | - |
| `target_column` | column reference | ✓ | The column to explain or predict. Must be in the dataset's schema. |
The target's distribution determines the task type:
* **Binary classification** — exactly two distinct values.
* **Regression** — continuous numeric.
* **Multiclass** is on the roadmap; today the component rejects targets with three or more distinct categorical values.
## Output shape (`ebm_graphs`)
```json theme={null}
{
"features": [
{
"name": "tenure_months",
"index": 0,
"importance": 0.342,
"type": "continuous",
"names": [0, 12, 24, 36, 48, 60, 72],
"scores": [-0.85, -0.34, 0.12, 0.41, 0.47, 0.39, 0.21],
"upper_bounds": [-0.71, -0.21, 0.24, 0.55, 0.62, 0.51, 0.34],
"lower_bounds": [-0.99, -0.47, 0.00, 0.27, 0.32, 0.27, 0.08],
"density": {
"names": [...],
"scores": [...]
}
},
{
"name": "region & plan_tier",
"index": 14,
"type": "interaction",
"importance": 0.082,
"scores": [[...], [...]],
"names": [["us-east", "us-west", "eu"], ["free", "pro"]]
}
],
"feature_names": [...],
"feature_importances": [...],
"metadata": { ... }
}
```
The artifact is written gzipped as `graphs.json.gz`. Each feature has:
* **`scores`** — the y-axis of the shape function (the contribution at each x-value).
* **`upper_bounds` / `lower_bounds`** — confidence bounds, derived from EBM's bagged ensemble.
* **`density`** — how many rows fall at each x-value (helps you spot when the curve is undersupported).
* **`importance`** — the global feature importance (mean absolute contribution across the training set).
Pairwise interaction terms appear as 2-D `scores` matrices with two `names` arrays (one per axis).
## Display
The Predictors component ships with a bespoke React viewer (`EBMVisualization`) instead of the generic block renderer. It draws:
* **Feature importance bar chart** — sorted descending.
* **Shape functions per feature** — line chart with confidence band, density underneath.
* **Pairwise interactions as heatmaps** — for the small number of interaction terms EBM keeps.
## Filtering from chat
Summand reads `ebm_graphs` via the `analyze` tool. Without parameters, it gets the summary fields (importances, feature names). With a `feature_name` parameter, it gets the full shape function for one feature plus an LTTB-downsampled version for context efficiency:
```text theme={null}
analyze({ component: "ebm_graphs", target: ..., params: { feature_name: "tenure_months" } })
```
This lets the agent ground answers like *"Why is tenure important?"* in the actual shape function rather than approximating from importance alone.
## Compute profile
| Component | Profile | Tier |
| - | - | - |
| `ebm_model` | Fargate | 4 CPU, 16 GB; scales with row count |
| `ebm_graphs` | Fargate | 2 CPU, 8 GB |
Most datasets fit in a few minutes on the standard tier. Datasets with millions of rows or hundreds of features take longer; the dispatcher routes them to the larger Fargate tier automatically when the row count crosses an internal threshold.
## Common gotchas
Either the target genuinely is noise relative to the columns you provided, or the target is a near-copy of one of the inputs (e.g. `revenue = price × quantity` and you have all three). EBM excludes near-tautological features, which can leave the result looking empty. Try removing suspect feature columns and re-running.
Two causes: insufficient data (under \~500 rows for the relevant feature value), or the feature is near-collinear with another feature. Check the density underneath the curve — if it's spiky, the curve is undersupported in that region.
EBM needs at least a few hundred non-null target rows. Filter the source before running the experiment, or pick a different target.
# Feature metadata
Source: https://docs.summand.com/concepts/components/feature-metadata
LLM-generated, business-friendly descriptions for every dataset column. Powers chat grounding.
`feature_metadata` produces one short, human-readable description per column, plus a dataset-level summary. The descriptions are generated by Claude using column statistics and sample values as context. They show up in the dataset's Configuration sidebar, in column tooltips, and most importantly as **grounding** the chat agent reads when answering questions about your data.
This component runs once per dataset version. Re-running only re-generates if the schema or context has changed.
## Why it exists
Most dataset columns have names like `ord_amt_usd_ttl` or `mau_d30` — meaningful to whoever set up the warehouse, opaque to anyone else. Without semantic context:
* Summand has to guess what a column represents from the name alone.
* Chart suggestions and view-builder field labels read like database internals.
* New teammates can't navigate the dataset without a SME walking them through it.
`feature_metadata` is the bridge. The Anthropic API call sees the column name, dtype, sample values, and column stats, and returns a one-sentence plain-English description plus a dataset-level summary.
## Inputs
None. The component reads the curated Parquet sample and the column-stats artifact.
## Output shape
```json theme={null}
{
"context": "E-commerce orders for an enterprise SaaS company. Each row is an order placed by a customer, with payment, geography, and post-checkout fulfilment status.",
"features": {
"order_id": "Unique identifier for the order. Always populated.",
"customer_id": "Foreign key to the customers table. Always populated.",
"ord_amt_usd_ttl": "Total order amount in USD, including tax and shipping. Range $0–$84k, mean ~$430.",
"ship_country": "ISO 3166-1 alpha-2 country code where the order shipped. 78% US.",
"checkout_at": "Timestamp the customer completed checkout, in UTC."
}
}
```
`context` is the dataset-level summary; `features` is keyed by column name. The artifact is `feature_metadata.json`.
## Display
The Feature metadata component ships with a bespoke React viewer (`FeatureMetadataView`):
* **Dataset context** rendered at the top.
* **Per-column descriptions** in a sortable table alongside the column's dtype and missingness.
* **Inline editing** — you can override any description; overrides take precedence on re-run.
## Where the descriptions show up
* **Dataset detail → Components tab** — viewable like any other component.
* **Configuration sidebar** — column tooltips show the description.
* **View builder** — the field picker shows the description as a hint under each column name.
* **Summand chat** — the agent reads the dataset context and per-column descriptions on every chat turn, grounding answers in business meaning rather than column-name guesses.
## Filtering from chat
Summand can ask for a specific column's metadata:
```text theme={null}
analyze({ component: "feature_metadata", target: ..., params: { column_name: "ord_amt_usd_ttl" } })
```
Returns just that column's description plus the dataset-level context.
## Compute profile
| Profile | Memory | Timeout |
| - | - | - |
| Lambda | 2 GB | 600 s |
The long timeout is because the component calls the Anthropic API for descriptions. It's still typically under a minute end-to-end; the timeout is there to absorb occasional API slowness.
## Privacy
Column descriptions are generated by sending the Anthropic API a small payload: column names, dtypes, basic stats from `column_stats`, and a handful of sample values. The full dataset is **not** sent. Anthropic is a listed subprocessor — see [Compliance](/enterprise/compliance) for the data-handling agreement.
If your organization has policies against sending column samples to external APIs, contact [support@intelligible.ai](mailto:support@intelligible.ai) — Enterprise customers can scope LLM-using components per-org.
## Override and refresh
Dataset owners can override any description from the **Components** tab — overrides persist across re-runs. To regenerate descriptions (e.g. after major schema changes), re-run the component manually from the Components tab or include it in a scheduled experiment.
# Forecast
Source: https://docs.summand.com/concepts/components/forecast
Time-series projection with 95% prediction intervals, using a Holt-Winters model under the hood.
The **Forecast** component projects future values for a single time-series target. It's a two-piece chain:
* `forecast_model` (internal) — fits a Holt-Winters / SES model on the aggregated history and persists the fit to S3.
* `forecast` (user-visible) — pulls the cached fit, calls `.forecast(steps=horizon)`, derives 95% prediction intervals, and emits the JSON the chat UI renders.
The split is deliberate: re-running with a different horizon shouldn't refit the model. Statsmodels' own docs are explicit on this — `refit` is for new observations, not for varying the projection horizon. Splitting the components lets the dispatcher cache the fit and only re-run the cheap projection step when only `horizon` changes.
## Inputs
| Input | Type | Required | Description |
| - | - | - | - |
| `date_column` | column reference | ✓ | The timestamp column. Must parse as a date. |
| `target_column` | column reference | ✓ | The numeric column to project forward. |
| `horizon` | integer | optional (default 12) | How many steps to forecast. Units depend on the inferred frequency (months, weeks, days, etc.). |
The frequency is inferred from the spacing of `date_column` values — daily, weekly, monthly, quarterly. The component picks an appropriate seasonal period (12 for monthly, 7 for daily, etc.).
## Output shape
```json theme={null}
{
"frequency": "MS",
"horizon": 12,
"model": "Holt-Winters (additive seasonal, period=12)",
"seasonality_period": 12,
"rmse": 1842.5,
"first_history_period": "2023-01-01",
"last_history_period": "2026-04-01",
"last_forecast_period": "2027-04-01",
"series": [
{ "period": "2023-01-01", "value": 12450.0, "kind": "history" },
{ "period": "2023-02-01", "value": 13200.0, "kind": "history" },
...
{ "period": "2026-05-01", "value": 18900.0, "lower": 17050.0, "upper": 20750.0, "kind": "forecast" },
{ "period": "2026-06-01", "value": 19200.0, "lower": 17150.0, "upper": 21250.0, "kind": "forecast" },
...
]
}
```
The `series` array combines history and forecast — `kind` flags which is which, and `lower` / `upper` (the 95% interval) are present only on forecast points. The artifact lives at `forecast.json`.
## Display
The Forecast component ships with a chart-block renderer:
* **Line chart** of history + forecast in one series, with a shaded confidence band over the forecast portion.
* **Model details** key/value block — frequency, seasonality period, RMSE.
* **Forecast table** — per-period numeric output for copy-paste.
## Filtering from chat
The full `forecast` artifact is small (history + horizon points), so chat usually reads it whole rather than filtering. Summand surfaces summary fields like `rmse`, `last_history_period`, and `last_forecast_period` for at-a-glance answers, with the full series available on demand.
## Compute profile
| Component | Profile | Memory | Timeout |
| - | - | - | - |
| `forecast_model` | Lambda | 2 GB | 180 s |
| `forecast` | Lambda | 1 GB | 60 s |
Both run on Lambda — Holt-Winters fits in seconds for typical historical lengths. There's no Fargate path because the cost of a refit isn't worth the parallelism.
## Use cases
* **Revenue / cost projections** — monthly forecasts with prediction intervals for budgeting.
* **Headcount / capacity planning** — extending a weekly headcount series N weeks forward.
* **Operational metrics** — daily request volume, latency, or error rate trended forward.
## Common gotchas
Holt-Winters captures level, trend, and seasonality but **not** structural breaks or external shocks. If your series has a known regime change (e.g. major launch, pricing change), the forecast will smooth across it. Filter the source to a stable post-change window via a [view](/concepts/views), then point the experiment at the view.
Wide intervals mean the model has high residual variance — the historical series isn't well-explained by level + trend + seasonal pattern. Either the data is genuinely volatile, or there's missing structure (e.g. a covariate the model can't see). Holt-Winters is univariate; if you need multivariate forecasting, that's roadmap.
The inference looks at the spacing of `date_column` values. If your data has gaps or irregular cadence, frequency detection can pick the wrong period. Aggregating to a regular frequency in a [view](/concepts/views) before the experiment usually fixes this.
# Missing-value patterns
Source: https://docs.summand.com/concepts/components/missing-value-patterns
Identifies patterns in the missing data: determines which columns go missing together and whether values are missing at random or not.
This component is currently in beta and may be subject to changes or instability.
The **Missing-Value Patterns** component answers the question: *are missing values random or do they follow a pattern?*
## Use cases
* **Retail data quality** — Are product weight and dimensions always missing together, or are these independent supplier data problems?
* **Selective disclosure** — Are customers who skip the household income question also refusing to answer questions about their spending habits?
* **Sensor fault attribution** — Are multiple conveyor-belt sensors dropping out together, suggesting a shared infrastructure failure?
## What it computes
* $p$-value for Little's MCAR test: values below 5% suggest that data is **not** missing at random.
* Missing-value pattern frequencies: which combinations of columns go missing together most often?
* Conditional missingness matrix: when one column goes missing, which other column is most often missing?
* Missingness correlation matrix: are some column pairs always missing together, or never missing at the same time? This is done by turning each column into a boolean indicator via the question "is this row missing in this column?" and then computing Pearson's correlation coefficient between the resulting boolean columns. A value of `+1` indicates that the two columns always go missing together; a value of `-1` indicates that for every row, exactly one of the two columns is missing: they are never both missing at the same time, and never both observed.
## Display
The missing-value patterns component displays several pieces of information in the Catalog.
* Result of Little's MCAR test: the $p$-value, the sample size, and which numeric columns were used. Only numeric columns with non-zero variance are included; constant columns and entirely-missing columns are excluded.
* Missing-value pattern frequencies: how often does each missing-value pattern occur, as a percentage of all rows?
(For datasets with many distinct missing-value patterns, only the 100 most common patterns are provided,
as well as any patterns where only a single column is missing -- even if it is not among the 100 most common.)
* Conditional missingness matrix: when the *reference* column is missing, how often is the *conditionally missing* columns also missing?
* Missingness correlation matrix: how often two columns go missing together and how often only one of them goes missing.
## Inputs
None. The component runs on the full dataset with no configuration required.
## Output shape
```json theme={null}
{
"little_mcar_test": {
"p_value": float,
"sample_size": int,
"n_columns_used": int,
"columns_used": list[str], # numeric columns with non-zero variance used in the test; constant columns and entirely-missing columns are excluded
},
"missing_value_pattern_frequencies": [
# Sorted by descending frequency_as_percentage; ties broken lexicographically by missing_columns.
{
"frequency_as_percentage": float,
"missing_columns": str, # column names joined by " & " in lexicographic order;
# empty string for complete rows
},
# ...
],
"missing_value_pattern_frequencies_top_10": [...], # same schema, first 10 entries
"conditional_missingness_matrix": [
# Not sorted. Use conditional_missingness_matrix_top_10 for the highest-rate entries.
{
"directional_column_pair": str, # "col_a -> col_b"
"reference_column": str,
"conditionally_missing_column": str,
"conditional_missing_rate": float, # P(col_b missing | col_a missing)
"n_reference_rows_used": int, # rows where col_a is missing
},
# ...
],
"conditional_missingness_matrix_top_10": [...], # same schema; sorted by descending conditional_missing_rate, ties broken lexicographically by (reference_column, conditionally_missing_column)
"missingness_correlation_matrix": [
# Not sorted. Each unordered pair stored twice (both orderings) so that filtering on
# column_1 alone finds every correlation involving that column.
# Use missingness_correlation_matrix_top_10 for the entries with the largest absolute value
# of the coefficient.
{
"column_pair": str, # "col_1 & col_2"
"column_1": str,
"column_2": str,
"missingness_correlation_coefficient": float,
},
# ...
],
"missingness_correlation_matrix_top_10": [
# Unique pairs only (stored once), sorted by descending absolute value of the coefficient; ties broken lexicographically by (column_1, column_2).
{
"column_pair": str,
"column_1": str,
"column_2": str,
"missingness_correlation_coefficient": float,
},
# ...
],
}
```
When Little's MCAR test cannot be run, `little_mcar_test` contains a single `reason_not_computed` field instead of the fields above:
```json theme={null}
{
"little_mcar_test": {
"reason_not_computed": str
# Possible values:
# "[NoValidNumericColumns] ..." — no numeric columns with non-zero variance
# "[NoMissingValuesInValidNumericColumns] ..." — included columns are fully observed
# "[CollinearityPresent] ..." — covariance matrix is singular
# "[NegativeDegreesOfFreedom] ..." — internal error; should not occur in practice
},
...
}
```
## Filtering from chat
Summand can dig into the missing-value patterns in a variety of ways:
```text theme={null}
# How often a specific missing-value pattern appears (columns listed alphabetically)
analyze({
component: "missing_value_patterns",
params: { missing_value_pattern: "dimensions & weight" }
})
# How often the second column is missing given that the first column is missing
analyze({
component: "missing_value_patterns",
params: { conditional_missingness_directed_pair: "household_income -> spending_habits" }
})
# How often all other columns go missing given that this reference column is missing
analyze({
component: "missing_value_patterns",
params: { conditional_missingness_reference_column: "household_income" }
})
# How often this column goes missing given that one of the other columns is missing
analyze({
component: "missing_value_patterns",
params: { conditionally_missing_column: "spending_habits" }
})
# The correlation between the boolean missingness indicators of two specific columns
analyze({
component: "missing_value_patterns",
params: { missingness_correlation_column_pair: "dimensions & weight" }
})
# The correlation between the boolean missingness indicators of one column and all other columns
analyze({
component: "missing_value_patterns",
params: { missingness_correlation_column: "weight" }
})
```
## Compute profile
| Profile | Profile |
| - | - |
| Fargate | 2 CPU, 8 GB |
# Outlier report
Source: https://docs.summand.com/concepts/components/outlier-report
Identify per-column outliers using quartile-based methods and multivariate outliers using an isolation forest.
This component is currently in beta and may be subject to changes or instability.
The **Outlier Report** component surfaces unusual values at two levels of granularity: within individual columns, and across combinations of columns. A row may look unremarkable in any single column while still being anomalous as a whole — the multivariate analysis is specifically designed to catch those cases.
The output is a warning, not a verdict. Values and rows flagged here are worth a closer look, not outright dismissal.
## What it computes
The component runs two independent analyses.
**Per-column outlier report** — for each column, the appropriate method is applied based on column type:
* **Numeric columns** — Tukey's fences (Q1 − 1.5 × IQR, Q3 + 1.5 × IQR) define the normal range. Values outside these fences are counted as outliers, and the 10 values furthest from the median are returned as `extreme_values`.
* **Categorical columns** — rare categories are identified and returned.
**Multivariate outlier report** — an [isolation forest](https://ieeexplore.ieee.org/document/4781136) is trained on all numeric columns. This isolation forest then assigns an *anomaly score* between 0 and 1 to every row, and rows with scores sufficiently near 1 are identified as anomalous.
For each row flagged as anomalous, the features identified by the isolation forest as most likely to be responsible for this anomaly are reported as the `likely_responsible_columns`.
Columns that are neither numeric nor categorical (e.g. timestamps) and unique identifier coumns are excluded from both analyses.
## Inputs
All inputs are optional. The component runs with sensible defaults and most users will not need to change anything.
| Input | Description | Default |
| - | - | - |
| `n_estimators` | Number of decision trees used to detect anomalies. More trees means more stable results but slower runtime. | 100 |
| `max_samples` | Number of rows each tree is trained on. Scales automatically with dataset size, from 256 (small datasets) up to 2 048 (very large ones). | auto |
| `anomaly_score_cutoff` | How unusual a row must be before it's flagged. Lower values flag more rows; higher values flag fewer. | 0.595 |
| `top_k_likely_responsible_columns` | How many columns to show as likely contributors for each flagged row. | 3 |
| `max_depth` | Controls how deep into each tree the attribution analysis looks. Scales automatically with dataset size. | auto |
## Output shape
````json theme={null}
{
"per_column_outlier_report": [
{
"column": "price_per_sqft",
"lower_fence": 87.50,
"upper_fence": 612.50,
"outlier_count": 38,
"outlier_pct": 0.76,
"extreme_values": [
{ "value": 1840.0, "row_index": 7823 },
{ "value": 1705.0, "row_index": 2104 }
]
}
{
"column": "property_type",
"rare_values": [
{ "value": "Houseboat", "count": 4, "frequency": 0.00008 },
{ "value": "Timeshare", "count": 2, "frequency": 0.00004 }
]
}
],
"multivariate_outliers_report": {
"anomaly_score_cutoff": 0.5946,
"outlier_count": 61,
"outlier_pct": 1.22
},
"multivariate_outliers": [
{
"row_index": 7823,
"anomaly_score": 0.847,
"likely_responsible_columns": [
{ "column": "sale_price", "prevalence_pct": 54.1 },
{ "column": "lot_size_sqft", "prevalence_pct": 31.2 },
{ "column": "year_built", "prevalence_pct": 14.7 }
]
}
],
"anomaly_score_distribution": [
{ "anomaly_score": 0.005, "proportion": 0.031 },
{ "anomaly_score": 0.015, "proportion": 0.044 }
]
}```
## Display
The Outlier Report renders four blocks:
- **Per-column outlier report table** — one row per column showing fences and outlier counts (numeric), or rare value lists (categorical).
- **Multivariate outliers summary** — key/value block with `outlier_count`, `outlier_pct`, and `anomaly_score_cutoff`.
- **Anomaly score distribution chart** — area chart of the full score distribution, useful for assessing whether the cutoff is well-placed.
- **Multivariate outliers table** — one row per flagged row with its anomaly score and likely responsible columns.
## Filtering from chat
Summand can query the report in two ways:
```text
# Per-column report for one column
analyze({
component: "outlier_report",
params: { column_name: "year_built" }
})
# Multivariate outlier detail for one anomalous row,
# identified by its 0-indexed row index
analyze({
component: "outlier_report",
params: { multivariate_outlier: 10291 }
})
````
By default, Summand sees the summary fields (`per_column_outlier_report` and `multivariate_outliers_report`) which are compact enough for quick answers. Drilling into a specific column or row fetches only that record.
## Compute profile
| Profile | CPU | Memory | Scales with rows |
| - | - | - | - |
| Fargate | 4 vCPU | 16 GB | Yes |
## Use cases
* **Data quality review** — catch data-entry errors, unit mismatches, or upstream pipeline bugs before they affect downstream models.
* **Clinical / operational anomaly detection** — surface patients or events with unusual combinations of values that wouldn't trigger any single-column alert.
* **Pre-modelling sanity check** — identify extreme values that could distort training before fitting a predictive model.
* **Rare-category discovery** — find low-frequency labels in categorical columns that may need consolidation or special handling.
## Common gotchas
This is expected and is one of the main reasons to run the multivariate analysis. A row with `height = 6'2", y = 135 lb` can be perfectly normal for each column individually while being anomalous in combination. The isolation forest detects the combination; the per-column Tukey fences do not.
The isolation forest requires at least one numeric column and at least one row where all numeric columns are non-null simultaneously. If every numeric column has at least one missing value in every row — or if there are no numeric columns at all — the multivariate analysis cannot run. The per-column report still runs for any columns it can handle.
The 1% threshold is applied to cumulative frequency, and ties at the boundary are excluded together. A column with many singleton categories (e.g. 50 categories each appearing once in a 100-row dataset) will report zero rare values — all singletons are tied and their combined frequency exceeds 1%, so all are excluded. This is intentional: it avoids surfacing noise as signal in high-cardinality columns.
# UMAP embedding
Source: https://docs.summand.com/concepts/components/umap
A 2-D projection of feature space for cluster visualization and 'similar rows' queries.
`umap_embedding` takes the curated Parquet for a dataset, projects every row into two dimensions using [UMAP](https://umap-learn.readthedocs.io/), and emits the coordinates. The result drives the cluster scatter plot on the dataset page and grounds Summand's "show me similar rows" answers.
UMAP is **unsupervised** — it doesn't need a target column. It looks at the geometry of the rows in feature space and finds a 2-D layout that preserves local neighborhoods.
## What it's good for
* **Cluster discovery** — see at a glance whether your data has natural groupings, and how many.
* **Outlier visualization** — outliers tend to land far from the dense regions of the projection.
* **Sanity-checking labels** — if you have a categorical column you suspect is meaningful, color the scatter plot by it and see whether the colors form coherent regions.
UMAP is **not** a tool for measuring distances quantitatively in 2-D. The projection compresses high-dimensional structure; absolute distance numbers don't carry the meaning they have in feature space. Use it for shape, not for numerics.
## Inputs
None. The component runs on the full curated dataset.
## Output shape
```json theme={null}
{
"coordinates": [
[0.42, -1.18],
[0.51, -1.06],
[-2.31, 0.74],
...
]
}
```
One `[x, y]` pair per row, in the same order as the curated Parquet. The artifact is `umap_embedding.json`.
For datasets with more than \~50,000 rows, the component subsamples to keep the projection tractable. The sampled-row indices are recorded in the manifest so downstream consumers can align points back to their source rows.
## Display
The UMAP component ships with a bespoke React viewer (`UMAPVisualization`):
* **Scatter plot** with zoom and pan.
* **Color-by-column** — pick any column from the schema to color points; categorical columns get a discrete legend, numeric columns a gradient.
* **Hover for row preview** — a tooltip shows the nearest point's actual row values.
* **Lasso select** — drag-select a region; the panel below shows the selected rows in a table.
## Filtering from chat
UMAP isn't directly queryable from chat — the raw coordinates aren't useful in a text response. Summand can reference the artifact existing (*"there are three visible clusters in this dataset's UMAP"*), but the actual visualization lives on the dataset page.
The component's `agent_config` is `enabled: false` for this reason — `analyze({ component: "umap_embedding", ... })` is intentionally a no-op.
## Compute profile
| Profile | Memory | Notes |
| - | - | - |
| Fargate | 4 CPU, 16 GB | Scales with row count; subsampling at 50k rows keeps cost bounded |
UMAP fitting is the most compute-intensive component in the catalog after EBM model fitting. For datasets under 10k rows it finishes in a minute or two; larger datasets benefit noticeably from the subsample cap.
## Common gotchas
Most often this means your dataset has one dominant cluster — common for filtered or single-segment datasets. Color by a categorical column (region, plan tier, product category) to see whether structure exists *within* the blob; if not, try running UMAP on a [view](/concepts/views) that includes more diverse rows.
UMAP groups by **all** features at once, not by your color column. If the color column isn't strongly correlated with the rest of the feature space, the colors won't form coherent regions. That's a finding, not a bug — it means the color column doesn't drive the broader structure.
UMAP is stochastic. Re-running on the same data produces a layout with the same cluster structure but possibly mirrored, rotated, or reflected. The clusters themselves are reproducible; the absolute axes aren't.
Not today. The 50k cap is a deliberate cost ceiling. If you need a denser projection, contact [support@intelligible.ai](mailto:support@intelligible.ai) — Enterprise customers can have it raised under contract.
# Computed-context layer
Source: https://docs.summand.com/concepts/computed-context
The bundle of model artifacts, statistics, and metadata that powers every analysis view and the Summand assistant.
The **computed-context layer** is the unit of analysis output. Every dataset has a history of computed-context versions; the UI always reads the latest one. When people on the team say "the analysis," they mean a computed-context version.
## What's in a version
A version is built from per-component artifacts. Each component (column stats, EBM model, EBM graphs, UMAP, etc.) writes its own outputs and registers them in a single `manifest.json`. The pieces that the UI most directly consumes:
| Artifact | Used by | Description |
| - | - | - |
| `column_stats.json` | Overview tab, Summand | Per-column means, distributions, missingness, cardinality. |
| `feature_metadata.json` | Features tab, Summand | EBM feature importance, pairwise interactions, types. |
| `graphs.json.gz` | Features tab | Shape functions and pairwise heatmaps — gzip-compressed because they're large. |
| `umap_embedding.json` | Insights tab, Summand | 2-D UMAP projection of rows in feature space. |
| `model.pkl` | Internal | The trained EBM, used to score new rows. |
| `manifest.json` | Internal | Index of every component's outputs and their content hashes. |
Surprise finding writes its top-N output directly to the `summand-task-outputs` DynamoDB table — not to S3 — so the Insights tab reads from there. Predictions for new rows are produced on-demand by re-loading the model; there's no per-row predictions Parquet sitting around.
All S3 artifacts are stored under a versioned path (`s3://summand-artifacts/curated/{connectorId}/{datasetId}/{version}/`) so older versions remain readable.
## Why a computed-context layer
Every part of the UI — and the Summand assistant — needs to answer questions like *"What's the mean of `revenue` by segment?"* or *"Which features matter most?"* without re-querying the source. The computed-context layer is the cached, structured answer to those questions.
Concretely:
* **Summand** gets grounding facts from the computed-context layer instead of hallucinating numbers.
* **Charts** suggested by Summand reference real columns and aggregations from the computed-context layer.
* **Refresh comparisons** become straightforward — diff version *N* against version *N–1*.
## Versioning model
A version is `(datasetId, version_number)`. Versions are append-only and immutable: once written, an artifact stays put. Updating the dataset (re-upload, refresh, target change) creates a new version; it does not mutate the previous one.
## Time travel
The Overview tab shows the latest version by default. Power users on Enterprise plans can pin an older version for comparison — useful for tracking how a model's understanding of the data has shifted over months.
## Storage and retention
Computed-context versions count toward dataset retention, not toward tier-based dataset caps. Pro and Enterprise retain all versions for the life of the subscription. Free tier retains only the latest two versions per dataset.
## Relationship to data warehousing
The computed-context layer is **not** a metrics store like Cube or LookML. It's narrower:
* It describes a **single dataset**, not a curated cross-source business model.
* It's **generated**, not authored — you don't write `.yml` to maintain it.
* It exists to power Summand's analysis surface; it doesn't expose itself as a SQL endpoint.
If you need a metrics layer, Summand pairs naturally with one — point both at the same warehouse — but the computed-context layer described here is internal to a dataset.
# Connectors
Source: https://docs.summand.com/concepts/connectors
Connectors are the typed interface between Summand and wherever your data lives.
A **connector** is the object that owns a connection to a data source. Every dataset belongs to exactly one connector. Connectors hold credentials (managed for you), schema metadata, and the list of tables Summand has discovered.
## Connector kinds
A file you upload from your machine. The connector wraps a single file as a single-table source.
Direct, read-only connections to your warehouse. Tables are discovered at create time and refreshed on demand.
Azure SQL Database and Managed Instance via the standard TDS protocol.
Databricks UniForm shares — Iceberg-backed for type-faithful, incremental refresh.
Managed connection to anything Fivetran supports (Databricks without UniForm, Redshift, Oracle, BigQuery, 300+ SaaS APIs). Summand reads Fivetran's Parquet output.
## What a connector stores
| Field | Description |
| - | - |
| `id` | Stable identifier (`con_…`). |
| `kind` | `csv`, `postgres`, `mysql`, `snowflake`, `fivetran`, or `s3`. |
| `displayName` | The name you see in the UI. Editable. |
| `glueDb` / `glueTable` | Internal: the Glue catalog references for query routing. |
| `visibility` | `private` (default), `showcase`, or `public`. Inherited by datasets — see [Sharing](/concepts/sharing). |
| `userId` | The owner. Sharing is granted on top of ownership. |
Credentials for database connectors live in AWS Secrets Manager — Summand never stores plaintext passwords or keys. For Fivetran, your source credentials never touch Summand servers at all (they go directly to Fivetran).
## Visibility inheritance
If a connector is set to `public` or `showcase`, every dataset under it is readable by anyone (subject to the visibility's content rules — `showcase` blocks raw rows, `public` allows them). Setting the connector back to `private` locks down all datasets at once, regardless of their individual visibility settings. Use this when you need to revoke anonymous access across an entire source quickly.
## When to create a new connector
* **One file per project** — upload as a new CSV connector for clean isolation.
* **One database** — one connector for the whole DB; Summand handles per-table datasets internally.
* **Different credentials** — if two parts of the same database need different access patterns, use two connectors.
## Limits
| Tier | Connectors |
| - | - |
| Free | CSV only |
| Pro / Education | CSV only |
| Enterprise | All kinds — CSV plus the database, Delta Sharing, and Fivetran connectors |
# Datasets
Source: https://docs.summand.com/concepts/datasets
A dataset is a single table within a connector — the unit of analysis, chat grounding, and experiment input.
Where a **connector** points at a source, a **dataset** is the unit Summand actually works with. One dataset = one table = one curated Parquet copy = one computed-context history.
## What's in a dataset
| Field | Purpose |
| - | - |
| `datasetId` | Stable identifier (`ds_…`). Survives renames. |
| `connectorId` | Parent connector. |
| `tableName` | Source-side name (e.g. `public.orders`). |
| `displayName` | Human-readable name in the UI. |
| `glueDb` / `glueTable` | Glue catalog references — what views and Athena queries resolve to. |
| `enabled` | Whether the dataset participates in experiments. Disabled datasets are inert but preserved. |
| `status` | `pending`, `ready`, or `failed`. |
| `datasetContext` | Free-text description that grounds Summand's answers and component prompts. |
There's no `targetColumn` field on the dataset itself. Predictive components (like the predictor) take the target column as a typed **input** when you configure an experiment — see [Experiments](/concepts/experiments).
## What you do with a dataset
Three primary actions, in increasing order of commitment:
1. **Chat** — open Summand and ask questions. The dataset's curated Parquet, schema, column stats, and context are all available to the assistant. It can run one-shot SQL, generate charts, and propose views or experiments.
2. **Create a view** over it — save a SQL transformation, optionally joining other datasets, queryable by chat and usable as an experiment source.
3. **Set up an experiment** — schedule one or more components to run on the dataset (or a view of it) on a cron. Outputs are versioned.
## The dataset detail page
Datasets have a configuration page with nine tabs. They're all about *tuning behavior*, not browsing analysis output (analysis output lives in chat, the Surprises page, and component-output views):
| Tab | What you do here |
| - | - |
| **Overview** | Last sync, freshness, summary stats. |
| **Schedule** | Sync frequency for live connectors; CSV re-upload for CSVs. |
| **Schema** | Column definitions, types, exclusions. |
| **Components** | Which components are assigned to this dataset (and run during experiments). |
| **Context** | Free-text dataset context, surfaced to Summand and component prompts. |
| **Access** | Sharing and permissions. |
| **Notifications** | Alerts for sync failures, drift, freshness lag. |
| **Run history** | Past sync and component-run logs. |
| **Advanced** | Deletion and danger zone. |
Most users never visit anything beyond Overview.
## Schema and types
Summand auto-infers types from a sample of the data on first ingest. You can override types and exclude columns from **Schema** if the inference is wrong. Changes take effect on the next sync or experiment run.
## Versioning
Each component run produces a new **computed-context version** keyed by `(datasetId, version)`. Versions are immutable and append-only. The latest version is what the UI reads; older versions remain queryable for audit and comparison.
A new version is created when:
* A connector is refreshed (live source pulls new data)
* A CSV is re-uploaded
* An experiment runs (manual or scheduled)
* Schema or context changes trigger re-runs of dependent components
## Limits
The active-dataset cap applies per account, not per connector:
* **Free:** 3 active datasets total
* **Pro / Education:** unlimited
* **Enterprise:** unlimited
# Experiments
Source: https://docs.summand.com/concepts/experiments
Schedule analytical components to run against a dataset or view, with versioned outputs and run history.
An **experiment** is a recurring run of one or more **components** (predictors, surprise finding, column stats, custom analyses) against a **dataset** or **view**. Experiments are how recurring analysis happens in Summand — instead of remembering to re-run a notebook, you wire up an experiment and it runs forever.
## Anatomy
| Field | Purpose |
| - | - |
| `experimentId` | Stable identifier. |
| `name` / `description` | Human-readable. |
| `datasetId` | The source. Required. |
| `viewId` | Optional. If set, the experiment runs against the view rather than the raw dataset. |
| `components[]` | List of component IDs to run. At least one. |
| `inputs` | A dict keyed by `ComponentInput.name` — typed values supplied to each component. |
| `schedulePreset` / `cronExpression` | When to run. |
| `enabled` | Pause without deleting. |
| `runCount`, `lastRunAt`, `recentRuns[]` | Run history (last 3 surfaced inline; full history under **Run history**). |
Experiments are stored as DynamoDB items keyed under the user. EventBridge Scheduler is what actually fires them on cron — Summand's runtime is Lambda + Step Functions, not a long-running scheduler service.
## Schedule options
Six presets cover the common cases:
* **Daily at 3 AM** (`cron(0 3 * * ? *)`)
* **Daily at 6 AM**
* **Every 6 hours**
* **Every 12 hours**
* **Weekly Monday 3 AM**
* **Weekly Sunday 3 AM**
Or write your own AWS EventBridge cron / rate expression:
```text theme={null}
cron(*/15 * * * ? *) — every 15 minutes
cron(0 9 ? * MON-FRI *) — every weekday at 9 AM
cron(0 0 1 * ? *) — first of every month at midnight
rate(2 hours) — every two hours
```
Note that EventBridge cron uses six fields, not the standard five — the day-of-week field has special semantics. The in-product editor validates and surfaces a human-readable description (e.g. *"At minute 0, every 6 hours"*) so you can sanity-check before saving.
## Components
A component is a unit of analysis with declared **inputs** and **outputs**. The component catalog defines what's available; today it includes:
* **Predictors** — fit an EBM, score the source, write feature importance and shape functions.
* **Surprise finding** — flag rows that disagree with predictions; rank by confidence.
* **Column stats** — per-column distributions, missingness, cardinality, correlations.
* **Computed-context pieces** — UMAP, feature metadata, and similar internal artifacts.
Each component has typed inputs that the experiment editor renders as form fields (number inputs for thresholds, dropdowns for column references, etc.). For example, the Predictors component has an input for "target column" — *that's where target column lives in the product today*, not on the dataset.
See [Components](/concepts/components) for the full catalog and what each one does.
## Sources: dataset vs. view
You can target either a dataset or a view:
* **Dataset** — components run on the curated Parquet for that dataset. The simplest case.
* **View** — components run on the SQL view's output. Use this when you need to filter, join, or aggregate first, or when you want experiments to share a common definition (define the cohort once as a view, point multiple experiments at it).
Views referenced by an experiment must be owned by the experiment's owner — there's no shared-view-as-source pattern today.
## Outputs
Each run writes:
* A **new computed-context version** for the source dataset.
* Component outputs to `summand-task-outputs` keyed by run ID.
* A row in **Run history** with status, duration, and any error.
Outputs are queryable from chat (*"what did the last predictor run say?"*), readable in the global Surprises page (for surprise-finding components), and feed downstream views you build on top.
## Run history
The experiment detail page shows the most recent runs with status (`SUCCEEDED` / `FAILED` / `IN_PROGRESS`), duration, and (on failure) the error message. Older runs paginate further back.
Failed runs are kept — Summand doesn't auto-retry. You can:
* **Manually re-run** from the experiment detail page (a one-shot trigger; doesn't change the schedule).
* **Edit and re-save** to fix the configuration; the next scheduled tick picks up the change.
* **Pause** if the underlying source is broken upstream and you don't want to spam failures.
## Manual triggers
Hit the **Run now** button to fire an experiment outside its schedule. The run shows up in history alongside scheduled runs; the next scheduled tick runs as normal.
This is the right way to test a configuration before letting it go on cron.
# Core concepts
Source: https://docs.summand.com/concepts/overview
How connectors, datasets, views, experiments, and components fit together.
Summand's data model is small. Most of the product makes sense once you've internalized seven terms.
A pointer to where your data lives — a CSV upload, a database, a Fivetran-managed source, a Delta Sharing endpoint.
A specific table within a connector, with a curated Parquet copy that everything else queries.
A saved SQL transformation over one or more datasets, with a visual builder and live Athena preview.
A scheduled run of one or more components against a dataset or view. Cron-driven, versioned outputs.
A unit of analysis — predictors, surprise finding, column stats, custom — with typed inputs and outputs.
The bundle of artifacts each experiment run writes: column stats, model graphs, embeddings.
Per-user grants plus visibility settings, enforced through OpenFGA on every read.
## How they fit together
```
Connector (CSV / Postgres / MySQL / Snowflake / Azure SQL / Delta Sharing / Fivetran)
└── Dataset (one per table, curated Parquet copy)
│
├── Chat — Summand, grounded in the dataset
│
├── View(s) — SQL transformations, optionally cross-dataset
│ └── Chat or experiments can target a view instead of the dataset
│
└── Experiment(s) — scheduled component runs
└── Components produce computed-context artifacts per run
└── Visible to chat, queryable downstream
```
A connector can have many datasets — one per table for databases. CSV connectors are always single-dataset. Datasets are the unit you chat about, query in views, and target with experiments.
## Identifiers
Every resource has a stable, URL-safe ID:
| Resource | Prefix | Example |
| - | - | - |
| Connector | `con_` | `con_01J5R...` |
| Dataset | `ds_` | `ds_01J5R...` |
| View | — | UUID-keyed under the user |
| Experiment | — | UUID-keyed |
| Run (component execution) | `run_` | `run_01J5R...` |
IDs are immutable. Display names can change without invalidating shared links.
## Lifecycle
1. **Create connector** — upload a CSV or point Summand at a data source.
2. **Datasets land automatically** — for CSVs, one dataset on upload; for databases, one per table you enable.
3. **Pick an action**:
* **Chat** with Summand for ad-hoc questions.
* **Create a view** to save a SQL transformation you'll re-use.
* **Create an experiment** to schedule recurring analysis.
4. **Read results** — through chat, in the global Surprises page, or in a view that pulls experiment outputs.
5. **Share** — invite teammates with explicit grants, or change visibility.
6. **Refresh** — for live sources, click *Refresh* to re-read; experiments will re-run on their next schedule against the fresh data.
# Sharing
Source: https://docs.summand.com/concepts/sharing
Per-user access grants, visibility settings, and how permissions are enforced.
Summand supports two orthogonal mechanisms: **direct grants** to specific users, and **visibility settings** that govern who else can see the dataset.
## Direct grants
A grant is a per-user, per-dataset (or per-connector) record that says *"this user can read"* or *"this user can edit"*. Grants are additive — once granted, the user has access regardless of the dataset's visibility setting.
| Role | Read data | Comment | Edit configuration | Re-run analysis | Share with others | Delete |
| - | - | - | - | - | - | - |
| **Owner** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| **Editor** | ✓ | ✓ | ✓ | ✓ | — | — |
| **Viewer** | ✓ | ✓ | — | — | — | — |
There is exactly one owner per dataset (the creator, by default). Authorization for grants is enforced through [OpenFGA](https://openfga.dev), the same engine that powers permissions in the rest of the product.
## Visibility settings
Independent of grants, every dataset has a **visibility** value that controls discovery and what unauthenticated viewers can see:
| Visibility | Who can find it | What they can see |
| - | - | - |
| `private` | Owner and explicit grantees only. Default. | Everything, subject to grants. |
| `showcase` | Anyone with the link, no sign-in required. | **Aggregated insights only** — feature importance, shape functions, summary stats. Raw row data is blocked. |
| `public` | Anyone on the internet, no sign-in required. | Everything — including raw row data and Summand chat. |
Use **showcase** when you want to share the *findings* of an analysis — for a case study, blog post, or sales conversation — without exposing the underlying rows. Use **public** for genuinely public data (open datasets, benchmarks, published research).
If a dataset's parent connector is set to `public` or `showcase`, the dataset inherits read access from the connector — you don't need separate grants. Setting a connector or dataset to `private` blocks anonymous access regardless of the other.
Both `public` and `showcase` are indexed by search engines and have stable URLs. Don't expose a dataset this way if it contains anything you wouldn't put on the homepage of your website.
## Granting access
From the dataset's **Share** dialog:
Summand checks if they have an account. If they do, the grant takes effect immediately.
Viewer or Editor. Owner can only be reassigned, not added.
For email addresses without an account yet, Summand sends an invite. The grant becomes active when they accept.
You can revoke a grant at any time. Revocation is immediate — in-flight requests fail closed on the next authorization check.
## Sharing limits by tier
| Tier | Direct grants per dataset | Public / showcase datasets |
| - | - | - |
| Free | — | — |
| Pro | 5 | ✓ |
| Education | 5 | ✓ |
| Enterprise | Unlimited | ✓ |
## Audit trail
Every grant change — added, role changed, revoked — is recorded with timestamp, actor, and target user. Enterprise customers can export this audit log for SOC 2 / HIPAA reviews.
## Sharing connectors (Enterprise)
You can also share an entire **connector** rather than individual datasets. A connector grant gives the user access to every dataset under that connector, including new ones created later. Useful for giving a team durable access to a database without re-granting for each new table.
## Filing and publication (v2 sharing model)
Sharing v2 (May 2026) splits ownership and consumption into two distinct concepts:
* **Filing** is single-parent. Every connector and dataset is "filed" inside exactly one workspace, which determines its primary owners.
* **Publication** is multi-target. Datasets can be published to additional consumers (specific users, workspace members, the public via showcase) without changing where they're filed.
This separation makes auditing access easier — you can see at a glance who *owns* a resource (filing) versus who has *read access* (publications and direct grants). All authorization is enforced through OpenFGA, so the same answer is given regardless of whether the request comes from the UI, the API, or an internal Lambda.
# Views
Source: https://docs.summand.com/concepts/views
Saved SQL transformations over one or more datasets, with a visual builder and live Athena preview.
A **view** is a named SQL query Summand runs against your curated data. Views can:
* Filter, project, or aggregate a single dataset.
* **Join across datasets** — including across different connectors, since everything's curated to the same Parquet store and registered in the same Glue catalog.
* Be edited visually with a drag-and-drop builder, hand-edited as raw SQL, or drafted by Summand in chat.
* Be used downstream — as a source in experiments, as grounding in further chat sessions, or shared on their own with grant + visibility semantics.
## Visual builder vs. raw SQL
Views ship with two editing modes that share the same underlying query:
* **Visual** — pick datasets, drag in joins and filters, define aggregations. The builder writes SQL underneath, and live previews against Athena update as you change things.
* **Code** — drop into a SQL editor for anything the visual builder can't express. Live preview is the same.
When you switch from Code back to Visual, Summand confirms before resetting hand-edits — there's no automatic round-trip from arbitrary SQL back into the builder's structured representation.
## Where views live
Views are stored under the user who created them:
```
PK: USER#{userId}
SK: VIEW#{viewId}
```
There's no cross-user view share today — to give someone else access to your view's output, materialize it (run the SQL once and save), or share the underlying datasets and let them rebuild it.
## Chat-created views
Summand can draft a view for you. Ask in chat — *"build me a view that shows monthly active customers from the orders dataset"* — and Summand returns a proposed SQL view rendered with a save button. Approve and it lands in your views list.
Views Summand creates inside a chat session are pinned to that session as **chat views** until you explicitly save them. Chat views aren't addressable by experiments and aren't shareable; they're scratch.
## Performance
Views run on Athena over the curated Parquet partitions. For most analytical patterns this is fast — Athena scans only the columns the SQL touches. For very large joins, consider materializing the view as part of an experiment (the experiment writes the result back as a new dataset on a schedule).
## Limits
* **One schema per view today.** Views are queries, not multi-statement scripts.
* **No mutations.** SQL is read-only — `INSERT` / `UPDATE` / `DELETE` aren't supported.
* **Glue-table references.** Views reference datasets by their Glue table name, not their ID. If you rename a dataset (display name change) the view is unaffected; if you delete a dataset, dependent views break with a clear error.
# Azure SQL
Source: https://docs.summand.com/data-sources/azure-sql
Connect Summand to an Azure SQL Database for live, refreshable analysis.
The Azure SQL connector talks to Microsoft's managed SQL Server (Azure SQL Database, Azure SQL Managed Instance) over the standard TDS protocol with TLS. Available on **Enterprise** plans.
## What Summand needs
A SQL login with read-only access to the schemas and tables you intend to analyze:
* `SELECT` on the target tables
* `VIEW DEFINITION` on the schemas (for catalog discovery)
* Standard SQL `INFORMATION_SCHEMA` access
Summand never executes writes, never reads system tables outside `INFORMATION_SCHEMA`, and never executes user-supplied SQL.
## Network access
Summand connects from a fixed set of egress IPs (visible in **Settings → Connectivity**). Allowlist them on:
* The Azure SQL **server's firewall** (Networking → Firewall and virtual networks)
* Any Azure Private Link configuration if the server is private
For servers behind Private Link with no public endpoint, Enterprise customers can request a managed peering — contact [our sales team](https://intelligible.ai/contact).
## Setup
```sql theme={null}
-- In master DB
CREATE LOGIN summand_reader WITH PASSWORD = '';
-- In your application database
CREATE USER summand_reader FOR LOGIN summand_reader;
ALTER ROLE db_datareader ADD MEMBER summand_reader;
GRANT VIEW DEFINITION TO summand_reader;
```
Use a long random password (32+ characters). Summand stores it encrypted in AWS Secrets Manager.
From **Connectors → Add connector → Azure SQL**, provide:
* **Server** (e.g. `.database.windows.net`)
* **Port** — usually `1433`
* **Database** name
* **Username** and **password** from the previous step
Click **Test connection**.
Same as any other database connector — Summand discovers the schemas you can read, you toggle on the tables to analyze, and you set targets per dataset.
## Authentication
Today, Summand uses **SQL authentication** (username + password). Microsoft Entra ID authentication and managed-identity authentication are on the roadmap for organizations that want to standardize on Entra credentials.
## Performance
Azure SQL connections honor the standard SQL Server query plan — Summand's curation step issues straightforward `SELECT *` against the table. For very large tables, create a database view that pre-filters or samples and point Summand at the view.
## Removing a connector
Deleting a connector immediately revokes access and queues the curated data for deletion. Re-creating with the same credentials works, but analysis history is not restored.
# CSV upload
Source: https://docs.summand.com/data-sources/csv-upload
The fastest way to get a one-off analysis: drag a file in.
CSV upload is Summand's no-setup entry point. It's available on every tier, including Free.
## Limits
| Tier | Maximum file size |
| - | - |
| Free | 50 MB |
| Pro / Education | 1 GB |
| Enterprise | 4 GB |
For files larger than 4 GB, point Summand at the source via a [database connector](/data-sources/databases) or [Fivetran](/data-sources/fivetran) instead — uploads aren't the right tool for very large data.
## File format
Other encodings (UTF-16, ISO-8859-1, Windows-1252) often work but aren't guaranteed. If column names look garbled in the preview, re-export as UTF-8.
The first non-empty row must contain column names. Names should be unique and human-readable; Summand uses them in the UI verbatim.
Auto-detected from the file extension and the first line. `.csv`, `.tsv`, `.txt` are all accepted.
One row per observation, one column per variable. Pivot tables and crosstabs produce noisy analyses — un-pivot first.
## What happens when you upload
1. The file streams directly to Summand's encrypted S3 bucket via a presigned URL — it doesn't pass through any application server.
2. Summand parses the header, samples the first \~10,000 rows to infer column types, and creates the dataset.
3. The full file is converted to Parquet on the analysis pipeline's first run.
4. The analysis pipeline produces a [computed-context version](/concepts/computed-context) and the dataset becomes browseable.
For a 100 MB file, end-to-end is typically under a minute.
## Re-uploading
To analyze a new version of the same file, click **Replace data** on the dataset page and upload again. Summand creates a new computed-context version pinned to the new file; the previous version remains accessible for comparison.
The dataset's schema overrides, context, sharing grants, and any experiments configured on it are preserved across re-uploads — you don't redo configuration.
## Troubleshooting
Large uploads are resumable up to 24 hours. Refresh the page; you'll be prompted to resume rather than restart. If the upload still fails, the file may be corrupted — try opening it in a text editor or spreadsheet first to confirm it's well-formed.
Most often this is non-numeric content in the column — currency symbols, units, commas as thousands separators. Either clean the file, or override the column type from the **Configuration** sidebar after upload.
Three common causes: (1) the target is highly imbalanced — fewer than \~30 minority-class rows; (2) too many features are high-cardinality strings excluded from the model; (3) the file is too small — EBM needs roughly 500+ rows for stable shape functions.
# Database connectors
Source: https://docs.summand.com/data-sources/databases
Connect Summand to PostgreSQL, MySQL, Snowflake, or Azure SQL for live, refreshable analysis.
Database connectors let Summand query a live warehouse and refresh analysis on demand. Available on **Enterprise** plans.
## Supported engines
Versions 11+. Read-only credentials recommended.
Versions 5.7+ and MySQL 8. Compatible with MariaDB.
Username + password authentication.
Azure SQL Database and Managed Instance.
For Databricks (with UniForm), see [Delta Sharing](/data-sources/delta-sharing). For Databricks without UniForm, Redshift, BigQuery, Oracle, and SaaS sources, see [Fivetran](/data-sources/fivetran).
## What Summand needs
A user with **read-only access** to the schemas and tables you intend to analyze. Specifically:
* `SELECT` on the target tables
* `USAGE` on the schemas (Postgres / Snowflake)
* `INFORMATION_SCHEMA` access for schema discovery
Summand never executes writes, never reads system catalogs beyond `INFORMATION_SCHEMA`, and never executes user-supplied SQL.
## Network access
Summand connects from a fixed set of egress IPs — share these with your network team to allowlist:
* `52.x.x.x/30` (production)
* `54.x.x.x/30` (production failover)
Live IP ranges are listed in the in-product **Settings → Connectivity** panel for your account. The values above are illustrative — always copy the live ones from there.
For databases inside a VPC with no public access, Enterprise customers can request:
* **PrivateLink** (AWS) — Summand creates a VPC endpoint in your account.
* **VPC peering** (AWS, GCP) — for ongoing high-throughput workloads.
* **SSH tunnel** — supported but not recommended for production.
Contact [our sales team](https://intelligible.ai/contact) for any of the above.
## Setup
Use the SQL appropriate for your engine. For Postgres:
```sql theme={null}
CREATE USER summand_reader WITH PASSWORD '';
GRANT CONNECT ON DATABASE your_db TO summand_reader;
GRANT USAGE ON SCHEMA public TO summand_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO summand_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO summand_reader;
```
From the **Connectors** page, click **Add connector → PostgreSQL** (or MySQL / Snowflake). Provide host, port, database, and the read-only credentials. Summand validates connectivity before saving.
Summand discovers all tables you have `SELECT` on. Choose which ones to enable as datasets. You can enable more later from the connector page.
Each enabled table becomes a dataset. Baseline column-stats run automatically. From there, [chat](/guides/ask-summand), [create views](/guides/create-a-view), or [set up experiments](/guides/set-up-an-experiment) — there's no per-dataset configuration step.
## Refresh
Click **Refresh** on a dataset to re-run analysis against the current state of the source table. Refresh:
* Streams the table to Summand's curated Parquet store
* Fits a fresh EBM and re-runs surprise finding
* Writes a new computed-context version
* Switches the UI to the new version on success
The previous version is preserved for comparison. There is no automatic refresh today — refresh is always user-initiated.
## Credential handling
* Database passwords are encrypted with AWS KMS and stored in AWS Secrets Manager.
* Plaintext credentials are never logged.
* Connection strings are never exposed in the UI or API responses.
* You can rotate credentials at any time from **Settings → Connectors → Edit**.
## Removing a connector
Deleting a connector immediately revokes all access to the underlying datasets and queues their data for deletion. Datasets can be re-created if you re-add the connector with the same credentials, but their analysis history is lost.
# Delta Sharing
Source: https://docs.summand.com/data-sources/delta-sharing
Connect Summand to a Databricks Delta Sharing recipient endpoint. Available on Enterprise.
The Delta Sharing connector reads tables published from Databricks via the open [Delta Sharing](https://delta.io/sharing/) protocol. Available on **Enterprise** plans.
Today Summand supports **Databricks UniForm** shares only. The recipient credential JSON must include an `icebergEndpoint` field — this is what Databricks emits when the share is created with UniForm enabled. Non-UniForm shares (OSS Delta Sharing servers, AWS Data Exchange, older Databricks shares without UniForm) are not yet supported.
## What you'll need from your Delta Sharing provider
A **recipient credential JSON** that contains, at minimum:
* `endpoint` — the Delta Sharing server URL
* `bearerToken` — the recipient access token
* `icebergEndpoint` — the UniForm Iceberg REST URL
Plus the share metadata you intend to consume:
* **Share name** — the named bundle of schemas and tables shared with you
* **Schema name** — a single schema within the share
If your provider sent a `.share` credential file, all three URLs are inside it. Open it in a text editor; you'll see a JSON document.
## Why UniForm
UniForm-backed shares produce **Iceberg-formatted** tables, which gives Summand:
* **Type-faithful reads** — column types come from Iceberg metadata, not inferred from Parquet samples.
* **Predicate pushdown for incremental sync** — only the partitions that changed are re-read on refresh.
* **Schema evolution** — new columns are picked up on the next refresh without breaking the dataset.
The non-UniForm Delta Sharing path lacks these guarantees, so we've held off on supporting it.
## Setup
Your Databricks-side admin must mark the share as UniForm-enabled when creating or updating it. Confirm the recipient credential JSON has an `icebergEndpoint` field before continuing.
From **Connectors → Add connector → Delta Sharing**, provide:
* **Endpoint** — the Delta Sharing server URL (`endpoint` from the credential JSON)
* **Bearer token** — the recipient access token
* **Share name** — the share you want to consume
* **Schema name** — a single schema within that share
Summand authenticates to the Delta Sharing server and lists the schemas in your share. On success, the schema-and-tables view appears.
Same as any other connector. Each table becomes a candidate dataset; pick targets and run analysis.
## Refresh
Click **Refresh** to re-read the share. Because UniForm provides Iceberg metadata, refresh is **incremental** — Summand only re-reads partitions that have changed since the last run, so refresh is fast even for large tables.
## Credentials
The bearer token is encrypted in AWS Secrets Manager and never logged. To rotate, edit the connector and supply a new token; the previous secret is overwritten on save.
If the bearer token is rotated on the Databricks side without updating Summand, refresh will fail with a 401 from the Delta Sharing server. Update the token in **Settings → Connectors → Edit**.
## Limits and caveats
* **Single schema per connector.** Delta Sharing connectors are scoped to one share + schema. To consume multiple schemas, create multiple connectors.
* **Read-only.** Summand never writes back to the share; this is enforced at the protocol level (Delta Sharing is read-only).
* **No row-level security.** Filtering happens server-side via the share configuration in Databricks. If you need different views for different teams, create separate shares.
# Fivetran
Source: https://docs.summand.com/data-sources/fivetran
Connect to anything Fivetran supports — Databricks, Redshift, Oracle, SaaS APIs — without giving Summand your source credentials.
Fivetran is Summand's universal connector. Instead of building native drivers for every database and SaaS API, Summand reads the Parquet output of a Fivetran-managed sync. Available on **Enterprise** plans.
## When to use Fivetran
Databricks, Redshift, BigQuery, Oracle, MongoDB, plus 300+ SaaS sources (Salesforce, HubSpot, Stripe, etc).
Source credentials only live in Fivetran. Summand sees only the Parquet output.
Reuse your existing Fivetran account and credit pool. No duplicate sync.
Fivetran handles incremental sync, retries, and rate-limit backoff for you.
## How it works
```
You: pick a source in Summand ──┐
Summand: provisions Fivetran group + │
destination + connection │
Fivetran Connect Card popup opens ──┘
You authenticate with your data source ──┐
│
Fivetran syncs to Summand's S3 bucket │
as Parquet │
│
You click Refresh in Summand │
Summand reads Parquet → curated Parquet │
→ Glue catalog → computed-context layer ──┘
```
You never interact with Fivetran's UI. Summand provisions the Fivetran account, group, and destination on your behalf — you only authenticate with the source itself, in a popup.
## Setup
From **Connectors → Add connector → Fivetran**, choose your source type (Databricks, Salesforce, etc.).
A Fivetran-hosted Connect Card opens in a popup. Authenticate with your source — OAuth, API key, or username/password depending on the source. Credentials go directly to Fivetran; Summand never sees them.
Fivetran's first sync may take from a few minutes to several hours depending on source size and rate limits. You'll see *Pending first sync* on the connector card until the first batch lands in S3.
Once the first sync completes, Summand discovers the schemas and tables. From there, configuration is identical to a native database connector — pick tables, set targets, click *Analyze*.
## Refresh
After the initial sync, **Refresh** in Summand re-reads Fivetran's most recent Parquet output. It does *not* trigger a new Fivetran sync — Fivetran syncs run on whatever schedule is configured in your Fivetran account (every 1, 5, 15, 60 minutes etc.).
To force a fresh sync from the source, trigger it from your Fivetran dashboard or wait for the next scheduled sync, then click *Refresh* in Summand.
Webhook-driven auto-refresh — where Summand re-runs analysis as soon as Fivetran finishes a sync — is on the roadmap. Until then, refresh is manual.
## Billing
Fivetran charges based on **monthly active rows (MAR)** — the count of distinct rows synced per month. Summand's bill is independent of this; we charge the standard Enterprise rate regardless of how much data Fivetran moves.
If you already have a Fivetran account, you can connect Summand to it instead of having Summand provision a new one. Contact sales to set this up.
## Limitations
* **Latency:** Refresh shows the most recent Fivetran sync, not real-time data.
* **Storage:** Parquet output stays in Summand's bucket; we manage retention.
* **Schema changes:** Handled automatically — adding/removing columns in the source propagates on the next sync, then on the next Summand refresh.
* **Custom transformations:** Fivetran's transformations layer is supported, but Summand reads the post-transformation output. Plan accordingly.
# Data sources overview
Source: https://docs.summand.com/data-sources/overview
Every source Summand supports, what it's good for, and which tier it requires.
Summand has five built-in connectors plus a universal **Fivetran** path that handles everything else. Pick the one that matches how the data lives today; you can mix and match across one account.
| Source | Best for | Tier required |
| - | - | - |
| [CSV upload](/data-sources/csv-upload) | One-off analyses, files up to 4 GB | Free + |
| [PostgreSQL / MySQL / Snowflake / Azure SQL](/data-sources/databases) | Live data in your warehouse | Enterprise |
| [Delta Sharing](/data-sources/delta-sharing) | Databricks UniForm shares with Iceberg metadata | Enterprise |
| [Fivetran](/data-sources/fivetran) | Anything Fivetran supports — Databricks (non-UniForm), Redshift, Oracle, BigQuery, 300+ SaaS APIs | Enterprise |
## How to choose
Use **CSV upload**. No setup, no credentials.
Use the **database connector** for Postgres, MySQL, Snowflake, or Azure SQL — direct connection, lowest latency.
Use **Delta Sharing** — Iceberg-backed, type-faithful, incremental refresh.
Use **Fivetran** — anything Fivetran can sync, Summand can analyze.
## What every source has in common
No matter the source, Summand:
* **Curates a Parquet copy** of your data on first analysis. The source isn't queried again until refresh.
* **Generates a computed-context version** with the same artifacts (column stats, EBM, surprises, UMAP).
* **Enforces the same authorization** (grants + visibility) regardless of source.
* **Charges the same** for analysis — pricing is per-account, not per-source.
The differences between sources are in **setup**, **credential handling**, and **refresh model**, not in what you can do once a dataset exists.
## Refresh model by source
| Source | Refresh trigger | Notes |
| - | - | - |
| CSV | Re-upload | Immediate. Replaces the file in place. |
| Database (Postgres / MySQL / Snowflake / Azure SQL) | Manual *Refresh* button | Full table re-read each time. |
| Delta Sharing | Manual *Refresh* button | **Incremental** — only changed partitions are re-read. |
| Fivetran | Manual *Refresh* button | Re-reads Fivetran's most recent sync output; doesn't trigger a new Fivetran sync. |
## Privacy and credentials
* **CSV** uploads stream directly to Summand's encrypted S3 bucket via presigned URLs. The file never passes through any application server.
* **Database** credentials are encrypted at rest in AWS Secrets Manager. Plaintext is never logged.
* **Delta Sharing** bearer tokens are stored encrypted in Secrets Manager; rotation is supported from the connector edit page.
* **Fivetran** holds your source credentials — Summand only sees the Parquet output. Your warehouse password never touches Summand servers.
# Snowflake
Source: https://docs.summand.com/data-sources/snowflake
Connect Summand to a Snowflake account for live analysis. Supports key-pair JWT, programmatic access tokens, and password authentication.
The Snowflake connector talks to your Snowflake account over TLS using the official `snowflake-sdk` (Node.js) and `snowflake-connector-python` libraries. Available on **Enterprise** plans.
Summand follows Snowflake's documented best practices for service connectors: dedicated read-only role, modern authentication (key-pair JWT or programmatic access tokens), structured query tags for cost attribution, and a 1-hour statement timeout to bound runaway queries.
## What Summand needs
A dedicated Snowflake **role** with read-only access to the database, schema, and tables you intend to analyze. Snowflake's [access control best practices](https://docs.snowflake.com/en/user-guide/security-access-control-considerations) recommend creating an integration-specific role rather than reusing a human user's role.
The role needs:
* `USAGE` on the **warehouse**
* `USAGE` on the **database** and **schemas**
* `SELECT` on the **tables and views** to be analyzed (or `SELECT ON ALL TABLES IN SCHEMA …` plus `SELECT ON FUTURE TABLES IN SCHEMA …` for new tables)
Summand never executes writes, never creates Snowflake objects, and never runs user-supplied SQL against your warehouse.
## Authentication
Snowflake is [deprecating single-factor password authentication for service users by October 2026](https://docs.snowflake.com/en/user-guide/security-mfa-rollout). Summand supports three auth methods, listed in order of preference:
| Method | Recommended for | Snowflake's stance |
| - | - | - |
| **Key-pair (JWT)** | Production, all customers | ✅ Required for service users post-Oct 2026 |
| **Programmatic Access Token (PAT)** | Quick setup, rotation-friendly service auth | ✅ Supported (introduced 2024) |
| **Password** | Initial trial only | ⚠️ Being deprecated for service users |
### Key-pair JWT (recommended)
On any machine with `openssl`:
```bash theme={null}
# Generate an encrypted PKCS#8 private key
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out summand_rsa_key.p8
# Extract the matching public key
openssl rsa -in summand_rsa_key.p8 -pubout -out summand_rsa_key.pub
```
The private key (`summand_rsa_key.p8`) goes into Summand. The public key (`summand_rsa_key.pub`) goes into Snowflake.
Strip the PEM header/footer from `summand_rsa_key.pub` and run, in Snowflake:
```sql theme={null}
ALTER USER SUMMAND_READER SET RSA_PUBLIC_KEY = '';
```
Snowflake's [key rotation guide](https://docs.snowflake.com/en/user-guide/key-pair-auth) explains how to rotate via `RSA_PUBLIC_KEY_2` without downtime.
In **Connectors → Add connector → Snowflake**:
* Choose **Key pair (recommended)**
* Paste the contents of `summand_rsa_key.p8` into **Private key**
* If you used `-v2 des3` (encrypted), supply the **Passphrase**
### Programmatic Access Token (PAT)
[Introduced in 2024](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens), PATs are token-based credentials scoped to a single user — simpler than key-pair, more secure than passwords. Best for "OAuth without the redirect dance."
```sql theme={null}
-- As an admin or the user themselves
ALTER USER SUMMAND_READER ADD PROGRAMMATIC ACCESS TOKEN summand_token
DAYS_TO_EXPIRY = 90
ROLE_RESTRICTION = 'SUMMAND_READER';
```
Snowflake returns the token value **once** — copy it immediately. Tokens are revocable via `ALTER USER … REMOVE PROGRAMMATIC ACCESS TOKEN summand_token`.
In **Connectors → Add connector → Snowflake**:
* Choose **Programmatic Access Token**
* Paste the token value into the **Token** field
### Password (legacy)
Supported for backward compatibility but [Snowflake is enforcing key-pair / OAuth for service users by October 2026](https://docs.snowflake.com/en/user-guide/security-mfa-rollout). Existing password-auth connectors should be migrated before then; new connectors should default to key-pair or PAT.
## Setup script — least-privilege role
Run this in Snowflake (as `SECURITYADMIN` or `SYSADMIN`) before adding the connector. Adjust ``, ``, and `` to your environment:
```sql theme={null}
USE ROLE SECURITYADMIN;
-- Dedicated user + role for Summand
CREATE ROLE IF NOT EXISTS SUMMAND_READER;
CREATE USER IF NOT EXISTS SUMMAND_READER
DEFAULT_ROLE = SUMMAND_READER
DEFAULT_WAREHOUSE =
COMMENT = 'Read-only role for the Summand integration';
GRANT ROLE SUMMAND_READER TO USER SUMMAND_READER;
-- Allow the role to use the warehouse
USE ROLE SYSADMIN;
GRANT USAGE ON WAREHOUSE TO ROLE SUMMAND_READER;
-- Grant database + schema USAGE and SELECT on tables/views
GRANT USAGE ON DATABASE TO ROLE SUMMAND_READER;
GRANT USAGE ON SCHEMA . TO ROLE SUMMAND_READER;
GRANT SELECT ON ALL TABLES IN SCHEMA . TO ROLE SUMMAND_READER;
GRANT SELECT ON ALL VIEWS IN SCHEMA . TO ROLE SUMMAND_READER;
-- Auto-grant SELECT on future objects (so adding tables/views doesn't require re-running grants)
GRANT SELECT ON FUTURE TABLES IN SCHEMA . TO ROLE SUMMAND_READER;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA . TO ROLE SUMMAND_READER;
```
For multi-schema access, repeat the schema-level grants for each schema, or grant at the database level if you want the role to see every schema.
## Network access
By default Summand connects from a fixed pool of egress NAT IPs (visible in **Settings → Connectivity**). Three deployment options exist:
### 1. Public endpoint with IP allowlist (default)
Add Summand's egress IPs to your Snowflake [network policy](https://docs.snowflake.com/en/user-guide/network-policies):
```sql theme={null}
USE ROLE SECURITYADMIN;
CREATE NETWORK POLICY summand_allowlist
ALLOWED_IP_LIST = ('', '', ...)
COMMENT = 'Allow Summand connector traffic';
-- Apply at the user level (recommended) or account level
ALTER USER SUMMAND_READER SET NETWORK_POLICY = 'summand_allowlist';
```
### 2. AWS PrivateLink (Enterprise only)
For accounts that disable public traffic via [AWS PrivateLink](https://docs.snowflake.com/en/user-guide/admin-security-privatelink), Summand can be added to your VPC peering. Contact [our sales team](https://intelligible.ai/contact) — this is a managed-peering setup and requires both sides to coordinate.
### 3. Hostname allowlist on customer side
If your firewall blocks outbound by hostname, allow:
* `.snowflakecomputing.com` (account-specific URL)
* `..privatelink.snowflakecomputing.com` (PrivateLink endpoint, if applicable)
* `*.snowflakecomputing.com` if you prefer broad allowlisting
## Adding the connector
From **Connectors → Add connector → Snowflake**:
| Field | Value |
| - | - |
| **Account** | The `-` identifier (e.g. `xy12345-MYACCT`). Summand auto-strips a trailing `.snowflakecomputing.com` and converts `_` → `-` so you can paste the URL directly. |
| **Warehouse** *(optional)* | The Snowflake warehouse the role has `USAGE` on. Leave blank to use the user's `DEFAULT_WAREHOUSE` per Snowflake's [recommended pattern](https://docs.snowflake.com/en/user-guide/warehouses-overview) |
| **Database** | The database to analyze |
| **Username** | The Snowflake user (e.g. `SUMMAND_READER`) |
| **Authentication** | Pick **Key pair**, **Programmatic Access Token**, or **Password** |
| **Role** *(advanced, optional)* | Override the user's default role — pin to `SUMMAND_READER` if you have multiple roles |
| **Schema** *(advanced, optional)* | Default schema for the session. Leave blank to discover **all schemas** the role can read |
## What Summand sets on every Snowflake session
For predictable cost and operational behavior, Summand applies these session parameters automatically:
| Parameter | Value | Why |
| - | - | - |
| `application` | `Summand_Connector` | Identifies our queries in your audit logs and Snowflake support tickets |
| `QUERY_TAG` | JSON `{service, action, connector_id, request_id}` | Lets your FinOps team attribute Snowflake credits via `ACCOUNT_USAGE.QUERY_HISTORY` — see [Snowflake's cost-attribution guide](https://docs.snowflake.com/en/user-guide/cost-attributing) |
| `STATEMENT_TIMEOUT_IN_SECONDS` | `3600` (1 hour) | Bounds runaway queries — the Snowflake account default is 172800 (2 days) |
| `TIMESTAMP_TYPE_MAPPING` | `TIMESTAMP_NTZ` | Deterministic timezone handling across ingestion runs |
| `CLIENT_SESSION_KEEP_ALIVE` | `false` | Short-lived ingestion sessions don't pin warehouse credits |
## Cost attribution
Every Summand query carries a JSON `QUERY_TAG`. To see credits attributable to Summand:
```sql theme={null}
SELECT
PARSE_JSON(QUERY_TAG):action::STRING AS summand_action,
PARSE_JSON(QUERY_TAG):connector_id::STRING AS connector_id,
COUNT(*) AS query_count,
SUM(CREDITS_USED_CLOUD_SERVICES) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE START_TIME > DATEADD(day, -30, CURRENT_TIMESTAMP())
AND PARSE_JSON(QUERY_TAG):service::STRING = 'summand'
GROUP BY 1, 2
ORDER BY credits DESC;
```
## Picking tables, views, and datasets
Summand discovers **base tables, views, and materialized views** in the schema(s) you have access to. View support means dbt-style "raw tables → curated views" pipelines work out of the box — point Summand at the curated view and analyze it directly.
Same UX as any other database connector: toggle on the tables/views to analyze, set targets per dataset, run.
## Common errors
### "Snowflake view metadata is stale"
Snowflake views can drift when an underlying table gains columns and the view's stored column shape becomes out of sync. The fix must be in Snowflake (`ALTER VIEW` cannot do this):
```sql theme={null}
CREATE OR REPLACE VIEW .. AS ;
```
Summand surfaces this error with the exact view name and remediation SQL inline.
### "Connection succeeded but no warehouse is bound"
The role lacks `USAGE` on the warehouse. Run:
```sql theme={null}
GRANT USAGE ON WAREHOUSE TO ROLE ;
```
### "Account identifier not found"
Most often caused by:
* Using the legacy `..` form — switch to `-`
* Trailing `.snowflakecomputing.com` (Summand auto-strips this, but other tools may not)
* Underscores in the identifier — Snowflake's Python connector requires hyphens (Summand auto-converts on the way in)
# Audit logs
Source: https://docs.summand.com/enterprise/audit-logs
Every authentication, authorization, and configuration event — viewable in WorkOS, streamed to your SIEM.
Summand's audit trail covers two surfaces:
| Surface | Where it lives | What it covers |
| - | - | - |
| **Identity events** | WorkOS Admin Portal + Log Streams | Sign-ins, MFA challenges, SSO connection changes, SCIM provisioning, role changes, session events |
| **Application events** | Summand AWS CloudWatch | Dataset creation, sharing changes, view and experiment edits, analysis runs, PDF exports |
Both are retained for **6+ years** to meet HIPAA requirements, and both are queryable.
## Viewing identity audit logs
From **Settings → Organization → Audit Logs → Configure** in Summand. The link opens a one-time WorkOS Admin Portal session pointed at the audit log viewer.
Every event has:
* Timestamp (UTC)
* Actor (user ID, email, IP address, user agent)
* Event type (`user.signed_in`, `connection.activated`, `sso.session_created`, etc.)
* Result (success / failure)
* Context (which org, which connection, which target)
You can filter by date range, event type, actor, and result.
## Streaming to your SIEM
For real-time monitoring and longer retention, forward events to your SIEM via **Log Streams**:
**Settings → Organization → Log Streams → Configure**.
Datadog, Splunk, AWS S3, or generic HTTPS webhook are supported.
Provide the API key / endpoint URL the destination requires. The portal validates the connection before saving.
Sign in or trigger a test event; you should see it in your SIEM within 30 seconds.
A common pattern: route events to S3 for long-term archive *and* to Datadog for real-time alerting. Multiple log streams can run in parallel.
## What to alert on
Suggested alerting rules:
* **Spike in failed logins** (`user.signed_in_failed`) from a single IP
* **Multiple SSO connection changes** (`connection.activated`, `connection.deactivated`) outside change windows
* **Unexpected role escalations** (`organization_membership.role_changed` to admin or owner)
* **MFA factor deletions** (`authentication_factor.deleted`)
* **SCIM provisioning failures** (`directory.sync_failed`)
## Application-level audit (Summand-side)
In addition to identity events, Summand logs application events to CloudWatch:
| Event | What's logged |
| - | - |
| Connector created / updated / deleted | Actor, kind, connector ID |
| Dataset created / updated / deleted | Actor, dataset ID, source connector |
| View created / updated / deleted | Actor, view ID, name |
| Experiment created / updated / deleted | Actor, experiment ID, components, schedule |
| Experiment run started / completed / failed | Actor, experiment ID, run ID, status |
| Share grant added / changed / revoked | Actor, target user, role |
| Visibility change | Actor, dataset ID, before / after |
| Analysis run started / completed / failed | Actor, dataset ID, version |
| PDF export | Actor, dataset ID, version |
Enterprise customers can request these forwarded to their SIEM via the same Log Streams plumbing — contact support to enable.
## Retention
| Surface | Retention |
| - | - |
| Identity audit logs (WorkOS) | 6 years |
| Application audit logs (CloudWatch) | 6 years (Enterprise), 1 year (other tiers) |
| User sign-in sessions | Managed by WorkOS; configurable per-org for Enterprise |
Six-year retention satisfies HIPAA's audit requirement. ISO 27001 and SOC 2 audits accept the same retention period.
## Compliance and legal hold
For litigation hold or regulatory retrieval requests:
* The WorkOS audit log can be exported via the portal in CSV or JSON.
* CloudWatch logs can be exported via your AWS account if Enterprise log forwarding is set up; otherwise, contact Summand support and we'll export for you within 5 business days.
# Compliance
Source: https://docs.summand.com/enterprise/compliance
Summand's compliance posture: HIPAA, SOC 2, ISO 27001, GDPR, CCPA — and what we ask of customers in return.
Summand is built for regulated industries. The full set of controls — data residency, audit retention, key management, penetration testing — is implemented at the infrastructure level on AWS, with identity controls layered through WorkOS.
## Frameworks
| Framework | Status |
| - | - |
| **HIPAA** | Compliant. BAA available for Enterprise customers handling PHI. |
| **SOC 2 Type II** | Audited annually. Latest report available under NDA. |
| **ISO 27001** | Aligned. Certification on roadmap. |
| **GDPR** | Compliant for processing of EU personal data. DPA available. |
| **CCPA** | Compliant for processing of California consumer data. |
## What's covered
### Data at rest
* AWS-managed KMS encryption on all DynamoDB tables, S3 buckets, and Secrets Manager secrets.
* Customer data is logically isolated per organization.
* Backups are encrypted with the same KMS keys; backup retention aligns with the source data's retention.
### Data in transit
* TLS 1.2+ for every external connection. TLS 1.3 preferred.
* Database connectors require certificate validation; self-signed certs are rejected.
* Internal service-to-service traffic is also TLS-encrypted within AWS VPCs.
### Identity and access
* All authentication routed through WorkOS, which is itself SOC 2 Type II compliant.
* MFA enforceable at the org level (WorkOS) and at sensitive-operation level (Summand).
* Sessions are managed by WorkOS AuthKit and refresh on the standard short-cookie/long-refresh pattern. Enterprise customers can adjust session lifetime per-org through the WorkOS Admin Portal.
* Cookie attributes: `HttpOnly`, `Secure`, `SameSite=Lax` for CSRF protection.
### Audit and monitoring
* All identity events retained for 6+ years (WorkOS).
* All application events retained 1-6 years depending on tier.
* Log streaming to customer-controlled SIEMs (Datadog, Splunk, S3, HTTPS).
* CloudWatch alarms on Lambda errors, DLQ depth, and authorization failures.
### Operational security
* Annual third-party penetration test; report shared under NDA on request.
* Quarterly internal vulnerability scans.
* Dependencies tracked via Dependabot; security-relevant updates merged within 7 days.
* Production access via federated identity (no shared credentials); all production sessions logged.
### Personnel
* Background checks for all employees with production access.
* Annual security awareness training.
* Access provisioning and deprovisioning automated through your-IdP-of-record (we use the same WorkOS we sell).
## HIPAA-specific notes
For Protected Health Information (PHI):
* A Business Associate Agreement (BAA) is required and provided to all Enterprise customers handling PHI.
* PHI must be processed within Summand's HIPAA-eligible services. By default, all Summand infrastructure is HIPAA-eligible.
* Audit log retention is set to 6 years to meet HIPAA's audit standard.
* Optional: dedicated infrastructure for organizations with the strictest requirements. Contact sales.
The standard Enterprise tier is suitable for most PHI workloads. For MIPS, the most stringent NIST 800-53 controls, or FedRAMP Moderate-equivalent profiles, contact sales.
## GDPR / data protection
* Summand processes personal data only as instructed by the customer (data controller). We're a processor under GDPR.
* A Data Processing Addendum (DPA) is included in every Enterprise contract.
* Subprocessors are listed on our [trust page](https://trust.intelligible.ai). Material changes are notified 30 days in advance.
* Customer data can be deleted on request; a confirmation of deletion is provided within 30 days.
### Data residency
* All Summand infrastructure runs in AWS `us-east-1` (Northern Virginia).
* For customers with strict residency requirements outside the US, contact [our sales team](https://intelligible.ai/contact) — alternative regions can be discussed under contract.
## Subprocessors
A complete, current list lives at [summand.com/subprocessors](https://summand.com/subprocessors). The headline ones:
* **AWS** — primary infrastructure
* **WorkOS** — identity, SSO, Directory Sync, audit logs
* **Stripe** — billing
* **Anthropic** — backs the Summand AI assistant
* **Vercel** — frontend hosting
## Customer responsibilities
A few controls are yours to configure:
* **MFA enforcement** — required vs. optional, set per org.
* **SSO setup** — verify domains, configure connections.
* **Sharing decisions** — who you grant access to, and at what visibility.
* **Audit log review** — Summand exposes the data; routine review is your security team's responsibility.
* **Off-boarding** — pair SSO with Directory Sync so user removal is automatic.
## Asking for documents
For NDA-gated artifacts (SOC 2 report, pen test report, DPA, BAA), email [security@intelligible.ai](mailto:security@intelligible.ai) from a verified work address. Standard turnaround is 1-2 business days.
# Multi-factor authentication
Source: https://docs.summand.com/enterprise/mfa
How MFA works in Summand — at the WorkOS layer for sign-in, and at the Summand layer for sensitive operations.
Summand has MFA in two places: at sign-in (handled by WorkOS) and at sensitive operations like accessing private shared datasets (handled by Summand).
## Sign-in MFA via WorkOS
Org admins can require MFA for every user in the organization, enforced at the WorkOS layer. This applies to email + password sign-ins, SSO sign-ins where the IdP doesn't already enforce MFA, and the Continue with Google / GitHub paths.
### Enforcement
Two modes:
| Mode | Behavior |
| - | - |
| **Required** | Every user must enroll a TOTP factor on first sign-in. No factor = no access. |
| **Optional** | Users may enroll a factor; access is granted with or without it. |
Configure in the WorkOS Admin Portal — **Settings → Organization** in Summand → click into the WorkOS-hosted org settings.
### Enrollment flow
A new user with MFA required:
1. Signs in with email + password (or SSO).
2. Hits the MFA enrollment screen with a QR code and a manual entry secret.
3. Scans the QR with Google Authenticator, 1Password, Authy, or any TOTP app.
4. Enters the 6-digit code to confirm.
5. Future sign-ins prompt for the 6-digit code after credentials.
The enrollment UI lives in `summand-web/components/features/auth/LoginForm.tsx` — same screen flow whether the user signed in via SSO or password.
### Recovery
If a user loses their device:
* **Self-recovery:** WorkOS supports backup codes (issued at enrollment). The user enters a backup code instead of the 6-digit TOTP.
* **Admin reset:** An org admin resets the user's MFA from **Settings → Organization → Members → Reset MFA**. The user re-enrolls on next sign-in.
Hardware keys (FIDO2 / WebAuthn) are on the WorkOS roadmap; today, MFA is TOTP-based.
## Per-operation MFA in Summand
Independently of sign-in MFA, Summand requires re-authentication for two sensitive operations:
* **Accessing a private dataset shared with you** — proves ongoing possession of the second factor, not just an active session.
* **Granting share access to a teammate** — for grants on private or sensitive datasets.
This is enforced regardless of how the user signed in. If they're MFA-enrolled, they enter their TOTP code; if they're not enrolled and the operation is hit, they're forced to enroll on the spot.
This is an intentional layer beyond sign-in MFA — long-lived sessions are cheap to compromise via cookie theft, but a fresh second-factor challenge isn't.
## Recommendation
For most enterprises:
* **Require sign-in MFA at the IdP.** This is the strongest layer — your IdP enforces it for every login attempt across every SaaS, including Summand.
* **Require sign-in MFA in WorkOS** as a backstop for sources where the IdP doesn't enforce it (e.g. social login).
* **Leave per-operation MFA on.** It's the protection that catches stolen-cookie scenarios.
For HIPAA-regulated data, all three layers are recommended.
## Audit
Every MFA enrollment, factor verification, and reset is logged. Events are visible in **Audit Logs** in the WorkOS Admin Portal and forwarded to your SIEM via Log Streams. See [Audit logs](/enterprise/audit-logs).
# Organizations
Source: https://docs.summand.com/enterprise/organizations
How org structure, membership, and roles work in Summand on Enterprise plans.
On Enterprise plans, **organizations** are the unit of multi-tenancy. An organization owns one or more workspaces, has its own SSO and Directory Sync configuration, and bills as a single account. Members are managed in WorkOS and surfaced in Summand.
## Provisioning
Enterprise organizations are provisioned through sales — once the contract is signed and a designated admin is named, we set up the organization in WorkOS and invite the admin by email. This is deliberate:
* **No domain squatting.** A random user signing up with a `@yourcompany.com` email can't claim an organization.
* **Verified admins.** The first admin is the person named in the contract.
* **Clean audit trail.** Provisioning events come from a sales actor, not anonymous signup.
To get an organization, contact [our sales team](https://intelligible.ai/contact).
## Roles
| Role | Manage SSO / SCIM | Manage members | Manage billing | Create datasets | Read all org datasets |
| - | - | - | - | - | - |
| **Owner** | ✓ | ✓ | ✓ | ✓ | ✓ |
| **Admin** | ✓ | ✓ | — | ✓ | ✓ |
| **Member** | — | — | — | ✓ | only ones shared with them |
Roles can be assigned manually in **Settings → Organization → Members** or mapped from IdP groups via Directory Sync. Per-resource access (Owner / Editor / Viewer on a specific dataset or connector) is separate — see [Sharing](/concepts/sharing).
## Domains
An organization can own multiple verified domains — useful for companies with subsidiary brands (`acme.com` + `acme-labs.com`). Each domain is verified independently via DNS TXT record. Once verified, sign-ins from that domain are routed to your SSO connection automatically.
To add a domain after the org is provisioned: **Settings → Organization → Domain Verification → Configure** in the WorkOS Admin Portal.
## Seat management
Each organization has a seat count tied to your contract. Seats are consumed when a user is added — either by manual invitation, JIT provisioning at first SSO sign-in, or SCIM provisioning from your IdP.
The current seat count vs. your limit is shown in **Settings → Organization** at the top of the page. If you're approaching the limit, contact your account manager — or remove inactive members first.
## Member lifecycle
| Event | What Summand does |
| - | - |
| User added in your IdP, then signs in via SSO | JIT-provisioned as **member** (or mapped role) |
| User added to a SCIM-synced group | Provisioned automatically with mapped role |
| User removed from the IdP | Sessions invalidated within minutes; seat freed (if SCIM is on) |
| User removed without SCIM | Sessions invalidated on next refresh; account remains until manually suspended |
| User suspended manually in Summand | Sessions invalidated immediately; data preserved |
| User deleted in Summand | Account removed; their datasets transferred to the org owner |
For air-tight deprovisioning, run SSO + Directory Sync together. Without SCIM, you'll need to manually suspend users when they leave.
## Workspaces
Within an organization, **workspaces** are an optional grouping for separating datasets across teams (e.g. `marketing-analytics` and `risk`). All workspaces share the org's billing, SSO, and member pool — workspaces are about organization, not isolation. For hard isolation between business units, use separate organizations.
# Enterprise overview
Source: https://docs.summand.com/enterprise/overview
What the Enterprise tier unlocks and how to roll it out across your organization.
The Enterprise tier is for organizations that need centralized identity, governed access, audit trails, and direct database connectivity. Everything in Pro, plus:
SAML 2.0 and OIDC for Okta, Entra ID, Google Workspace, OneLogin, JumpCloud, Auth0, Ping, and custom IdPs — all configured via the WorkOS Admin Portal.
SCIM-based auto-provisioning and deprovisioning. Users created when added to an IdP group, removed when they leave.
TOTP enforcement at the WorkOS layer, with optional Summand-layer MFA for shared private datasets.
Auth and security events streamed to Datadog, Splunk, S3, or any HTTPS webhook.
HIPAA, SOC 2 Type II, ISO 27001, GDPR, CCPA — with BAA available.
Direct PostgreSQL, MySQL, Snowflake. Plus Fivetran for everything else.
## Rollout sequence
A typical Enterprise rollout is four steps. Items can run in parallel — most customers are fully live in 1-2 weeks.
Sales creates an organization for your domain. You'll receive an invitation email naming a designated admin user. Domains are sales-provisioned (not self-claim) to prevent squatting.
From **Settings → Organization**, click **Configure** under *Domain Verification* and *Single Sign-On*. Both buttons open the WorkOS Admin Portal — Summand's identity layer is built on WorkOS, so SSO setup runs there rather than in a Summand-side wizard. See the [SSO guides](/enterprise/sso/overview) for IdP-specific steps.
From **Settings → Organization**, configure:
* **SSO** (required for SSO-eligible domains) and **Directory Sync** for SCIM
* **MFA enforcement** (TOTP at the WorkOS layer, with optional Summand-layer MFA for sensitive ops)
* **Audit logs** and **Log Streams** for SIEM forwarding
* Member roles and seat counts
Users sign in with their company email. Summand detects the verified domain, redirects to your IdP, and JIT-provisions the user on first sign-in. Pair this with Directory Sync so users are also auto-deprovisioned when removed from the IdP.
## Roles and permissions
Enterprise plans have four roles, manageable from **Settings → Members**:
| Role | What they can do |
| - | - |
| **Org admin** | Manage SSO, MFA, billing, members, audit logs. Full visibility into everyone's datasets. |
| **Workspace admin** | Manage members and connectors within a workspace. No billing/SSO control. |
| **Member** | Create datasets, share, run analysis. Standard user. |
| **Guest** | Read-only access to datasets explicitly shared with them. No connector creation. |
Roles can be assigned manually or mapped from IdP groups via SSO group sync.
## Support
Enterprise customers get:
* **Email support** — 4-hour response SLA for production issues
* **Dedicated CSM** — single point of contact for onboarding, training, and roadmap input
* **99.9% uptime SLA** — credited per the contract
* **Priority feature requests** — direct line to the product team
Reach support at [support@intelligible.ai](mailto:support@intelligible.ai) or via the in-product chat.
# Azure AD / Entra ID SSO
Source: https://docs.summand.com/enterprise/sso/azure-ad
Connect Microsoft Entra ID (formerly Azure AD) to Summand via the WorkOS Admin Portal.
Microsoft Entra ID supports both OIDC and SAML 2.0 against Summand. Setup runs through the WorkOS Admin Portal that Summand opens from the organization settings — there's no Summand-side SAML wizard.
## What Entra unlocks
| Capability | WorkOS intent | Notes |
| - | - | - |
| **OIDC SSO** | `sso` | Recommended path for Entra. Uses Microsoft Identity Platform v2.0. |
| **SAML 2.0 SSO** | `sso` | Use if your security team specifically requires SAML. |
| **Directory Sync (SCIM)** | `dsync` | Provisions and deprovisions users from Entra. |
OIDC is generally simpler with Entra — Microsoft's native protocol — but SAML works equally well. Pick whichever your team standardizes on.
## Setup
**Settings → Organization → Domain Verification → Configure**, and follow the DNS TXT record flow. Once verified, Summand will route sign-ins from this email domain to your Entra tenant.
**Settings → Organization → Single Sign-On → Configure**. The portal opens scoped to your org.
In the portal, choose **Microsoft Entra ID** (formerly Azure AD) and the protocol you want — OIDC or SAML.
In the [Microsoft Entra admin center](https://entra.microsoft.com), register a new application:
* **For OIDC** — *App registrations → New registration*. The portal provides a redirect URI to paste in.
* **For SAML** — *Enterprise applications → New application → Create your own application → Non-gallery*. The portal provides Reply URL and Identifier.
Detailed Microsoft-side steps live in the [WorkOS Microsoft Entra ID guide](https://workos.com/docs/sso/identity-provider-handbook/azure).
The portal lists the attributes WorkOS expects (`email`, `name`, optionally `given_name`, `family_name`, `groups`). Configure them on the Entra side under *Token configuration* (OIDC) or *Attributes & Claims* (SAML).
For OIDC, paste the **Tenant ID**, **Client ID**, and **Client Secret** into the portal. For SAML, paste the **App Federation Metadata URL** the portal validates and parses.
Click *Test connection* in the portal. WorkOS runs an end-to-end Entra sign-in flow and reports the result.
On the Entra application's **Users and groups** tab, assign the people or security groups who should access Summand.
**Settings → Organization → Directory Sync → Configure**. Pick **Microsoft Entra ID SCIM**, follow the portal, and complete the provisioning configuration on the Entra side.
## Conditional Access
If your tenant uses Conditional Access policies, ensure the Summand-via-WorkOS application is included in your policy scope and that your policies allow access from the device and network the user is signing in from. Common cause of "user can authenticate at Microsoft but not get back to Summand" is a Conditional Access policy that blocks the redirect.
## Group → role mapping
Two ways:
* **Via the SAML/OIDC `groups` claim** — Entra sends group IDs (or names if you've mapped them). Map specific groups to Summand roles in the WorkOS portal.
* **Via Directory Sync** (recommended) — Entra groups become WorkOS groups; map them to Summand roles in **Settings → Organization → Members**.
A common Entra-specific quirk: by default Entra emits group **Object IDs** (GUIDs), not names. Either configure group claim mapping to send `sAMAccountName` / display names, or paste the GUIDs directly into the WorkOS portal and label them there.
## Removing the connection
**Single Sign-On → Disable** in the WorkOS portal. Sessions outlive the connection until they naturally expire — revoke them in **Settings → Organization → Members** for immediate effect.
# Other identity providers
Source: https://docs.summand.com/enterprise/sso/generic-saml
Connect any standards-compliant SAML 2.0 or OIDC IdP — OneLogin, JumpCloud, Auth0, Ping, custom — via the WorkOS Admin Portal.
Summand supports any IdP supported by [WorkOS](https://workos.com). The WorkOS Admin Portal is the configuration surface; Summand opens it for you from organization settings.
## IdPs with first-class WorkOS support
Beyond Okta, Entra, and Google Workspace (which have their own pages), WorkOS ships preset wizards for:
* **OneLogin** (SAML, OIDC, SCIM)
* **JumpCloud** (SAML, SCIM)
* **Auth0** (OIDC)
* **Ping Identity** (SAML)
* **Duo SSO** (SAML)
* **Salesforce** (SAML)
* **VMware Workspace ONE** (SAML)
* **CyberArk Identity** (SAML)
* **Rippling** (SAML, SCIM)
* **BambooHR** (SCIM directory only)
Plus generic **SAML 2.0** and **OIDC** options for anything not in the list — including custom in-house IdPs.
The full, current list lives in WorkOS's [Identity Provider Handbook](https://workos.com/docs/sso/identity-provider-handbook).
## Setup
The flow is identical for every IdP:
**Settings → Organization → Domain Verification → Configure**.
**Settings → Organization → Single Sign-On → Configure**. Pick your IdP from the list.
The portal provides the ACS URL / redirect URI / Entity ID, and tells you which attributes to send. Configure the IdP using its own admin UI.
Most IdPs provide a metadata URL or XML download. Paste it; WorkOS validates the certificate and pre-fills.
Click *Test connection* in the portal.
If your IdP supports SCIM and you want auto-deprovisioning, **Settings → Organization → Directory Sync → Configure** and walk through the SCIM setup.
## Required attributes
Whatever IdP you use, the SAML response (or OIDC ID token) must include:
| Attribute | Required | Purpose |
| - | - | - |
| `email` | ✓ | Primary identifier |
| `name`, or `given_name` + `family_name` | ✓ | Display name |
| `groups` | optional | For group-based role mapping |
Summand-side mapping happens inside the WorkOS portal — you can rename source attributes and bind groups to roles without touching the IdP again.
## Custom in-house IdPs
If you run your own SAML or OIDC provider:
* For **SAML**, use the **Generic SAML** option in the WorkOS portal. Provide your IdP's metadata URL or paste the SSO URL, Entity ID, and X.509 certificate manually.
* For **OIDC**, use the **Generic OIDC** option. Provide the issuer URL, client ID, and client secret. Required scopes: `openid`, `email`, `profile`.
WorkOS handles RelayState, encrypted assertions, and standard SAML signing patterns. For unusual setups (e.g. signed authn requests with a custom signing key), contact [support@intelligible.ai](mailto:support@intelligible.ai) — Enterprise customers can request a guided integration session.
## What if my IdP isn't supported?
If WorkOS doesn't support your IdP and the generic SAML / OIDC paths don't work:
* Most IdPs are reachable through OneLogin or Auth0 as a layer.
* For brand-new IdPs gaining traction, [WorkOS regularly ships new connectors](https://workos.com/changelog) — file a request via Summand support and we'll forward it.
* For air-gapped enterprise deployments, contact sales — we can discuss a private deployment.
# Google Workspace SSO
Source: https://docs.summand.com/enterprise/sso/google-workspace
Connect Google Workspace to Summand via the WorkOS Admin Portal — custom SAML 2.0.
Google Workspace integrates with Summand via SAML 2.0 through the WorkOS Admin Portal. (Direct **Continue with Google** OAuth is also available on the login screen for any Google user — that's separate from org-managed SSO.)
## Setup
**Settings → Organization → Domain Verification → Configure**, then publish the DNS TXT record. Verified domains are routed to your Workspace SSO on sign-in.
**Settings → Organization → Single Sign-On → Configure**. The portal opens scoped to your org.
Choose **Google Workspace** in the portal. WorkOS provides:
* The **ACS URL**
* The **Entity ID**
* The required attributes: `email`, `name`, optionally `given_name`, `family_name`
From [admin.google.com](https://admin.google.com), go to **Apps → Web and mobile apps → Add app → Add custom SAML app**. Paste the ACS URL and Entity ID from the portal; set Name ID format to **EMAIL** and Name ID to **Basic Information → Primary email**.
Detailed Google-side steps are in the [WorkOS Google Workspace guide](https://workos.com/docs/sso/identity-provider-handbook/google-workspace).
Map these attributes:
| App attribute | Source |
| - | - |
| `email` | Primary email |
| `name` | Full name (first + last) |
| `given_name` | First name |
| `family_name` | Last name |
On the SAML app's IdP details page, download the **Metadata** XML or copy the SSO URL, Entity ID, and certificate.
Upload the metadata XML (or paste the individual fields). WorkOS validates and pre-fills.
Back in Google Admin, on the SAML app page, set the service status to **On for everyone** (or for a specific OU). New apps default to *Off*, which is the most common cause of "user gets blocked at Google" errors.
Click *Test connection* in the WorkOS portal. WorkOS runs an end-to-end Google sign-in flow and reports the result.
## Group → role mapping
Google's custom SAML apps don't send group memberships in the SAML response by default. If you want group-based role mapping in Summand, pick the option that fits:
* **Manual mapping by Google Group address** — list a Google Group's email in the WorkOS portal and bind it to a Summand role.
* **Cloud Identity** — Google Cloud Identity supports richer claim attributes, including arbitrary group sends.
* **Workspace-only orgs** — for most teams, mapping by group address is enough and removes the need to enable Cloud Identity.
## Why no Directory Sync?
Google Workspace **does** support SCIM, and WorkOS supports a Workspace SCIM connector. If you want it, **Settings → Organization → Directory Sync → Configure** and pick **Google Workspace** in the portal — note that this requires your Workspace admin to set up a service account and enable the Admin SDK API on the Google side. The WorkOS portal walks through that.
## Removing the connection
**Single Sign-On → Disable** in the WorkOS portal. Existing sessions persist until expiry; revoke explicitly via **Settings → Organization → Members** if you need an immediate sign-out.
# Okta SSO
Source: https://docs.summand.com/enterprise/sso/okta
Connect Okta to Summand via the WorkOS Admin Portal — SAML, OIDC, and SCIM.
Okta is one of the best-tested IdPs in WorkOS, the identity layer Summand uses. Setup happens entirely inside the WorkOS Admin Portal, which Summand opens for you from the organization settings. You don't need to copy anything between Summand and Okta directly — the portal sits in the middle.
## What Okta unlocks
| Capability | WorkOS intent | Notes |
| - | - | - |
| **SAML 2.0 SSO** | `sso` | Most common path. Uses Okta's SAML app integration. |
| **OIDC SSO** | `sso` | Alternative; pick whichever your security team prefers. |
| **Directory Sync (SCIM)** | `dsync` | Auto-provisions and deprovisions users on Okta group membership changes. |
You can configure SSO without Directory Sync — users will be JIT-provisioned on first sign-in. For production, we strongly recommend pairing SSO with Directory Sync so deprovisioning is automatic.
## Setup
In Summand, go to **Settings → Organization → Domain Verification → Configure**. The portal asks you to publish a DNS TXT record. Once verified, Summand routes any sign-in attempt from that email domain to your Okta tenant.
From **Settings → Organization → Single Sign-On**, click **Configure**. Summand POSTs to `/api/workos/portal` with `intent: sso`, gets a one-time link, and redirects you. The portal session is scoped to your org and expires shortly after.
Inside the portal, choose **Okta** as the connection type. WorkOS's wizard provides:
* The **Single Sign-On URL** (ACS) you paste into Okta
* The **Audience URI** (Entity ID) you paste into Okta
* The required attribute statements: `email`, `name`, optionally `given_name` / `family_name` and `groups`
In your Okta admin console, **Applications → Create App Integration → SAML 2.0**. Paste the values from the portal into Okta's *Configure SAML* screen, set Name ID format to **EmailAddress**, add the attribute statements, and finish.
Detailed Okta-side steps live in the [WorkOS Okta SSO guide](https://workos.com/docs/sso/identity-provider-handbook/okta).
On Okta's *Sign On* tab, copy the **Identity Provider metadata URL** (or download the XML). Paste it into the WorkOS portal. The portal validates the certificate, parses the metadata, and surfaces any mismatches inline.
Click *Test connection* in the portal. WorkOS opens an Okta auth flow in a popup and reports success or a specific error. On success, the connection moves to *Active*.
From the Okta SAML app's **Assignments** tab, assign the people or groups who should be able to sign in to Summand.
Back in Summand, **Settings → Organization → Directory Sync → Configure**. Pick Okta SCIM and follow the portal's wizard. You'll provision a SCIM URL and bearer token, paste them into Okta's *Provisioning* tab on the SAML app, and toggle the SCIM features (Create Users / Update User Attributes / Deactivate Users / Group Push) you want enabled.
## What it looks like to your users
Once the connection is live, Okta-managed users sign in this way:
1. Open `summand.com`.
2. Enter their company email (e.g. `name@acme.com`).
3. Summand detects the verified domain and redirects them to Okta.
4. They authenticate at Okta as usual.
5. They land back in Summand, signed in. First-time users are auto-provisioned as standard members.
There's no "Sign in with Okta" button to click and no workspace URL to remember.
## Group → role mapping
If you want Okta groups mapped to Summand roles automatically, two paths:
* **Via SAML group attribute** (light) — Okta sends a `groups` attribute in the SAML response. WorkOS captures it; you map specific groups to Summand roles in the portal.
* **Via Directory Sync** (recommended) — Okta groups are first-class objects in WorkOS, and you map them to Summand roles in **Settings → Organization → Members**. Changes in Okta propagate within seconds.
Use Directory Sync if you can — group changes survive token refresh and aren't dependent on the user re-authenticating.
## Removing the connection
From the WorkOS portal, **Single Sign-On → Disable**. Active sessions remain valid until they naturally expire — to force immediate sign-out, also revoke sessions in **Settings → Organization → Members**. Once disabled, sign-in falls back to password (or other configured methods) for the affected domain.
# SSO overview
Source: https://docs.summand.com/enterprise/sso/overview
How Summand uses the WorkOS Admin Portal for SSO setup — and what your admin can configure from a single dashboard.
Summand's identity layer is built on [WorkOS](https://workos.com). When an org admin clicks **Configure** under any Enterprise feature in **Settings → Organization**, Summand generates a one-time WorkOS **Admin Portal** link and redirects you to it. The portal is where every actual configuration step happens — Summand doesn't reimplement the IdP wizard.
This means every IdP and integration WorkOS supports is automatically available to Summand customers, without us shipping a new release.
## What's available in the Admin Portal
The portal exposes one hosted UI per **intent**. Each intent is a separate "Configure" button in Summand's organization settings.
| Intent | What it configures | Common IdP examples |
| - | - | - |
| **SSO** | SAML 2.0 or OIDC for sign-in | Okta, Azure AD / Entra, Google Workspace, OneLogin, JumpCloud, Auth0, Ping, custom |
| **Directory Sync** | SCIM provisioning + deprovisioning | Okta, Azure AD, OneLogin, JumpCloud, BambooHR, Rippling |
| **Domain Verification** | Claim ownership of an email domain | DNS TXT record validation |
| **Audit Logs** | View authentication & security events | WorkOS-hosted log viewer |
| **Log Streams** | Forward events to your SIEM | Datadog, Splunk, AWS S3, generic webhook |
| **Certificate Renewal** | Rotate SAML signing certificates | Per-IdP rotation flows |
See the per-IdP guides for setup details:
SAML or OIDC, with optional SCIM directory sync.
OIDC or SAML, with Entra-native directory sync.
Custom SAML, with manual user provisioning.
OneLogin, JumpCloud, Auth0, Ping, custom — any standards-compliant SAML or OIDC provider.
## How sign-in works
```
User enters email at summand.com
│
▼
Summand calls /api/auth/sso/check-domain
│ GET workos.organizations.listOrganizations({ domains: [] })
▼
Domain matches a WorkOS organization with SSO?
│
├─ Yes → redirect to WorkOS authorization URL
│ └─ User authenticates at the IdP
│ └─ WorkOS validates the response
│ └─ Redirects to /auth/callback with code
│ └─ Summand exchanges the code for a session
│ └─ JIT-provisions the user if first sign-in
│ └─ Sets session cookies → user is in
│
└─ No → falls back to email + password (or Google / GitHub OAuth)
```
The user **never types a workspace URL**. Email-domain lookup handles routing automatically. Summand also exposes direct **Continue with Google** and **Continue with GitHub** buttons on the sign-in screen — those go straight to WorkOS's hosted social providers.
## Setting up SSO end-to-end
From **Settings → Organization → Domain Verification**, click **Configure**. The Admin Portal asks you to add a TXT record at the apex of your domain. Once DNS propagates and you click *Verify*, that domain becomes the routing key for SSO sign-ins.
Multiple domains are supported — verify each one separately.
From **Settings → Organization → Single Sign-On**, click **Configure**. The Admin Portal opens; pick your IdP (Okta, Azure AD, Google Workspace, etc.) and follow the per-IdP wizard. WorkOS provides ACS URLs, Entity IDs, and metadata download links inline — copy them into your IdP, paste your IdP's metadata back into the portal, and click *Test*.
The whole step takes 5-10 minutes if you have IdP admin access.
Under **Directory Sync → Configure**, connect a SCIM provider so users are auto-provisioned when added to your IdP and auto-deprovisioned when removed. Without directory sync, users are JIT-created on first sign-in but not removed automatically when they leave.
Under **Log Streams → Configure**, forward auth events to Datadog, Splunk, S3, or any HTTPS webhook. Keep this enabled in production for compliance.
Open `summand.com` in an incognito window, enter an email at your verified domain, and confirm you're redirected to your IdP. New users are auto-provisioned via JIT and added to your WorkOS organization.
## Authentication options
Summand surfaces three sign-in paths on the login screen:
| Method | When to use |
| - | - |
| **Email-based SSO** | Default for SSO-enabled domains. Email entry triggers IdP redirect automatically. |
| **Continue with Google / GitHub** | Direct social login via WorkOS-hosted OAuth, useful for individual accounts. |
| **Email + password** | Fallback for non-SSO domains and individual accounts. |
Email + password and social login coexist with SSO. If your org wants password login disabled for SSO-eligible domains, configure that in your **WorkOS organization settings** via the Admin Portal — it's enforced at the WorkOS layer, not in Summand code.
## Just-in-time (JIT) provisioning
When a new user signs in via SSO for the first time, Summand creates their account automatically using attributes from the IdP. Required attributes:
| Attribute | Purpose |
| - | - |
| `email` | Primary identifier |
| `name` (or `given_name` + `family_name`) | Display name |
Group memberships and roles are mapped via Directory Sync if enabled, or manually in **Settings → Organization → Members**.
## What Summand stores vs. what WorkOS stores
| Data | Stored in |
| - | - |
| User identity, sessions, MFA factors | WorkOS |
| SSO connection config (cert, ACS URL, attributes) | WorkOS |
| Directory sync state | WorkOS |
| Audit log events for auth | WorkOS (forwarded to your SIEM via Log Streams) |
| Organization membership in Summand | Summand DynamoDB |
| Datasets, connectors, computed-context layers | Summand AWS |
This split is intentional — identity-critical data is held by a SOC 2 Type II identity provider rather than reimplemented inside Summand.
## Troubleshooting
For symptom-level debugging — bad metadata, attribute mismatches, certificate issues — see [SSO troubleshooting](/enterprise/sso/troubleshooting).
# SSO troubleshooting
Source: https://docs.summand.com/enterprise/sso/troubleshooting
Diagnose common sign-in failures across the WorkOS-backed SSO stack.
Most SSO issues fall into one of five categories. Match the symptom to the section, follow the checks in order, and contact [support@intelligible.ai](mailto:support@intelligible.ai) if nothing fits.
## Domain isn't routed to my IdP
**Symptom:** You enter your company email at `summand.com` but Summand asks for a password instead of redirecting to your IdP.
**Settings → Organization → Domain Verification**. The domain you typed in the email field must show *Verified*. If it's *Pending*, re-check the DNS TXT record.
**Settings → Organization → Single Sign-On**. The connection state should be *Active*. *Draft* or *Inactive* means setup wasn't completed.
Subdomains aren't matched against parent domains. If you verified `acme.com` and the user signs in with `eng@labs.acme.com`, that's a different domain — verify it separately.
## "No SSO provider found for this email domain"
**Symptom:** Sign-in fails with this exact message before reaching the IdP.
This means `/api/auth/sso/check-domain` matched a verified domain in WorkOS but couldn't find a corresponding SSO connection on that organization. Either:
* The connection was deleted from the WorkOS portal but the domain is still registered, or
* The connection was set up for a different organization than the one the domain is on.
**Fix:** open the WorkOS Admin Portal (**Settings → Organization → Single Sign-On → Configure**) and confirm an active connection exists. If not, configure one.
## User reaches IdP but bounces back with an error
**Symptom:** The IdP authenticates the user (no errors at the IdP) but Summand shows *Sign-in failed* on return.
The IdP's configured ACS URL or redirect URI must match what the WorkOS portal showed exactly — every character, every trailing slash. Re-paste from the portal.
SAML certificates expire. The portal flags expired certs in **Single Sign-On → Connection details**. Renew via **Certificate Renewal → Configure** and re-upload from your IdP.
The SAML response (or OIDC ID token) must include `email` and either `name` or both `given_name` and `family_name`. Some IdPs default to omitting these unless you explicitly add them.
For Okta, the user must be assigned to the SAML app under *Assignments*. For Entra, on *Users and groups*. For Google Workspace, the SAML app must be turned on for the user's OU.
## "Invalid SAML response" or "Bad assertion"
**Symptom:** The error message references the SAML response itself — invalid signature, untrusted certificate, schema mismatch.
Click **Refresh metadata** on the connection in the WorkOS portal. If the metadata URL has rotated certificates, this picks up the new ones.
SAML responses include `NotBefore` and `NotOnOrAfter` timestamps. If your IdP's clock is far ahead/behind UTC, responses are rejected. WorkOS allows \~5 minutes of skew; clocks more than 5 minutes off need fixing on the IdP side.
The IdP must return Name ID in `EmailAddress` format. Re-check the IdP's SAML configuration — it's the most commonly misconfigured field.
## Group → role mapping doesn't work
**Symptom:** SSO sign-in succeeds, but users land in Summand without the role you'd expect from their IdP group.
Open the WorkOS Admin Portal → **Single Sign-On → Connection → Test Connection**. The test result shows the raw attributes WorkOS received. If `groups` isn't there, the IdP isn't sending it.
Most issues here are Entra-specific — Entra emits group **Object IDs** (GUIDs) by default, not display names. Either configure Entra to emit `sAMAccountName`, or paste the GUIDs into the WorkOS portal mapping.
SAML group claims are sent at sign-in time. Adding a user to a group in your IdP doesn't update the claim until they sign in again. For real-time group propagation, use Directory Sync instead.
## Directory Sync isn't provisioning users
**Symptom:** Users added to a synced group in your IdP don't appear in Summand.
**Settings → Organization → Directory Sync** should show the connection as *Active*. If it's *Linked* but not *Active*, the SCIM provisioning step on the IdP side hasn't been enabled.
From the WorkOS portal, regenerate the SCIM bearer token and re-paste it into the IdP. Common issue: the token was rotated in WorkOS and the IdP-side value drifted.
Most IdPs require you to explicitly assign users *and* groups to the SCIM app. Just being in the IdP isn't enough — the SCIM scope is opt-in.
The WorkOS portal's **Directory Sync** view shows recent SCIM events with success/failure status and the raw IdP payload. Failed events usually reveal a missing required attribute or a malformed group reference.
## When to escalate
If you've worked through the relevant section and still can't sign in:
1. From the WorkOS portal, run *Test Connection* and capture the full error text.
2. Note the user's IdP, browser, and the timestamp of the failed attempt.
3. Email [support@intelligible.ai](mailto:support@intelligible.ai) with all three. Enterprise customers also have a `#summand-support` channel — drop the same details there for faster escalation.
# Ask Summand
Source: https://docs.summand.com/guides/ask-summand
How to get useful answers out of the in-product assistant.
**Summand** is the AI assistant inside every Summand dataset. It answers questions in plain English and generates charts on demand, grounded in the dataset's [computed-context layer](/concepts/computed-context).
## What Summand can do
* Answer questions about the data (*"What's the mean of `revenue` by segment?"*).
* Generate one-shot SQL and run it against your curated data via Athena.
* Generate charts (*"Show me a histogram of `tenure` colored by `churned`."*).
* Explain feature importance and shape functions when a Predictors experiment has run.
* Drill into surprising rows when a Surprise-finding experiment has run.
* **Draft views** — *"build me a view that joins orders with customers"* — with a save button on the rendered SQL.
## What Summand can't do
* **Modify the dataset.** No re-uploads, no schema changes, no sharing actions from chat — those are explicit UI operations.
* **Run mutations.** SQL is read-only; no `INSERT` / `UPDATE` / `DELETE`.
* **Reach data you don't own.** Same authorization model as the rest of the product, enforced through OpenFGA.
## How to ask better questions
Instead of *"what's the relationship between price and sales,"* say *"plot `unit_price` against `units_sold` and add a regression line."* Summand performs better with explicit column names.
The dataset's **Context** field (set on the Configuration sidebar) is included in every Summand turn. Put dataset-level facts there — *"orders in USD, B2C only, Q1 2026"* — instead of repeating them per message.
The first chart is rarely the right one. Ask for changes in plain English: *"color this by region,"* *"flip the axes,"* *"only show the top 10 categories."* Summand edits the chart in place.
Summand is most useful for questions that map to one or two computed-context reads. For multi-paragraph reports, use it to draft, then edit by hand — don't rely on it to write narrative analysis end-to-end.
## Limits
| Tier | Questions | Conversation history | Message length | Context window |
| - | - | - | - | - |
| Free | 20 / week | 7 days | 2,000 chars | 4,000 tokens |
| Pro / Education | Unlimited | 90 days | 4,000 chars | 8,000 tokens |
| Enterprise | Unlimited | 365 days | 4,000 chars | 16,000 tokens |
The **context window** is how much of the conversation Summand can see at once — longer is better for multi-turn analysis sessions.
## Privacy
Summand's prompts and responses are processed through Anthropic's API. The full dataset is **not** sent — only summary statistics, column names, and the specific values needed to answer the question being asked. Anthropic is a listed subprocessor; see [Compliance](/enterprise/compliance) for the data-handling agreement.
If your organization needs to disable Summand entirely, contact [support@intelligible.ai](mailto:support@intelligible.ai) — Enterprise customers can scope Summand availability per-org.
## Troubleshooting
Sanity-check against the dataset's Overview tab or run the SQL Summand surfaces directly. If the numbers don't match, the issue is almost always Summand picking the wrong column. Reword the question with explicit column names and try again. If it still disagrees with what queries return, please report it via [support@intelligible.ai](mailto:support@intelligible.ai) — we treat ground-truth disagreements as bugs.
Usually means the requested chart doesn't make sense for the column types — e.g. a histogram of a free-text column. Summand will explain why; switching to a different visualization (counts, top-N) usually works.
Free-tier limits reset every Monday at 00:00 UTC. If your week-of-use spans a Sunday-to-Monday boundary, the count resets mid-session.
# Connect a database
Source: https://docs.summand.com/guides/connect-database
Step-by-step setup for live PostgreSQL, MySQL, or Snowflake analysis. Enterprise plans only.
Database connectors give Summand a live view of a warehouse. This guide walks through PostgreSQL end-to-end; MySQL and Snowflake follow the same shape with different SQL.
For databases not in this list (Databricks, Redshift, BigQuery, Oracle), see the [Fivetran connector](/data-sources/fivetran).
Summand connects from a fixed set of egress IPs, listed in **Settings → Connectivity**. Allowlist them on your database firewall before continuing.
For private databases — VPC-only, no public endpoint — Enterprise customers can use PrivateLink, VPC peering, or an SSH tunnel. Contact [our sales team](https://intelligible.ai/contact) to set this up; it takes about a day.
Run the SQL appropriate for your engine. Postgres example:
```sql theme={null}
CREATE USER summand_reader WITH PASSWORD '';
GRANT CONNECT ON DATABASE your_db TO summand_reader;
GRANT USAGE ON SCHEMA public TO summand_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO summand_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO summand_reader;
```
Snowflake equivalent:
```sql theme={null}
CREATE ROLE summand_reader;
GRANT USAGE ON WAREHOUSE compute_wh TO ROLE summand_reader;
GRANT USAGE ON DATABASE your_db TO ROLE summand_reader;
GRANT USAGE ON SCHEMA your_db.public TO ROLE summand_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA your_db.public
TO ROLE summand_reader;
GRANT SELECT ON FUTURE TABLES IN SCHEMA your_db.public
TO ROLE summand_reader;
CREATE USER summand_user PASSWORD = ''
DEFAULT_ROLE = summand_reader;
GRANT ROLE summand_reader TO USER summand_user;
```
Use a long random password — at least 32 characters. Summand stores it encrypted in AWS Secrets Manager.
Go to **Connectors → Add connector → PostgreSQL** (or MySQL / Snowflake). Provide:
* Host
* Port (5432 for Postgres, 3306 for MySQL, your account URL for Snowflake)
* Database name
* Username and password from the previous step
Click **Test connection**. Summand opens a connection, runs `SELECT 1`, and reports success or a clear error.
Once connected, Summand queries `INFORMATION_SCHEMA` and lists every table the user can read. Toggle on the tables you want as datasets — you can enable more later.
Each enabled table becomes a dataset. The baseline column-stats component runs automatically; no other configuration is required.
From any dataset's detail page:
* **Chat** with Summand for ad-hoc questions.
* **Create a view** to save a SQL transformation, including cross-table joins.
* **Set up an experiment** to schedule the Predictors, Surprise finding, or other components on the dataset (or on a view of it).
Click **Refresh** on any dataset to re-read current data from the source. Scheduled experiments will pick up the new data on their next tick. The previous computed-context version is preserved for comparison.
## Performance tips
* **Limit row count for huge tables.** A 100M-row table will take a long time to refresh. If you only need a representative sample, create a database view that samples or filters, and point Summand at the view.
* **Pre-aggregate via Summand views.** If multiple experiments target the same cohort, define the cohort once as a [view](/guides/create-a-view) and point experiments at the view rather than re-filtering in each component.
* **Refresh during off-peak hours.** A refresh is a single full table read. For warehouses with concurrent workloads, schedule analysis around your peak.
## Security review checklist
If you need to walk security through the integration:
* ✓ Read-only credentials, scoped to the schemas you grant
* ✓ Credentials stored encrypted in AWS Secrets Manager (KMS-backed)
* ✓ TLS required for all database connections; cert validation enforced
* ✓ Egress from a fixed IP range we publish
* ✓ No write paths exist in code — `SELECT`-only is a hard property of the connector, not a configuration
* ✓ Audit log entries for every connector create / update / delete (Enterprise tier)
# Create a view
Source: https://docs.summand.com/guides/create-a-view
Save a SQL transformation over your data — visually, by hand, or with Summand's help.
Views are saved SQL queries you can re-use across chat, experiments, and other views. Three ways to make one.
## Path 1 — Visual builder
The default. Pick datasets and shape the query without writing SQL.
Click **Views** in the sidebar, then **+ New view**.
Add one or more datasets from your account. Cross-connector joins work — the curated Parquet for every connector lives in the same Glue catalog.
Drag join keys between datasets, filter rows with predicates, project the columns you want. The builder writes SQL underneath.
The preview pane runs the SQL against the actual curated data and refreshes as you edit. If a query won't compile, the error surfaces here.
Give it a name (e.g. *Active customers Q1*) and a description. Save. The view is now addressable from chat and from experiments.
## Path 2 — Hand-written SQL
Drop into the Code editor for anything the visual builder can't express.
Click **Code** in the editor's mode toggle. The visual SQL is preserved as-is in the editor.
Standard ANSI SQL plus Athena extensions. Reference datasets by their Glue table name (visible in the schema panel).
```sql theme={null}
SELECT
o.customer_id,
COUNT(*) AS orders,
SUM(o.total) AS revenue
FROM ${orders_glue_table} o
JOIN ${customers_glue_table} c
ON c.id = o.customer_id
WHERE c.tier = 'enterprise'
AND o.created_at >= DATE '2026-01-01'
GROUP BY o.customer_id
```
Same as the visual path. Note that switching back to **Visual** mode discards hand-edits the builder can't represent — the editor confirms before resetting.
## Path 3 — Have Summand draft it
The lowest-friction path when you can describe what you want in English.
Make sure the dataset(s) you want to query are pinned to the conversation.
*"Build me a view that counts orders per customer, grouped by tier, for orders since January 1."*
Summand returns the proposed SQL inline. Click **Save as view**, give it a name, and it lands in your views list.
Views Summand creates inside a chat session start as **chat views** — pinned to the session, not addressable elsewhere. Saving promotes them to a regular catalog view.
## Sharing a view
Views are owned by the user who created them. There's no view-share model today — to give a teammate access to a view's results, materialize it (run the SQL once and save as a separate dataset), or share the underlying datasets and let them rebuild the view themselves. View-level sharing is on the roadmap.
## Using a view as an experiment source
When creating an [experiment](/concepts/experiments), pick **View** instead of **Dataset** as the source and select your view. The experiment's components will run on the view's output rather than the raw dataset. Useful for:
* **Defining a cohort once** — *"active enterprise customers in Q1"* — and pointing several experiments at it.
* **Pre-aggregating** — components run faster on a smaller, pre-aggregated view than on a raw 50M-row table.
* **Ensuring consistency** — every experiment downstream sees exactly the same definition.
## Limits
* **One SQL statement per view.** Multi-statement scripts aren't supported — chain via experiments instead.
* **Read-only.** No `INSERT` / `UPDATE` / `DELETE`.
* **Glue-table references.** Internal renames (display name changes) don't break views; deletions do, with a clear error.
# Export a PDF report
Source: https://docs.summand.com/guides/export-pdf
Generate a shareable PDF of an analysis for stakeholders without Summand access.
PDF export is the way to send analysis findings to people outside Summand — execs, customers, regulators, anyone who needs the artifact but not the live dashboard.
## What's in the PDF
* **Dataset header** — name, source, last analysis timestamp.
* **Executive summary** — auto-generated from the computed-context layer; one paragraph on what the model found.
* **Overview** — row count, column types, missingness, key distributions.
* **Top features** — feature importance with shape function plots for the top 8.
* **Surprises** — top 10 surprising rows with feature contributions.
* **Custom sections** — anything you've pinned to the report from Summand or the analysis tabs.
The PDF is paginated, has a clickable table of contents, and embeds vector charts (not bitmap screenshots) — it prints cleanly.
## How to export
Navigate to the dataset whose analysis you want to export.
The export menu is in the dataset header. PDF generation runs server-side and typically completes in 5-15 seconds.
By default, the export includes Overview, Features, and Insights. You can toggle individual sections on or off, or add **custom sections** built from saved chart configurations.
The PDF downloads to your machine. It's also saved to the dataset's **Reports** tab so you (or grantees) can re-download it later without re-generating.
## Branding
| Tier | Branding |
| - | - |
| Free | Summand watermark on every page; capped at 2 exports / week |
| Pro / Education | No watermark; unlimited exports |
| Enterprise | No watermark; unlimited exports |
Org-level custom branding (logo, cover page, footer colors) on PDFs is a roadmap item for Enterprise. Reach out via [support@intelligible.ai](mailto:support@intelligible.ai) if it's a hard requirement for your contract — we can prioritize.
## Report templates
If you find yourself making the same export shape repeatedly — same sections, same custom charts — save it as a **report template**. From the export dialog, click *Save as template* and name it. Future exports can pick the template from the dropdown.
| Tier | Saved templates per dataset |
| - | - |
| Free | — |
| Pro / Education | 10 |
| Enterprise | Unlimited |
Templates are per-dataset by default. Enterprise customers can mark a template as **org-wide** so it appears on every dataset in the workspace.
## Sharing the PDF
A PDF is a static file — once you download it, Summand has no further control over who sees it. Treat exports the way you'd treat any internal document. For ongoing access where revocation matters, [share the dataset directly](/guides/share-a-dataset) instead of mailing PDFs around.
For datasets that change often, regenerate the PDF on each refresh. Auto-export on refresh is roadmap; for now it's a manual click.
# Set up an experiment
Source: https://docs.summand.com/guides/set-up-an-experiment
Schedule analytical components — predictors, surprise finding, column stats — to run on a dataset or view, on cron.
Experiments are how recurring analysis happens in Summand. Once configured, the experiment fires on its schedule, runs the components you picked, writes versioned outputs, and surfaces results back to chat and the global Surprises page.
Click **Experiments** in the sidebar, then **+ New experiment**.
Choose either a **dataset** or a **view**. Datasets are the simplest; views let you target a pre-aggregated or filtered subset (e.g. *enterprise customers only*) without the components having to filter each run.
The source picker lists the datasets and views you own.
From the component catalog, select one or more components to run:
* **Column stats** — distributions, missingness, cardinality. Cheap; usually first.
* **Predictors** — fits an EBM and writes feature importance. Requires a target column input.
* **Surprise finding** — flags rows the predictor disagrees with. Chains automatically when both are in the same experiment.
* **UMAP embedding** — 2-D projection for cluster visualization.
See [Components](/concepts/components) for the full catalog.
Each component declares typed inputs that the editor renders as form fields. For Predictors, you'll see:
* **Target column** — dropdown of the source's columns. The thing the model should predict.
* **Feature exclusions** — optional, columns to skip.
Inputs are validated client-side before save. Required inputs are marked.
Choose a preset:
* **Daily at 3:00 AM** or **Daily at 6:00 AM**
* **Every 6 hours** or **Every 12 hours**
* **Weekly Monday 3:00 AM** or **Weekly Sunday 3:00 AM**
Or write a custom AWS EventBridge cron / rate expression:
```text theme={null}
cron(*/15 * * * ? *) — every 15 minutes
cron(0 9 ? * MON-FRI *) — every weekday at 9 AM
rate(2 hours) — every two hours
```
EventBridge cron uses **six fields**, not the standard five. The editor renders a human-readable description (*"At minute 0, every 6 hours"*) so you can sanity-check.
Give the experiment a name and an optional description. Save. The first run fires on the next schedule tick — or hit **Run now** to test immediately.
## After it's running
The experiment detail page shows:
* **Recent runs** — status, duration, error message on failure.
* **Run history** — older runs paginated back.
* **Manual trigger** — *Run now* fires outside the schedule; the next scheduled run goes as normal.
* **Pause** — stop scheduled runs without deleting the experiment.
* **Edit** — update components, inputs, or schedule. Changes apply on the next tick.
## Reading the output
Experiment outputs land in three places:
* **Chat with Summand** — *"What did the last predictor run say about churn?"* Summand reads the latest computed-context version and answers.
* **Global Surprises page** — surprise-finding outputs across all your experiments, ranked.
* **Downstream views** — write a SQL view that pulls component outputs and join them with other data.
There isn't a "results" tab on the experiment itself today — the model is "outputs are first-class data, queryable like any other".
## Patterns
### One component per experiment
Simplest case. Predictor on dataset X, daily at 3 AM. One row in your experiments list per analysis.
### Chained components in a single experiment
If you put **Predictors** and **Surprise finding** in the same experiment, Surprise finding chains to the predictor's output automatically — no input wiring needed. This is the canonical setup for "find rows that don't match the model's expectations."
### Different schedules for different cohorts
Define a view per cohort (*enterprise customers*, *trial users*, *newly-onboarded*), then set up one experiment per view. Each runs on its own cadence. All three reuse the same component definitions.
### Running on demand only
For experiments you only want to fire manually, set the schedule to a far-future cron (`cron(0 0 1 1 ? 2099)` works) and use **Run now** when needed. A first-class "manual only" mode is on the roadmap.
## Failures
Failed runs are kept in history with the error message. Common causes:
* **Source unavailable** — the underlying database connection failed or the view's SQL no longer compiles.
* **Input validation** — the target column was renamed or removed in the source.
* **Component error** — usually a data-shape issue (e.g. predictor target is all null on the latest snapshot).
Summand doesn't auto-retry failed runs. Edit the configuration to fix the underlying issue, or pause the experiment if the upstream is broken longer than you want failure noise.
## Limits
* **Number of components per experiment** — no hard cap, but cost and duration scale linearly.
* **Schedule frequency** — minimum is whatever EventBridge allows (1 minute), though most analytical components don't need that level of frequency.
* **Concurrent runs** — at most one run per experiment at a time. If a tick fires while the previous run is still in progress, the new tick is skipped (it's not queued).
# Share a dataset
Source: https://docs.summand.com/guides/share-a-dataset
Grant teammates read or edit access, or publish a dataset publicly.
Sharing in Summand is per-user and per-resource. There are two questions:
1. **Who** has access? — managed via direct grants.
2. **Who else** can find it? — managed via visibility settings.
These are independent. You can grant a single user read access while keeping the dataset private to everyone else, or publish a dataset publicly without granting anyone explicit access.
For background, see [Sharing concepts](/concepts/sharing).
## Grant access to a teammate
From the dataset page, click **Share** in the top-right.
Type the teammate's email. Summand checks if they have an account.
* **Existing user** — the grant takes effect immediately.
* **New email** — Summand sends an invitation. The grant becomes active when they sign up.
* **Viewer** — can read every tab, comment, and ask Summand. Can't change configuration.
* **Editor** — everything Viewer can do, plus change target, add column descriptions, and re-run analysis.
* **Owner** — sole owner per dataset; can be reassigned, not added.
See the full role matrix in [Sharing concepts](/concepts/sharing).
The note appears in the invitation email. Useful for context: *"Q1 churn analysis we discussed Tuesday."*
## Change visibility
Visibility controls who can find the dataset and what they see, separate from who's been granted explicit access.
| Visibility | Who can find it | What they see |
| - | - | - |
| **Private** | Owner and direct grantees only. Default. | Everything, subject to grants. |
| **Showcase** | Anyone with the link, no sign-in. | Aggregated insights only — feature importance, shape functions, summary stats. Raw rows are blocked. |
| **Public** | Anyone on the internet, no sign-in. | Everything, including raw rows and Summand chat. |
Change visibility from the **Settings → Visibility** section of the dataset page. Changes take effect immediately.
Both **showcase** and **public** are reachable without sign-in and indexed by search engines. Use **showcase** when you want to share findings without exposing rows; use **public** only for genuinely public data.
If a dataset's parent connector is `public` or `showcase`, the dataset inherits that read access from the connector — you don't need separate grants. Setting the connector to `private` locks down every dataset under it.
## Sharing limits
| Tier | Direct grants per dataset | Public datasets |
| - | - | - |
| Free | — | — |
| Pro / Education | 5 | ✓ |
| Enterprise | Unlimited | ✓ |
If you've hit the Pro grant limit, either upgrade to Enterprise or move the dataset's visibility to **showcase** if rows can be hidden, or **public** if not.
## Revoking access
From the Share dialog, click the role dropdown next to a user and choose **Remove**. The grant is revoked immediately — in-flight requests fail closed on the next authorization check.
For datasets shared publicly, change visibility to **private** to revoke open access. Direct grants are unaffected.
## What gets shared
A grant gives access to the **dataset**, which includes:
* Every analysis tab (Overview, Features, Insights, Predictors)
* The computed-context history (current and previous versions)
* The conversation history with Summand
* The list of comments
Grants do **not** include:
* The underlying source credentials (database password, S3 keys)
* The connector configuration (you can't change which database the dataset reads from)
* Other datasets under the same connector
If you want to share an entire connector, including future datasets, see [Sharing concepts → Connector grants](/concepts/sharing) (Enterprise only).
## Audit trail
Every share action — grant added, role changed, visibility flipped, grant revoked — is logged with timestamp and actor. Enterprise customers can export the audit log from **Settings → Audit logs**. Free and Pro tiers can see the most recent 30 days inline on the dataset page.
# Upload your first CSV
Source: https://docs.summand.com/guides/upload-first-csv
Drop in a file, get a working dataset, decide what to do with it.
CSV upload is Summand's no-setup entry point. There's no wizard, no schema review, no target column to pick. Drag, drop, name it, done.
From the dashboard, click **Upload**. Drag the CSV onto the drop zone, or click *Browse*.
Defaults to the filename minus extension. Rename now or later — it's just a display name.
The file streams directly to S3 via a presigned URL. As soon as the upload finishes, Summand kicks off the baseline analysis (column stats, types, missingness, distributions). Files under 100 MB land within a minute.
That's the entire upload flow. No target, no schema review.
## What you get out of the box
Once the dataset shows *Ready*, the **Overview** tab on the dataset detail page shows:
* Row and column counts, types, missingness per column.
* Distributions for numeric columns, top values for categoricals.
* Last sync time and freshness pill.
That's all baseline — produced by the **column stats** component, which runs automatically on first ingest.
## What to do next
You have three primary paths:
Pin the dataset to a conversation. Ask anything in plain English.
Save a SQL transformation — visual, code, or Summand-drafted.
Schedule predictors, surprise finding, and other components.
## Re-uploading
To analyze a new version of the same file, click **Replace data** on the dataset page (under the **Schedule** tab) and upload again. Summand creates a new computed-context version pinned to the new file; previous versions remain accessible for comparison and for chat history.
The dataset's context, schema overrides, sharing grants, and any experiments you've set up are preserved across re-uploads — you don't redo configuration.
## Common gotchas
Open **Schema** on the dataset page and override the inferred type. The next analysis run uses your override.
Set up an experiment with the **Predictors** component, supplying the target column as a typed input. See [Set up an experiment](/guides/set-up-an-experiment).
Large uploads are resumable for several hours. Refresh the page; you'll be prompted to resume rather than restart. If the upload still fails, try opening the file in a text editor or spreadsheet to confirm it's well-formed.
Most often this is non-numeric content in the column — currency symbols, units, commas as thousands separators. Either clean the file before upload, or override the column type from the **Schema** tab.
# Welcome to Summand
Source: https://docs.summand.com/introduction
Connect your data, then chat with it, save SQL views over it, or schedule analyses to run on a cron — without writing a notebook.
Summand is what happens when you let an AI agent and a SQL warehouse share the same workspace. Connect a CSV, a database, or anything Fivetran supports, and within seconds you can ask questions in plain English, save SQL views (with a visual builder *and* a code editor), and schedule analytical components to run on a recurring basis.
There's no setup wizard, no target column you have to pick, no model you have to configure. Connect the data and start working.
## What you can do with a dataset
The in-product AI assistant. Ask questions in plain English, get answers grounded in your data — including charts and one-shot SQL. Summand can also create views and set up experiments for you.
Save a SQL transformation over one or more datasets. Build it visually with the join/filter UI, hand-edit the SQL, or have Summand draft it for you. Live Athena preview as you build.
Run analytical components — predictors, surprise finding, column stats, custom — on a dataset or view, on a schedule. Daily, hourly, custom cron. Inputs are typed and validated.
## How Summand differs
* **No setup tax.** Most analytics tools want a schema, a target, a metrics model, and a dashboard before they'll show you anything. Summand goes from upload to chat in seconds, and the rest is pull-driven.
* **Views are real SQL, not a metric DSL.** They run on Athena over the same Parquet your dataset is curated to, so you can join across CSVs, databases, and Fivetran sources without copying data.
* **Experiments make analysis reproducible.** Pick a component, configure its inputs, schedule it. Outputs are versioned and queryable; if results change between runs, you can see exactly what shifted.
* **Per-account pricing on Pro.** \$99/month flat, not per-seat.
## Where to go next
Upload a CSV and see all three actions in under five minutes.
How connectors, datasets, views, experiments, and components fit together.
SSO, SCIM, audit logs, and database connectors for organizations.
## Need help?
Email [support@intelligible.ai](mailto:support@intelligible.ai), or check live system status at [status.summand.com](https://status.summand.com).
# Pricing
Source: https://docs.summand.com/pricing
Free for evaluation, Pro at $99/month per account, Education for verified students, Enterprise for organizations.
Summand uses **per-account** pricing on Pro — not per-seat — so \$99/month buys unlimited datasets and unlimited questions, not a single user license. Enterprise unlocks database connectors, SSO, audit logs, and unlimited sharing.
## Tiers
**\$0 / month** — for evaluating Summand on real data.
* 50 MB CSV uploads
* 3 active datasets
* 20 Summand questions / week
* Watermarked PDF export
**\$99 / month** — for analysts and small teams.
* 1 GB CSV uploads
* Unlimited datasets
* Unlimited Summand questions
* Share with up to 5 users per dataset
* Extended thinking & template editor
**\$0 / month (= Pro)** — for verified `.edu` email holders.
* Full Pro feature set
* Annual re-verification required
* Individual non-commercial use only
**From \$499 / month** — for organizations.
* Database connectors (PostgreSQL, MySQL, Snowflake, Databricks)
* SSO (SAML, OIDC), org-wide MFA
* HIPAA-grade audit logs, SOC 2, ISO 27001
* Unlimited sharing, custom branding, SLAs
## Feature comparison
| Capability | Free | Pro / Education | Enterprise |
| - | - | - | - |
| CSV upload size | 50 MB | 1 GB | 4 GB |
| Active datasets | 3 | Unlimited | Unlimited |
| Summand questions | 20 / week | Unlimited | Unlimited |
| PDF exports | 2 / week (watermarked) | Unlimited | Unlimited |
| Message length | 2,000 chars | 4,000 chars | 4,000 chars |
| Conversation history | 7 days | 90 days | 365 days |
| Context window | 4K tokens | 8K tokens | 16K tokens |
| Sharing | — | 5 users / dataset | Unlimited |
| Saved report templates | — | 10 / dataset | Unlimited |
| Extended thinking | — | ✓ | ✓ |
| Report editor | — | ✓ | ✓ |
| Database connectors (Postgres, MySQL, Snowflake, Azure SQL) | — | — | ✓ |
| Delta Sharing & Fivetran | — | — | ✓ |
| SSO (SAML, OIDC) via WorkOS | — | — | ✓ |
| Audit logging | — | — | ✓ |
| Priority support | Community | Email (48 hr) | 4 hr + dedicated CSM |
| 99.9% SLA | — | — | ✓ |
Rate limits are tier-tuned and may change as we calibrate against real usage. Hitting a limit returns `429`; current values are visible in the response's `X-RateLimit-*` headers.
## Enterprise pricing
Enterprise pricing is contract-based — there's no public price card. Standard packages start at \$499/month and scale with seat count, data volume, and add-ons (HIPAA BAA, dedicated infrastructure, extended audit retention).
**Annual** commitments come at a discount, and **multi-year** commitments at a larger one. Contact [our sales team](https://intelligible.ai/contact) for a quote.
## Free tier guardrails
The Free tier has weekly resets — not monthly — to keep evaluation steady rather than encouraging binge-and-churn. Caps reset every Monday at 00:00 UTC.
## Education tier eligibility
Education is the same feature set as Pro, free for individuals at academic institutions. To request Education status, sign up with your `.edu` email and contact [support@intelligible.ai](mailto:support@intelligible.ai) — we verify and apply the upgrade. Universities looking for institutional or classroom licenses should reach out to sales.
# Quickstart
Source: https://docs.summand.com/quickstart
Connect data, then chat with it, query it, or schedule analyses — in five minutes.
This guide walks through the fastest path to a result: sign in, connect data, and pick whichever of the three primary actions matches what you want to do.
Go to [summand.com](https://summand.com) and create an account. Free tier is the default — no card required.
`.edu` users can request an Education upgrade from [support@intelligible.ai](mailto:support@intelligible.ai) for full Pro features at no cost.
Click **Upload** and drop in a CSV (up to 50 MB on Free, 1 GB on Pro, 4 GB on Enterprise), or, on Enterprise, click **Add connector** for PostgreSQL, MySQL, Snowflake, Azure SQL, Delta Sharing, or any Fivetran-supported source.
Summand registers the data as a **dataset** under a new **connector** and runs an immediate baseline analysis — column stats, types, missingness, distributions. Files under 100 MB land within a minute.
There's no setup wizard. No target column to pick. No schema review. Once the dataset shows *Ready*, you're done with setup.
On the dataset, choose one of three primary actions:
Open Summand and ask in English. *"What's interesting in this data?"* is a fine first question.
Build a SQL transformation — visual or code — that you can re-use across chats and experiments.
Schedule a component (predictors, surprise finding, custom) to run on a cron. Outputs are versioned.
These aren't sequential — pick whichever fits the problem you brought to Summand. The order in the rest of this guide is: chat first (lowest friction), then views (when you need durable SQL), then experiments (when you need recurring analysis).
Open the chat panel from the sidebar. Pin the dataset (or a view) to the conversation, and ask anything:
* *"How many rows are in this?"* — quick fact.
* *"Which columns are most correlated with `revenue`?"* — exploratory.
* *"Build me a view that joins this with the customer table."* — Summand drafts SQL and offers to save it as a view.
Answers come grounded in the dataset's [computed-context layer](/concepts/computed-context), so the numbers match what queries return.
For SQL transformations you'll re-use, go to **Views** in the sidebar. Either:
* **Build it visually** — pick datasets, drag in joins and filters, watch live Athena preview update as you go.
* **Hand-write SQL** — drop into the code editor; preview is live there too.
* **Have Summand draft it** — ask in chat, accept the suggestion.
Saved views work as inputs to experiments and as data sources for chat.
Go to **Experiments** in the sidebar and click **+ New experiment**. Pick:
* **A source** — a dataset or a view.
* **One or more components** — predictors, surprise finding, column stats, computed-context pieces. Each component has typed inputs you fill in (e.g. *which column to predict* for the predictor component).
* **A schedule** — daily 3 AM, every 6 hours, weekly Monday, or a custom cron.
Save and the experiment runs on schedule. Each run produces a versioned output you can read in chat or wire into another view.
## What just happened
Behind the scenes, you created:
* A **connector** — the typed pointer to your data source.
* A **dataset** — one per table, with the curated Parquet copy and column-level stats.
* (Optionally) one or more **views** and **experiments** that build on the dataset.
The dataset's detail page has nine configuration tabs — Overview, Schedule, Schema, Components, Context, Access, Notifications, Run history, Advanced — for tuning behavior. Most users never need to touch them.
## Next steps
PostgreSQL, MySQL, Snowflake, Azure SQL — Enterprise tier.
Visual builder, code editor, or Summand-assisted.
Components, inputs, cron, run history.
Per-user grants and visibility settings.
# Support
Source: https://docs.summand.com/support
How to get help, report bugs, and check system status.
## Get help
The fastest path. Reply within 48 hours on Pro, 4 hours on Enterprise.
Live status of every Summand subsystem. Subscribe for incident notifications.
Report vulnerabilities or request security artifacts (SOC 2 report, BAA, DPA).
Invoicing, refunds, plan changes, tax questions.
## Reporting bugs
A useful bug report has:
1. **What you were doing** — clicked X, then Y, then Z.
2. **What happened** — observed result, exact error message if any.
3. **What you expected** — sometimes obvious, sometimes not.
4. **The dataset / connector / org IDs involved** (if relevant).
5. **The timestamp (UTC)** — helps us match server logs.
6. **Your browser and OS** for UI issues.
If a screenshot helps, attach it. For chart-rendering bugs, the dataset URL is enough; we can reproduce from there.
Email [support@intelligible.ai](mailto:support@intelligible.ai) with whatever you have. We'd rather you over-share than under-share — there's no template you have to follow.
## Feature requests
Two paths:
* **Pro / Education** — email [support@intelligible.ai](mailto:support@intelligible.ai) with the feature you'd like and a sentence on the use case. We track requests and respond when they're scheduled.
* **Enterprise** — bring it up with your account manager. Enterprise customers have direct input into the roadmap.
## Response times
| Tier | First response (production issue) | Resolution target (production issue) |
| - | - | - |
| Free | Best-effort, \~5 business days | None |
| Pro / Education | 48 hours | None |
| Enterprise | 4 hours (24×7) | Per contract SLA |
"Production issue" is anything blocking your work — auth failures, missing data, broken analysis. For non-blocking issues (cosmetic bugs, feature requests, polish), responses follow the same SLA but resolution targets aren't promised.
## Outage protocol
If [status.summand.com](https://status.summand.com) shows a degraded subsystem, you don't need to file a ticket — we're already on it. Subscribe at the top of the status page for email or Slack notifications.
For incidents that affect production but aren't visible on status (a regression we haven't detected), email support immediately. Enterprise customers can also reach the on-call engineer via the `#summand-support` Slack shared channel.
## Security and compliance
* **Vulnerability reports:** [security@intelligible.ai](mailto:security@intelligible.ai). PGP key on request. We respond within 1 business day and credit reporters in our security hall of fame.
* **NDA-gated artifacts:** SOC 2 report, BAA, DPA, pen test report — request from `security@intelligible.ai` from a verified work address.
* **GDPR / CCPA requests:** [privacy@intelligible.ai](mailto:privacy@intelligible.ai). 5-day acknowledgement, 30-day completion.
## Community
Public community is at [summand.com/community](https://summand.com/community). It's a good place for use-case discussions, dataset templates, and informal help — but not a substitute for support for anything time-sensitive.