> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zudo.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Reporting

> Build any chart you need across accounts, requests, meetings, tasks, issues, and emails.

Custom Reporting is a self-service chart builder. Pick an object type, configure axes and aggregation, choose a visualization, and save the result. Charts can be personal or shared with your team, and any chart can be added to a [dashboard](/reporting/dashboards).

## Object types

Every chart is built from one of six object types. Switch between them using the pill selector at the top of the page.

| Object type  | What's included                                             |
| ------------ | ----------------------------------------------------------- |
| **Accounts** | Customer accounts with MRR, health score, and custom traits |
| **Requests** | Feature requests and product feedback                       |
| **Meetings** | Scheduled meetings with duration and attendee data          |
| **Tasks**    | To-dos with status, priority, and assignee                  |
| **Issues**   | Synced issue-tracker items (e.g. from Linear)               |
| **Emails**   | Email threads with message counts                           |

Switching object types clears the current chart builder so you start fresh.

## Building a chart

Each chart is configured in a panel in the **Chart Builder** section at the bottom of the page.

### 1. Select an object type

Use the pill selector at the top of the page to choose which object type to work with.

### 2. Configure the X axis

The X axis is the dimension you want to group records by — for example, account name, request status, or a date field. Any trait except URL and email fields can be used as an X axis.

When you select a date trait, additional date controls appear (see [Date handling](#date-handling)).

### 3. Configure the Y axis

The Y axis is the numeric value to measure per group — for example, MRR, duration, or message count. This field is optional: if you leave it empty, the chart defaults to a count of records in each group.

Only numeric traits appear in the Y axis selector.

### 4. Choose an aggregation

When a Y axis is set, select how to combine values within each group:

| Aggregation | What it computes               |
| ----------- | ------------------------------ |
| **Count**   | Number of records in the group |
| **Sum**     | Total of all Y values          |
| **Average** | Mean of all Y values           |
| **Min**     | Lowest Y value                 |
| **Max**     | Highest Y value                |
| **Median**  | Middle value (50th percentile) |

### 5. Select a chart type

Pick the visual format using the chart type pills. You can switch chart types at any time without losing your other settings.

## Chart types

| Chart type         | Best for                                                            |
| ------------------ | ------------------------------------------------------------------- |
| **Bar**            | Comparing categories with vertical bars                             |
| **Horizontal bar** | Long category labels or rank comparisons                            |
| **Line**           | Trends over time, especially with a date X axis                     |
| **Pie**            | Part-of-whole distribution (works best with 12 or fewer categories) |
| **Scatter**        | Correlation between two numeric traits (requires numeric X and Y)   |
| **Table**          | Exact values and raw data review                                    |
| **Number / KPI**   | A single headline metric displayed as a large number                |

## Number / KPI charts

Select **Number** as the chart type to display a single aggregate value — useful for KPIs like total MRR, average health score, or open request count.

* Choose a **Y axis** and **aggregation** to compute the value (e.g. Sum of MRR).
* If you leave the Y axis empty, the chart shows a simple count of records.
* Use the **format** dropdown to control how the number displays:

| Format                   | Example    | When to use                             |
| ------------------------ | ---------- | --------------------------------------- |
| **Auto**                 | 4.5K       | General use; abbreviates large numbers  |
| **Integer**              | 1,234      | Whole numbers with thousands separator  |
| **1 decimal**            | 1,234.5    | One decimal place                       |
| **2 decimals**           | 1,234.56   | Two decimal places                      |
| **USD (no cents)**       | \$1,234    | Dollar amounts rounded to whole numbers |
| **USD (with cents)**     | \$1,234.56 | Dollar amounts with cents precision     |
| **Percent**              | 12%        | Percentages with no decimals            |
| **Percent (1 decimal)**  | 12.3%      | Percentages with one decimal            |
| **Percent (2 decimals)** | 12.34%     | Percentages with two decimals           |

## Date handling

When your X axis is a date field, the chart groups records into time buckets. Two additional controls appear:

**Interval** — controls the bucket size:

| Interval      | Bucket format                  | Example    |
| ------------- | ------------------------------ | ---------- |
| **Auto**      | Chosen based on the date range | —          |
| **Daily**     | Day                            | 2025-01-15 |
| **Weekly**    | Week starting Monday           | 2025-01-13 |
| **Monthly**   | Month                          | 2025-01    |
| **Quarterly** | Quarter                        | 2025-Q1    |
| **Yearly**    | Year                           | 2025       |

Auto interval picks the best bucket size based on how wide your date range is:

| Date range span    | Auto picks |
| ------------------ | ---------- |
| More than 2 years  | Yearly     |
| More than 6 months | Quarterly  |
| More than 2 months | Monthly    |
| More than 2 weeks  | Weekly     |
| 2 weeks or less    | Daily      |

**Date range** — optional **From** and **To** inputs that clip the dataset to a specific window before aggregation. Click **Clear range** to remove the filter and show all data.

## Filters

Add filters to narrow the data before aggregation — for example, show only open requests, or only accounts with MRR above a threshold.

To add a filter:

1. Click the **filter icon** in the panel header.
2. Select a trait from the dropdown.
3. Choose an operator.
4. Enter a value if the operator requires one.

Multiple filters combine with **AND** logic — every condition must match for a record to be included.

**String, text, and select fields:**

| Operator         | Behavior           |
| ---------------- | ------------------ |
| equals           | Exact match        |
| does not equal   | Not equal          |
| contains         | Substring match    |
| does not contain | No substring match |
| is empty         | Null or blank      |
| is not empty     | Has a value        |

**Number fields:**

| Operator     | Behavior              |
| ------------ | --------------------- |
| =            | Equal to              |
| !=           | Not equal to          |
| >            | Greater than          |
| >=           | Greater than or equal |
| \<           | Less than             |
| \<=          | Less than or equal    |
| is empty     | Null                  |
| is not empty | Has a value           |

**Date fields:**

| Operator     | Behavior              |
| ------------ | --------------------- |
| before       | Before the given date |
| after        | After the given date  |
| on           | Exact date match      |
| is empty     | Null                  |
| is not empty | Has a date value      |

**Boolean fields:**

| Operator     | Behavior       |
| ------------ | -------------- |
| is true      | Value is true  |
| is false     | Value is false |
| is empty     | Null           |
| is not empty | Has a value    |

## Saving charts

Once your chart looks right, save it so it appears in your saved charts grid:

1. Click **Save** (the bookmark icon) in the panel.
2. Enter a title for the chart.
3. Choose a scope:
   * **Personal** — only visible to you.
   * **Team** — visible to everyone in your organization.
4. The chart moves from the builder to the saved charts grid.

Saved charts are independent from dashboard snapshots. Adding a chart to a dashboard copies its configuration at that point in time — see [Dashboards](/reporting/dashboards) for details.

## Editing saved charts

1. Find the chart in the saved charts grid and click the **pencil icon**.
2. The chart opens in the builder with an amber "Editing" banner.
3. Make your changes — update axes, filters, chart type, format, or anything else.
4. Click **Update** to save. You can also update the title at this step.
5. Click **Cancel edit** to discard changes.

## How-to examples

<AccordionGroup>
  <Accordion title="Track requests over time">
    1. Select **Requests** as the object type.
    2. Set **X axis** to **Created At**.
    3. Leave **Y axis** empty — the chart will count requests per period.
    4. Set **Interval** to **Monthly**.
    5. Switch chart type to **Line**.

    You now have a month-by-month view of new request volume. Optionally set a date range to focus on a specific period.
  </Accordion>

  <Accordion title="Show total MRR as a KPI number">
    1. Select **Accounts** as the object type.
    2. Set chart type to **Number**.
    3. Set **Y axis** to **MRR**.
    4. Set **Aggregation** to **Sum**.
    5. From the format dropdown, choose **\$1,234 — USD integer**.

    The chart displays your total portfolio MRR as a large formatted number. Save it as "Total MRR" to add it to a dashboard.
  </Accordion>

  <Accordion title="Filter a chart to a subset of data">
    1. Build any chart — for example, request count by status.
    2. Click the **filter icon** in the panel header.
    3. Click **+ Add filter**.
    4. Select trait **Internal Request**, operator **is false**.
    5. Optionally add a second filter — for example, **Owner** equals a specific CSM's name.

    All filters combine with AND logic. The chart now shows only the records that match every condition you've set.
  </Accordion>

  <Accordion title="Compare average meeting duration by account">
    1. Select **Meetings** as the object type.
    2. Set **X axis** to **Account**.
    3. Set **Y axis** to **Duration (min)**.
    4. Set **Aggregation** to **Average**.
    5. Switch chart type to **Horizontal bar** for readability when there are many accounts.

    You now see average meeting length per account — useful for spotting which customers require the most time.
  </Accordion>

  <Accordion title="Analyze task completion by status">
    1. Select **Tasks** as the object type.
    2. Set **X axis** to **Status**.
    3. Leave **Y axis** empty to count tasks per status.
    4. Switch chart type to **Pie**.
    5. Add a filter: **Auto-created** → **is false** to exclude automated tasks.

    You get a visual breakdown of manually created tasks by their current status.
  </Accordion>
</AccordionGroup>
