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

# Chart updates

> Replace chart data in an existing presentation without regenerating the deck.

Chart updates replace the data inside a chart that was already generated (or uploaded), without regenerating the deck. The chart's type, colours, legend, axis formatting, and position on the slide are preserved — only the categories, series values, and optional data rows change.

<Columns cols={2}>
  <Frame caption="Before update">
    <img src="https://mintcdn.com/duomi/0eYM0n6_9GystnoS/images/chart-updates/before.png?fit=max&auto=format&n=0eYM0n6_9GystnoS&q=85&s=12172196a6e1d513f00db1406a37bf3f" alt="NPS stacked bar chart with original survey data." width="2880" height="1620" data-path="images/chart-updates/before.png" />
  </Frame>

  <Frame caption="After update">
    <img src="https://mintcdn.com/duomi/0eYM0n6_9GystnoS/images/chart-updates/after.png?fit=max&auto=format&n=0eYM0n6_9GystnoS&q=85&s=2b1f3dbdb29273c64150a1fc0cdb2069" alt="Same NPS chart with refreshed survey data — promoter percentages increased, detractor percentages decreased." width="2880" height="1620" data-path="images/chart-updates/after.png" />
  </Frame>
</Columns>

## When to use chart updates vs. regeneration

Use chart updates when you want to refresh chart data in a deck that already exists — either one the API generated, or one a user edited manually in PowerPoint. Layout, formatting, and any manual edits to other slides are preserved.

Use full regeneration when the deck structure itself needs to change (different slides, different tables, different layouts).

## Endpoint

```
PUT /api/v1/presentations/{presentation_id}/update-charts
```

The same endpoint handles two input modes:

* **JSON body** — reference a presentation already in storage by its ID
* **Multipart form** — upload a `.pptx` file and update charts in it in one request

### JSON body (presentation already in storage)

```http theme={"dark"}
PUT /api/v1/presentations/gen_abc123/update-charts
X-API-Key: your-api-key
Content-Type: application/json

{
  "updates": [
    {
      "slide_index": 6,
      "chart_index": 0,
      "chart_data": {
        "categories": ["Acme Corp", "TechFlow Inc", "DataSync Ltd", "CloudFirst", "Innovate Labs", "SecureNet", "GrowthMetrics", "Nexus Digital"],
        "series": [
          { "name": "Promoters (9-10)", "values": [50, 42, 18, 35, 48, 36, 15, 46] },
          { "name": "Passives (7-8)", "values": [30, 33, 30, 35, 32, 38, 28, 30] },
          { "name": "Detractors (0-6)", "values": [20, 25, 52, 30, 20, 26, 57, 24] }
        ],
        "data_rows": [
          ["n=", "156", "142", "89", "178", "201", "134", "67", "188"],
          ["NPS", "+30", "+17", "-34", "+5", "+28", "+10", "-42", "+22"]
        ],
        "data_table_header_column": true
      }
    }
  ]
}
```

The `presentation_id` path parameter accepts:

* `gen_xxx` — from slide generation, deck generation, or chart updates
* `pres_xxx` — older direct-return generation output, if present

### Multipart form (upload a .pptx and update it)

Use this when a user has edited a deck manually in PowerPoint and you want to refresh chart data in the edited file.

```http theme={"dark"}
PUT /api/v1/presentations/{presentation_id}/update-charts
X-API-Key: your-api-key
Content-Type: multipart/form-data

file: (binary .pptx)
updates: [{"slide_index": 6, "chart_index": 0, "chart_data": {...}}]
```

The `updates` field is a JSON string in the form body. When a file is uploaded, the path parameter is ignored — the response returns a new `cupd_xxx` ID for the updated file.

### Response

```json theme={"dark"}
{
  "presentation_id": "gen_abc123",
  "status": "completed",
  "slides_updated": 1,
  "file_size": 7450000,
  "download_url": "https://storage.example.com/download...",
  "download_url_expires_in": 3600,
  "created_at": "2024-01-15T10:45:00Z"
}
```

## Update fields

Each entry in the `updates` array targets one chart:

| Field         | Type    | Required         | Description                                |
| ------------- | ------- | ---------------- | ------------------------------------------ |
| `slide_index` | integer | yes              | Zero-based slide index in the presentation |
| `chart_index` | integer | no (default `0`) | Zero-based chart index on the slide        |
| `chart_data`  | object  | yes              | New chart data (see below)                 |

### `chart_data` fields

| Field                      | Type         | Required             | Description                                                                            |
| -------------------------- | ------------ | -------------------- | -------------------------------------------------------------------------------------- |
| `categories`               | string\[]    | yes                  | Category labels for the x-axis                                                         |
| `series`                   | object\[]    | yes                  | One object per series: `{ "name": "...", "values": [...] }`                            |
| `data_rows`                | string\[]\[] | no                   | Rows rendered in the data table beneath the chart                                      |
| `data_table_header_column` | bool         | no (default `true`)  | Whether the first value in each `data_rows` entry is a row header                      |
| `data_table_format`        | object       | no                   | Font overrides for the data table: `font_name`, `font_size`, `bold`, `italic`, `color` |
| `chart_type`               | string       | no                   | Override the chart type (e.g. `"stacked_bar"`, `"clustered_column"`)                   |
| `title`                    | string       | no                   | Override the chart title text                                                          |
| `title_format`             | object       | no                   | Font overrides for the chart title                                                     |
| `legend`                   | object       | no                   | Legend position and formatting                                                         |
| `value_axis`               | object       | no                   | Value axis formatting (min, max, labels)                                               |
| `category_axis`            | object       | no                   | Category axis formatting                                                               |
| `show_bar_labels`          | bool         | no (default `false`) | Show value labels on bars                                                              |
| `show_data_table`          | bool         | no (default `false`) | Show the built-in PowerPoint data table                                                |
| `caption`                  | string       | no                   | Caption text below the chart                                                           |

Only `categories` and `series` are required. Omitted fields are left unchanged from the existing chart.

## Slide index after pagination

`slide_index` refers to the output presentation, not the original input array. If a table slide paginated into multiple pages during generation, subsequent slide indexes shift.

The generation response includes `total_pages_generated` and `slide_results` — use those to determine the correct output position for each chart.

## Errors

| Error                    | Status | Meaning                                            |
| ------------------------ | ------ | -------------------------------------------------- |
| Slide index out of range | `400`  | `slide_index` exceeds the number of slides         |
| No chart found           | `400`  | No chart exists at that `chart_index` on the slide |
| Presentation not found   | `404`  | The `presentation_id` does not exist in storage    |

```json theme={"dark"}
{
  "detail": "slide_index 7 out of range. Presentation has 7 slides (valid: 0-6)."
}
```
