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

# Charts

> Detect and digitize charts from a completed extraction or split. The
response includes normalized source bounding boxes, reconstructed data
series, axis metadata, confidence scores, and optional export files.

Provide exactly one of `extraction_id` or `split_id`. When using an
extraction, `page_range` can limit processing to selected 1-indexed
pages. Split requests inherit their pages from the split and therefore
cannot also provide `page_range`.

Export URLs require authentication and are consumed after one successful
download. Request every required format up front and store the downloaded
bytes rather than the URL.

Set `async: true` to return immediately with a `job_id`. Poll
`GET /job/{job_id}` for the completed `ChartsResponse`.

Requires the `charts_endpoint` feature flag to be enabled for your
organization. Billed at **1 credit per reconstructed chart**.

## Overview

<Info>
  **Pipeline Step 2 (terminal)** — Charts reuses a completed extraction or split.
  It does not accept a document upload directly.
</Info>

Reconstruct line, scatter, bar, pie, donut, and well-log charts as auditable data.
Each result contains the source page and normalized bounding box, reconstructed
series, axis metadata, a confidence score, and warnings. You can also request Excel,
CSV, or LAS exports.

The endpoint can run synchronously or asynchronously and is billed at **1 credit per
reconstructed chart**. It must be enabled for your organization.

## Request

Provide exactly one source:

| Field           | Type    | Required   | Description                                                                             |
| --------------- | ------- | ---------- | --------------------------------------------------------------------------------------- |
| `extraction_id` | UUID    | One source | A completed, saved extraction.                                                          |
| `split_id`      | UUID    | One source | A completed split. Results are grouped by split topic.                                  |
| `page_range`    | string  | No         | Extraction mode only. 1-indexed pages such as `"1-3,5"`. Split mode inherits its pages. |
| `charts_config` | object  | No         | Reconstruction and export options.                                                      |
| `async`         | boolean | No         | Defaults to `false`. With `true`, returns a `job_id` immediately for polling.           |

### `charts_config`

| Field            | Type           | Default     | Description                                                                                              |
| ---------------- | -------------- | ----------- | -------------------------------------------------------------------------------------------------------- |
| `data_points`    | integer, 2–500 | `20`        | Requested samples per continuous series.                                                                 |
| `agentic_zoom`   | boolean        | `false`     | Inspect difficult regions at higher resolution. This can improve recovery at additional latency.         |
| `export_formats` | array          | `["excel"]` | Any of `excel`, `csv`, and `las`. Use `[]` to disable exports. LAS applies only to compatible well logs. |

Options belong inside `charts_config`. Top-level `data_points`, `agentic_zoom`,
`export_formats`, `generate_las`, and `layout_confidence` are rejected.

```bash theme={null}
curl -X POST https://api.runpulse.com/charts \
  -H "x-api-key: $PULSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "extraction_id": "0d904c3c-8eb8-4abd-a455-04c3a83c5b43",
    "page_range": "1-3,5",
    "async": true,
    "charts_config": {
      "data_points": 100,
      "agentic_zoom": true,
      "export_formats": ["excel", "csv"]
    }
  }'
```

For a split, replace `extraction_id` with `split_id` and omit `page_range`.

## Response

With `async: true`, the endpoint returns HTTP `202`:

```json theme={null}
{
  "job_id": "90705060-b7b9-48c3-9593-7c7d62ce280e",
  "status": "pending",
  "message": "Chart extraction started. Poll GET /job/{job_id} for results."
}
```

Poll `GET /job/{job_id}` until the job reaches a terminal status. The completed chart
response is returned in the job response's `result` field. `charts_id` belongs to that
completed result; it is not duplicated in the initial async acknowledgement.

Extraction mode returns a flat `charts` array. Split mode returns `results`, keyed by
topic, with each topic's inherited pages and charts. `count` is the total number of
charts across the response.

```json theme={null}
{
  "charts_id": "90705060-b7b9-48c3-9593-7c7d62ce280e",
  "extraction_id": "0d904c3c-8eb8-4abd-a455-04c3a83c5b43",
  "page_range": "1-3,5",
  "count": 1,
  "charts": [
    {
      "id": "fig-1",
      "page_number": 2,
      "bounding_box": [
        {"x": 0.12, "y": 0.18},
        {"x": 0.88, "y": 0.18},
        {"x": 0.88, "y": 0.76},
        {"x": 0.12, "y": 0.76}
      ],
      "type": "line",
      "title": "Monthly price",
      "x_axis": {"type": "categorical", "title": "Month"},
      "y_axis": {"type": "linear", "title": "Price"},
      "series": [
        {
          "name": "Series 1",
          "color": "#1769aa",
          "line_style": "solid",
          "data": [["Jan", 102.4], ["Feb", 105.1]]
        }
      ],
      "confidence": 0.94,
      "warnings": []
    }
  ],
  "exports": [
    {
      "format": "excel",
      "filename": "charts.xlsx",
      "url": "https://api.runpulse.com/results/90705060-b7b9-48c3-9593-7c7d62ce280e/charts/charts.xlsx"
    }
  ],
  "excel_url": "https://api.runpulse.com/results/90705060-b7b9-48c3-9593-7c7d62ce280e/charts/charts.xlsx",
  "credits_used": 1
}
```

`excel_url` is a compatibility alias. New integrations should iterate over `exports`.
If an export cannot be produced, `export_warnings` explains why without failing the
chart reconstruction.

## Export Downloads

Every export URL:

* requires the same API key as the chart request;
* belongs to the organization that created the chart result;
* is deleted after one successful stream;
* must not be prefetched by an agent, UI, or link preview.

```bash theme={null}
curl -H "x-api-key: $PULSE_API_KEY" \
  "https://api.runpulse.com/results/90705060-b7b9-48c3-9593-7c7d62ce280e/charts/charts.xlsx" \
  --output charts.xlsx
```

Store the downloaded file. Do not store the URL as a durable artifact reference.

## Retrieve Results

Authenticated applications can hydrate saved views without rerunning reconstruction:

| Endpoint                                                      | Purpose                                                                                              |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `GET /api/v1/charts/{charts_id}`                              | Read one owned result by ID.                                                                         |
| `GET /api/v1/charts/extraction/{extraction_id}/latest`        | Read the newest result associated with an extraction, including split and pipeline runs.             |
| `GET /api/v1/charts/extraction/{extraction_id}/public/latest` | Read the newest result only while that extraction's public sharing and retention windows are active. |

The public route intentionally returns `404` for missing, private, expired, and deleted
extractions so it does not disclose which condition failed.

## Accuracy

Chart output is reconstructed from pixels and OCR, so treat values as estimates. Review
`confidence` and `warnings`, and validate consequential data against the source using the
returned `page_number` and `bounding_box`. `agentic_zoom` can help with small labels or
dense curves, but does not guarantee exact source values.

## Related

<CardGroup cols={2}>
  <Card title="Extract" icon="file-lines" href="/api-reference/endpoint/extract">
    Create the saved extraction consumed by Charts.
  </Card>

  <Card title="Chaining Steps" icon="diagram-project" href="/concepts/chaining">
    Reuse extraction and split IDs across downstream steps.
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /charts
openapi: 3.1.0
info:
  title: Pulse API Structure
  version: 0.1.0
  description: >-
    Canonical contract for the Pulse extraction APIs. This specification is the
    single source of truth for shared request/response models that client and
    server packages consume.
servers:
  - url: https://api.runpulse.com
    description: Default Pulse API base URL
security:
  - ApiKey: []
paths:
  /charts:
    post:
      tags:
        - Charts
      summary: Reconstruct charts from a saved extraction or split
      description: >-
        Detect and digitize charts from a completed extraction or split. The

        response includes normalized source bounding boxes, reconstructed data

        series, axis metadata, confidence scores, and optional export files.


        Provide exactly one of `extraction_id` or `split_id`. When using an

        extraction, `page_range` can limit processing to selected 1-indexed

        pages. Split requests inherit their pages from the split and therefore

        cannot also provide `page_range`.


        Export URLs require authentication and are consumed after one successful

        download. Request every required format up front and store the
        downloaded

        bytes rather than the URL.


        Set `async: true` to return immediately with a `job_id`. Poll

        `GET /job/{job_id}` for the completed `ChartsResponse`.


        Requires the `charts_endpoint` feature flag to be enabled for your

        organization. Billed at **1 credit per reconstructed chart**.
      operationId: extractCharts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChartsInput'
      responses:
        '200':
          description: Completed chart reconstruction.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartsResponse'
        '202':
          description: Chart job accepted (when async=true).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncSubmissionResponse'
        '400':
          description: Invalid target, page range, or chart configuration
        '401':
          description: Authentication failed or missing API key
        '403':
          description: Charts endpoint not enabled for your organization
        '404':
          description: Extraction, split, or source artifact not found
        '429':
          description: Rate limit exceeded
        '503':
          description: Chart inference is temporarily unavailable
components:
  schemas:
    ChartsInput:
      type: object
      additionalProperties: false
      description: Input for `POST /charts`. Provide exactly one target ID.
      oneOf:
        - required:
            - extraction_id
          not:
            required:
              - split_id
        - required:
            - split_id
          not:
            required:
              - extraction_id
      properties:
        extraction_id:
          type: string
          format: uuid
          description: Completed extraction to process.
        split_id:
          type: string
          format: uuid
          description: Completed split whose topic page groups should be processed.
        page_range:
          type: string
          pattern: ^[0-9, -]+$
          description: >-
            Optional 1-indexed pages for extraction mode, for example `"1-3,5"`.
            Do not provide this with `split_id`; split pages are inherited.
        charts_config:
          allOf:
            - $ref: '#/components/schemas/ChartsConfig'
          description: Chart reconstruction options. Defaults are used when omitted.
        async:
          type: boolean
          default: false
          description: >-
            When true, returns immediately with a job ID. Poll `GET
            /job/{job_id}` for the completed chart result.
    ChartsResponse:
      type: object
      required:
        - charts_id
        - count
        - exports
        - excel_url
      properties:
        charts_id:
          type: string
          format: uuid
        extraction_id:
          type: string
          format: uuid
          nullable: true
        split_id:
          type: string
          format: uuid
        page_range:
          type: string
        count:
          type: integer
          minimum: 0
          description: Total reconstructed charts across the response.
        charts:
          type: array
          description: Present in extraction mode.
          items:
            $ref: '#/components/schemas/Chart'
        results:
          type: object
          description: Split-mode results keyed by topic name.
          additionalProperties:
            $ref: '#/components/schemas/ChartTopicResult'
        exports:
          type: array
          items:
            $ref: '#/components/schemas/ChartExport'
        excel_url:
          type: string
          format: uri
          nullable: true
          deprecated: true
          description: Compatibility alias for the Excel item in `exports`.
        export_warnings:
          type: array
          items:
            type: string
        credits_used:
          type: number
          format: float
    AsyncSubmissionResponse:
      type: object
      description: >-
        Acknowledgement returned when a request is submitted for asynchronous
        processing. Poll `GET /job/{job_id}` to check status and retrieve
        results.
      required:
        - job_id
        - status
      properties:
        job_id:
          type: string
          description: Identifier assigned to the asynchronous job.
        status:
          type: string
          description: Initial status reported by the server.
          enum:
            - pending
            - processing
            - completed
            - failed
            - canceled
        message:
          type: string
          description: Human-readable description of the accepted job.
        queuedAt:
          type: string
          format: date-time
          deprecated: true
          description: >-
            **Deprecated** — Timestamp indicating when the job was accepted.
            Retained for backward compatibility. Use `GET /job/{jobId}` for
            timing details.
        credits_used:
          type: number
          format: float
          nullable: true
          description: >-
            Number of credits consumed by this request. Only present when the
            organization has the credit billing system enabled.
    ChartsConfig:
      type: object
      additionalProperties: false
      description: Configuration for chart reconstruction and export generation.
      properties:
        data_points:
          type: integer
          minimum: 2
          maximum: 500
          default: 20
          description: Number of reconstructed points requested per continuous series.
        agentic_zoom:
          type: boolean
          default: false
          description: >-
            Enable targeted high-resolution inspection for difficult chart
            regions. This can improve recovery but adds latency.
        export_formats:
          type: array
          default:
            - excel
          uniqueItems: true
          description: >-
            Export files to generate. An empty array disables file generation.
            LAS files are emitted only for compatible well-log charts.
          items:
            type: string
            enum:
              - excel
              - csv
              - las
    Chart:
      type: object
      required:
        - id
        - page_number
        - bounding_box
        - type
        - title
        - x_axis
        - y_axis
        - series
        - confidence
        - warnings
      properties:
        id:
          type: string
          description: Figure identifier from the source extraction.
        page_number:
          type: integer
          minimum: 1
        bounding_box:
          type: array
          minItems: 4
          maxItems: 4
          description: Four normalized source points ordered around the chart rectangle.
          items:
            $ref: '#/components/schemas/ChartPoint'
        type:
          type: string
          enum:
            - line
            - scatter
            - bar
            - pie
            - donut
            - well_log
            - other_chart
        title:
          type: string
          nullable: true
        x_axis:
          $ref: '#/components/schemas/ChartAxis'
        y_axis:
          $ref: '#/components/schemas/ChartAxis'
        series:
          type: array
          items:
            $ref: '#/components/schemas/ChartSeries'
        confidence:
          type: number
          format: float
          minimum: 0
          maximum: 1
        warnings:
          type: array
          items:
            type: string
    ChartTopicResult:
      type: object
      required:
        - pages
        - charts
      properties:
        pages:
          type: array
          items:
            type: integer
            minimum: 1
        charts:
          type: array
          items:
            $ref: '#/components/schemas/Chart'
    ChartExport:
      type: object
      required:
        - format
        - filename
        - url
      properties:
        format:
          type: string
          enum:
            - excel
            - csv
            - las
        filename:
          type: string
        url:
          type: string
          format: uri
          description: Authenticated one-time download URL.
        chart_id:
          type: string
          description: Present for exports that contain one specific chart.
    ChartPoint:
      type: object
      required:
        - x
        - 'y'
      properties:
        x:
          type: number
          format: float
          minimum: 0
          maximum: 1
        'y':
          type: number
          format: float
          minimum: 0
          maximum: 1
    ChartAxis:
      type: object
      required:
        - type
        - title
      properties:
        type:
          type: string
          enum:
            - linear
            - log
            - categorical
            - normalized
        title:
          type: string
          nullable: true
    ChartSeries:
      type: object
      required:
        - name
        - color
        - data
      properties:
        name:
          type: string
        color:
          type: string
          pattern: ^#[0-9a-fA-F]{6}$
        data:
          type: array
          items:
            $ref: '#/components/schemas/ChartDataPoint'
        line_style:
          type: string
          enum:
            - solid
            - dashed
            - dotted
            - dash_dot
            - unknown
          description: Present when a line style is available for the series.
    ChartDataPoint:
      type: array
      description: Two-item `[x, y]` reconstructed data tuple.
      minItems: 2
      maxItems: 2
      prefixItems:
        - $ref: '#/components/schemas/ChartDataValue'
        - oneOf:
            - type: number
            - type: 'null'
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-api-key
      x-fern-header:
        name: apiKey
        env: PULSE_API_KEY

````