Every visual on an Output Charts dashboard holds one JSON document. You can paste that document in the editor, or you can replace it from anywhere that can make an HTTP request. This guide does it from a terminal with cURL, which is the quickest way to see how pushing works before you put it in a script.
What you need
- A Solo plan. API push is part of Solo; pasting JSON works on every plan.
- A dashboard with at least one visual. This guide uses a KPI, which shows one number.
- An API key, which you create in the next step.
1. Create an API key
Open Account → API keys and create a key. The secret starts with oc_live_ and is shown once, so copy it now. Solo accounts can have up to five keys, so give each script its own and revoke one without touching the rest.
Keep the secret out of your shell history by putting it in an environment variable:
export OC_KEY="oc_live_..."
A new key can take a few seconds before its first push is accepted.
2. Copy the visual's push URL
Open the dashboard in the editor and select the visual. Under Push from code, choose Copy push URL. It looks like this, with your visual's id in the middle:
export VISUAL_URL="https://api.outputcharts.com/visuals/<visual-id>/data"
3. Send the JSON
A KPI document needs a label, a number, and a format:
curl -X PUT "$VISUAL_URL" \
-H "Authorization: Bearer $OC_KEY" \
-H "Content-Type: application/json" \
-d '{ "label": "Orders today", "value": 214, "format": "number" }'
A successful push answers 200 with the visual's id and the time of the change:
{ "visualId": "<visual-id>", "updatedAt": "2026-10-18T17:02:11.000Z" }
Open copies of the dashboard check for new data every 15 seconds, so the number changes on every screen within a few seconds, with no reload.
Sending a chart instead of a number
Each visual type has its own document shape. A line chart takes a key for the x axis, the series to draw, and one row per point:
{
"xKey": "day",
"curve": "monotone",
"series": [{ "key": "signups", "label": "Signups" }],
"data": [
{ "day": "Mon", "signups": 41 },
{ "day": "Tue", "signups": 57 },
{ "day": "Wed", "signups": 49 }
]
}
For anything longer than a line, keep the document in a file and let cURL read it:
curl -X PUT "$VISUAL_URL" \
-H "Authorization: Bearer $OC_KEY" \
-H "Content-Type: application/json" \
--data @signups.json
To check a document before you push it, paste it into the JSON to chart tool. It flags the same mistakes the API rejects and lists the shape every visual type takes.
Things to know
- A push replaces the whole document. Send every series and every row each time, not only what changed. The last push wins.
PUTandPOSTdo the same thing, so use whichever your tool makes easier.- Documents can be up to 100 KB.
- Each key can push 60 times a minute. That is plenty for a dashboard; if a loop needs more, slow it down.
When a push fails
The API answers with a status code and a short JSON error:
| Status | Code | What it means |
|---|---|---|
| 401 | invalid_api_key | The key is missing, mistyped, revoked, or a few seconds too new. |
| 403 | requires_solo | The account is on Free. Keys pause on Free and work again after an upgrade. |
| 404 | not_found | The visual id is wrong, or the visual was deleted. |
| 413 | payload_too_large | The document is over 100 KB. |
| 422 | invalid_document | The JSON does not fit the visual's type. The details list names each field that is wrong. |
| 429 | rate_limited | More than 60 pushes in a minute from one key. |
A 422 is the one you will see most while you are getting started. It tells you exactly where to look:
{
"error": "Visual document is invalid",
"code": "invalid_document",
"details": [{ "path": "value", "message": "Expected number" }]
}
Next
cURL is fine for trying things out. To push on a schedule, run the same request from a script, a cron job, or a CI step. Create a free account to build the dashboard first; upgrading to Solo turns on API keys.

