Formatting Output
How to format alice skill results in Slack. Configure table, summary, list, and text output types with column formatting and templates.
The Format Step
Every skill has a Format step in the skill builder where you configure how results are rendered in Slack. The format settings determine the visual structure, which fields to include, how values are displayed, and how many rows to show.

Alice supports four primary output types, each suited to different kinds of data. Choosing the right one makes your Slack messages scannable and actionable.
Output Types
Table
Best for multi-row results with consistent columns. Think user lists, subscription tables, invoice histories, or any query that returns rows of similar data.

Configuration options:
| Setting | Description | Default |
|---|---|---|
| Columns | Which fields to display, in order. Each column has a key, label, format, and visibility toggle. | Auto-detected from query results |
| Max rows | Maximum number of rows to display in the Slack message. Range: 1 to 50. | 10 |
| Auto-detect | When enabled, alice infers columns from the query result automatically. Turn off to manually control the column list. | On |
Each column is configured with:
- Key -- The field name from the query result (e.g.,
email,amount,created_at) - Label -- The display header shown in Slack (e.g., "Email", "Amount", "Signed Up")
- Format -- How the value is rendered. See Column Formats below.
- Visible -- Toggle whether the column appears in the output. Hidden columns are still available for actions that reference them.

When to use Table:
- Query returns multiple rows with the same fields
- Data is best compared side-by-side (subscription list, user roster, invoice history)
- You need to scan and compare values across rows
Max row limits: Slack Block Kit limits messages to approximately 50 structured blocks. If your query returns more rows than the max, alice truncates and shows a footer noting "Showing 10 of 142 results." Users can export full results with the Export as CSV action.
Summary
Best for aggregate metrics and KPI snapshots. Use when your query returns a single row of computed values: MRR, churn rate, active users, or any "how much?" / "how many?" answer.

Configuration options:
| Setting | Description | Default |
|---|---|---|
| Fields | Which fields to display, each with a key, label, and format. | Auto-detected |
| Show change | Display a change indicator next to each value (e.g., +3.2%, -$500). Requires the query to return a comparison column. | Off |
Each field is configured with:
- Key -- The field name from the query result (e.g.,
mrr,churn_rate) - Label -- Human-readable display name (e.g., "Monthly Recurring Revenue", "Churn Rate")
- Format -- How the value is rendered (currency, percentage, number, etc.)
When Show change is enabled, alice looks for a companion field with a _change or _delta suffix. For a field named mrr, it checks for mrr_change or mrr_delta and renders it as a colored indicator:
MRR: $45,200 (+3.2%)
Churn Rate: 1.8% (-0.2%)
Active Users: 312 (+15)When to use Summary:
- Query returns a single row of aggregated values (COUNT, SUM, AVG)
- You want a dashboard-like snapshot (daily standup metrics, revenue overview)
- Maximum of 10 fields per summary (Slack Block Kit constraint)
List
Best for actionable items where each row represents a distinct entity that needs context and per-row actions. Think churn risks, failed payments, support tickets, or VIP users that each need individual attention.

Configuration options:
| Setting | Description | Default |
|---|---|---|
| Title key | The field used as the item heading (e.g., email, name). | First text field |
| Subtitle key | Secondary context line (e.g., plan, status). | Second text field |
| Detail keys | Additional fields shown below the subtitle as key-value pairs. | Remaining fields |
| Max items | Maximum number of items to display. Range: 1 to 50. | 10 |
Each list item renders as:
jane@acme.com
Pro plan -- Last login 18 days ago
MRR: $99 | Status: past_due | Payment: failed
[Tag in Stripe] [Send Slack DM] [Open in Stripe]When to use List:
- Each row is a distinct entity that may need individual action
- Results have a natural "title" (email, name) and supporting context
- You want per-row action buttons (tag, DM, open in Stripe)
- You are building combined queries that surface actionable insights
Text
Freeform text output using a template with {{field}} interpolation. Best for status messages, narrative summaries, or custom formatting that does not fit table, list, or summary.

Configuration options:
| Setting | Description |
|---|---|
| Template | A text template with {{field_name}} placeholders that are replaced with values from the first result row. Supports full Slack mrkdwn formatting. |
Example template:
*Revenue Status*
MRR: {{mrr}} ({{mrr_change}} from last month)
Active subscriptions: {{active_count}}
Trials ending this week: {{expiring_trials}}
_Last updated: {{timestamp}}_The template pulls values from the first row of the query result. If your query returns multiple rows, only the first is used. For multi-row data, use Table or List instead.
Slack mrkdwn is fully supported in templates:
*bold*for emphasis_italic_for secondary text`code`for values and IDs>for block quotes<url|text>for links
When to use Text:
- The output is a sentence or paragraph, not structured data
- You want full control over the message layout
- Status checks, narrative summaries, or templated notifications
Column Formats
Column formats control how individual values are rendered in Table, Summary, and List output types. Set the format on each column or field to match the data type.
| Format | Description | Example Output |
|---|---|---|
| Text | Plain text, displayed as-is. Default for unrecognized fields. | jane@acme.com |
| Currency | Formatted as US dollars. Stripe amounts in cents are automatically divided by 100. | $45,200.00 |
| Percentage | Number with one decimal place and % suffix. Expects the value as a number (2.3), not a fraction (0.023). | 2.3% |
| Number | Locale-aware formatting with thousands separators. | 1,204 |
| Relative Date | Human-readable time distance. Best for recency: last login, last payment, created date. | 2 days ago |
| Date | Formatted absolute date. Best for fixed dates: subscription start, trial end. | Jan 15, 2025 |
| Rendered in monospace code formatting for visual distinction and easy copying. | `jane@acme.com` | |
| Truncated Text | Long text cut to 50 characters with ellipsis. Use for descriptions, error messages, or notes. | This is a long description that gets cu... |
How alice Chooses Formats
When auto-detect is enabled, alice infers formats from the data:
- Fields ending in
_at,_date,created,updatedget Relative Date - Fields named
emailget Email - Fields named
mrr,arr,amount,revenue,price, or ending in_amountget Currency - Fields named
rate,percentage, or ending in_rate,_pctget Percentage - Numeric fields with no other match get Number
- Everything else gets Text
You can override any auto-detected format in the column configuration.
Stripe Currency Handling
Stripe stores all monetary values in the smallest currency unit (cents for USD). When you apply the Currency format, alice automatically divides by 100 for display. A raw value of 4520000 renders as $45,200.00.
This conversion applies only to data coming from Stripe sources. If your Supabase query already returns dollar values, the Currency format displays them as-is. See Connect Stripe for more on how Stripe data is handled.
Auto-Detect vs. Manual Configuration
By default, the auto-detect toggle is enabled. When you test your query in the builder, alice examines the result columns and automatically:
- Identifies all fields in the response
- Assigns a default format to each field
- Generates a human-readable label from the field name (
created_atbecomes "Created At") - Sets all fields as visible
Turn off auto-detect when you want full control: choose exactly which fields to show, in what order, with what labels and formats. This is recommended for skills your team will use daily -- the extra minute of configuration pays off in clarity.

Previewing Output
After configuring your format settings, use the Test button in the query step to run the skill and see a preview of the formatted output. The preview shows exactly how the message will appear in Slack, including:
- Column headers and alignment for Tables
- Labeled values for Summaries
- Title/subtitle/details for Lists
- Interpolated template for Text
If the preview looks wrong, return to the Format step and adjust. Common issues:
- Currency showing raw cents: Make sure the format is set to Currency, not Number
- Dates showing timestamps: Switch from Text to Date or Relative Date
- Too many columns: Toggle visibility off for fields that add noise
- Truncated table: Reduce max rows or remove low-value columns
Best Practices
Choose output type early. The output type affects how useful your skill is. A list of churn-risk users needs per-row context and actions (List), while a revenue snapshot needs labeled metrics (Summary). Picking the right type is more important than tweaking column formats.
Label everything. Default labels from field names are functional but ugly. monthly_recurring_revenue labeled as "MRR" is immediately recognizable. Spend 30 seconds renaming columns.
Use Currency format for all money. Never show raw Stripe cent values. The Currency format handles the conversion automatically and adds proper formatting with dollar signs and commas.
Keep tables narrow. Three to five columns is ideal. More than seven columns will be hard to read in Slack, especially on mobile. Hide supplementary fields and let users drill into details via actions.
Set reasonable max rows. The default of 10 works well for daily reviews. For scheduled reports to a channel, consider 5 to keep the message scannable. If users need full data, pair your skill with an Export as CSV action.
Use Summary for scheduled reports. When a skill runs automatically via cron and posts to a channel, a Summary with 4 to 6 key metrics is more useful than a 50-row table that nobody reads.
Related
- Creating a Skill -- the full skill builder walkthrough including the Format step
- Parameters -- pass dynamic values at runtime
- Scheduled Reports -- format tips for automated channel posts
- Actions -- action buttons that appear alongside formatted output
- Slash Commands -- how formatted results display in Slack
- Skill Templates -- pre-configured skills with format settings included
- Combined Queries -- formatting multi-source results
Was this page helpful?