> For the complete documentation index, see [llms.txt](https://captivatehelp.newbluelive.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://captivatehelp.newbluelive.com/play-and-update-graphics/chapter-index-2/legacy-json-controller.md).

# Legacy JSON controller

**❗ IMPORTANT**\
This page documents the **legacy** JSON controller (the Qt/C++ `CSVFileReaderHandler` registered as **General > JSON** and **Sports > JSON**). It is retained so existing projects continue to open. For new projects, use [Tables](/play-and-update-graphics/chapter-index-1/tables-overview.md) — the unified Tables controller reads JSON via **Browse** or **Open URL** in **Load New Data** and is the supported path forward. The legacy JSON menu entry may be removed in a future release.

Captivate can display data from incoming JSON feeds, such as Scoreboard OCR and other sources that write real-time data to JSON files. This data can be assigned to design elements such as text and updated in real time.

## Add a legacy JSON input

1. In Captivate’s playout interface, open a project (if a project isn’t already open) and select a graphic in the Project List.

   **💡 TIP**\
   Open the Graphics Library panel and drag a graphic from the library to your channel. To customize existing variables or create new ones, see [Create variables in graphics](/design-and-customize-graphics/chapter-index-4/create-variables-in-graphics.md).
2. Click the **Select a Datasource** cell in the Data Controller column and choose **General** > **JSON** > **New Input** (or **Sports** > **JSON** > **New Input** if a sports-graphic input list is open).
3. A dialog box prompts you to either select a JSON file from your computer or enter a URL that hosts your JSON data.

   <div align="left"><figure><img src="https://352477438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFCWMxradHcVjURnrXSYX%2Fuploads%2Fgit-blob-e0d28e2129479b7ae1b892f1d8429d7edd811dc8%2Fimage_4723.png?alt=media" alt="Legacy JSON file or URL dialog"><figcaption></figcaption></figure></div>

   * Enter the **URL** of the JSON file on your local network or FTP location, or click the **Select file** button and pick a local JSON file.

     **💡 TIP**\
     **FTP syntax:** The URL form is `ftp://username:password@server.com/path/file.json`. You can also use an IP address after `@` instead of a hostname.
4. The JSON data and its variables appear in the **Link Data** sidebar in the **Preview** panel. Click **Link Data** in the **Preview** panel to view the JSON input and variables.
5. Click and drag a JSON variable onto an object in the graphic. Repeat this step for each variable you want to include in the graphic.

   **💡 TIP**\
   To disconnect a variable from an object in your graphic, right-click the variable in the **Preview** panel and choose **Disconnect variable**.

   <div align="left"><figure><img src="https://352477438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFCWMxradHcVjURnrXSYX%2Fuploads%2Fgit-blob-83fd507d12d4ced27d962a71ad96355e49e091bd%2Fimage_2893.png?alt=media" alt="Legacy JSON variables linked in the Preview panel"><figcaption></figcaption></figure></div>

The JSON data is now visible in the graphic. Captivate updates the graphic as the underlying data changes.

## How Captivate reads JSON

The legacy JSON handler auto-flattens the document into a table by heuristic. There is no JSONPath, jq, or dotted-key query language — you cannot ask for a specific node by selector.

* An array of objects is read as rows; each object’s fields become columns.
* The parser defaults to **400 keys** maximum and a **max depth of 3**. Heavily nested or oversized documents may not produce the columns you expect.
* If the generated columns are not what you want, reshape the feed upstream (export a flatter JSON) or convert to CSV/XLSX and load through the modern Tables controller.

## Refresh behavior

How Captivate picks up new data depends on the source:

* **Local files** — Captivate watches the file via the OS file-change events and reloads automatically when the file is rewritten.
* **URL / FTP sources** — Captivate fetches once at load. Click the **Refresh** / **Reload** control in the input’s settings to pull a fresh copy, or use the input’s Auto Refresh interval if exposed for that source.

## Migration to the new Tables controller

If you maintain a project that currently uses **General > JSON**, you can switch to [Tables: Row](/play-and-update-graphics/chapter-index-1/drive-a-graphic-with-tables-row.md) or **Tables: Block** without changing the source file: choose **Productivity > Tables: Row > New Input**, click **Browse** to pick the same JSON file, and re-link the variables to your graphic. The Tables grid then exposes column sorting, header context menus, and Auto Refresh that the legacy handler does not.

## See also

* [Legacy data controllers](/play-and-update-graphics/chapter-index-2.md) — chapter overview
* [Tables](/play-and-update-graphics/chapter-index-1/tables-overview.md) — modern Tables controller
* [Legacy XML controller](/play-and-update-graphics/chapter-index-2/legacy-xml-controller.md) — sibling article for XML feeds


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://captivatehelp.newbluelive.com/play-and-update-graphics/chapter-index-2/legacy-json-controller.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
