> 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/6-write-your-own-controller.md).

# 6. Write your own Data Controller

By the end of this step, you’ll understand when to build a custom Data Controller: when Captivate doesn’t include a controller for your source, or when an in-house system needs a dedicated live connection to graphics.

This step is for developers. The other steps taught you how to use Captivate; this one is about extending it.

## When to choose this step

Pick this step when you’ve ruled out the simpler options:

* The source isn’t available in the [Data Controller catalog](/play-and-update-graphics/chapter-index-3.md). Check the catalog first; a Data Controller you need may already exist.
* The data can’t reasonably be shaped into a CSV, Excel, Google Sheets, XML, or JSON source for Tables. Tables covers more cases than you might expect: if your system can export a CSV or JSON feed on a regular interval, Tables is usually the lower-effort path.
* You need the source to appear in the **Data Controller** column dropdown next to the built-in Data Controllers, to offer its own configuration panel, and to push live updates with the same animation behavior as everything else in Captivate.

If a built-in Data Controller or Tables can handle the source, use step 4 or step 5 instead — it saves development time and is easier to support.

## What this looks like

Captivate exposes a **Data Controller API**. A Data Controller you implement against the API is loaded by Captivate on startup and appears alongside the built-in Data Controllers: it shows up in the **Data Controller** column dropdown, provides its own configuration panel, declares the fields it produces, and pushes live updates with the same on-air update behavior as the built-ins. When field names match the graphic’s values, Captivate connects them automatically; users can adjust the connections with **Link Data**.

In practice your code reads data from the source — a REST API, WebSocket feed, vendor SDK, serial device, or internal service — and sends Captivate the fields your graphics need. Captivate hosts the controller, displays it in the Data Controller workflow, connects its fields to graphics, and renders the on-air updates.

## Basic development steps

1. **Design the fields first.** List the fields your Data Controller will provide; these are what users connect to graphic values in **Link Data**. Get this right before you write any code; it’s harder to change after graphics are built against it.
2. **Build a matching graphic** whose value names match the fields your Data Controller provides, so Captivate can connect them automatically ([Create variables in graphics](/design-and-customize-graphics/chapter-index-4/create-variables-in-graphics.md)).
3. **Implement the Data Controller** against the API. The API documentation covers the contract, lifecycle hooks, and update mechanism.
4. **Test it inside Captivate**: add it to a graphic, configure it, check **Link Data**, play the graphic, and verify that updates appear correctly on air.
5. **Package and distribute** per the API documentation’s packaging guidance.

## Go deeper

The Data Controller API (class contract, lifecycle, update mechanism, packaging, signing) is documented separately from this help system. Contact NewBlue support for the current API documentation.

## What you just did

You learned when a custom Data Controller is the right choice and what the development work involves. The build itself happens in your own codebase, against the Data Controller API, with the API reference open alongside.

## Next step

You’re at the end of the path. From here:

* Browse the [Data Controller catalog](/play-and-update-graphics/chapter-index-3.md) to confirm your source isn’t already covered.
* [Re-evaluate Tables](/play-and-update-graphics/chapter-index-1/tables-overview.md). If your system can produce a CSV, Google Sheet, XML, or JSON source, Tables is usually less work.
* Contact NewBlue support for the current Data Controller API documentation.

## Related

* [5. Drive a graphic with a Data Controller](/play-and-update-graphics/chapter-index/5-drive-with-data-controller.md)
* [Tables overview](/play-and-update-graphics/chapter-index-1/tables-overview.md)
* [Create variables in graphics](/design-and-customize-graphics/chapter-index-4/create-variables-in-graphics.md)


---

# 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/6-write-your-own-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.
