This is the quick, copy-pasteable reference for building cards with Tako Thin-Viz. For the full example gallery (every component with a worked example), see the Overview; for the auto-generated schema, see the API reference.
What Thin-Viz does
POST https://tako.com/api/v1/thin_viz/create/ turns your own data into an interactive, embeddable Tako card. One call, one card: you post an array of components, and the response gives you embed_url, image_url, and webpage_url.
- Base URL:
https://tako.com/api/
- Auth: send your API key in the
X-API-Key request header (not a bearer token). Create a key in the Tako console.
Install
pip install tako-sdk # Python
npm install tako-sdk # TypeScript / JavaScript
Minimal working example
A single line chart. Set TAKO_API_KEY and run.
curl -X POST https://tako.com/api/v1/thin_viz/create/ \
-H "X-API-Key: $TAKO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Monthly Revenue",
"source": "Internal Analytics",
"components": [
{
"component_type": "generic_timeseries",
"config": {
"datasets": [
{
"label": "Revenue",
"data": [
{"x": "2024-01", "y": 50000},
{"x": "2024-02", "y": 62000},
{"x": "2024-03", "y": 71000}
],
"units": "$"
}
],
"chart_type": "line",
"title": "Monthly Revenue"
}
}
]
}'
import os
from tako import Configuration, CreateCardRequest, ComponentConfig
from tako.lib import Tako
config = Configuration()
config.api_key["apiKey"] = os.environ["TAKO_API_KEY"]
client = Tako(config)
card = client.create_card(CreateCardRequest(
title="Monthly Revenue",
source="Internal Analytics",
components=[
ComponentConfig(
component_type="generic_timeseries",
config={
"datasets": [
{
"label": "Revenue",
"data": [
{"x": "2024-01", "y": 50000},
{"x": "2024-02", "y": 62000},
{"x": "2024-03", "y": 71000}
],
"units": "$"
}
],
"chart_type": "line",
"title": "Monthly Revenue"
},
),
],
))
print(card.embed_url)
import { Tako } from "tako-sdk";
const tako = new Tako({ apiKey: process.env.TAKO_API_KEY! });
const card = await tako.createCard({
title: "Monthly Revenue",
source: "Internal Analytics",
components: [
{
component_type: "generic_timeseries",
config: {
datasets: [
{
label: "Revenue",
data: [
{ x: "2024-01", y: 50000 },
{ x: "2024-02", y: 62000 },
{ x: "2024-03", y: 71000 },
],
units: "$",
},
],
chart_type: "line",
title: "Monthly Revenue",
},
},
],
});
console.log(card.embed_url);
The response is a card with card_id, title, description, embed_url, image_url, webpage_url, and card_type.
Request fields (CreateCardRequest)
| Field | Type | Required | Description |
|---|
components | array | Yes | Ordered list of components; they render top-to-bottom on the card. |
title | string | No | Card title (falls back to a header component’s title, else “Card”). |
description | string | No | Card description. |
source | string | No | Source attribution shown in the footer. |
height | integer (100–2000) | No | Override the aspect-ratio height. |
postmessage_embed | boolean | No | Enable postMessage data injection mode (default false). |
normalize_currencies | string | No | Target ISO 4217 code to normalize currency values to. |
image_ttl_minutes | integer (1–1440) | No | ZDR cards only — keep a downloadable preview image for this many minutes, then 410 Gone. |
Each entry in components is a ComponentConfig: component_type (from the enum below) + a free-form config object (plus optional component_variant).
Component types
These are the valid component_type values (ComponentTypeEnum):
header · generic_timeseries · categorical_bar · data_table_chart · financial_boxes · table · timeline · pie · histogram · scatter · bubble · choropleth · heatmap · boxplot · treemap · waterfall · sankey · marimekko · person_card · top_level_metric
See the Overview for a worked config example of each.
For stock-style cards, use generic_timeseries with show_kicker_boxes: true (each dataset with a kicker renders a box above the chart). stock_boxes appears in older examples but is not a ComponentTypeEnum value — prefer generic_timeseries + show_kicker_boxes.
Data shapes — know which one a component wants
Most components take datasets, but a few take a different shape. Getting this wrong is the most common error:
| Shape | Components | Example |
|---|
datasets: [{ label, data: [{x, y}], units }] | generic_timeseries, categorical_bar, data_table_chart, pie, histogram, treemap | {"x": "2024-01", "y": 50000} |
datasets with {x, y, r} | scatter, bubble (r = radius on bubble) | {"x": 4.2, "y": 12.5, "r": 15} |
Flat data: [{x, y, v}] | heatmap, marimekko | {"x": "Mon", "y": "AM", "v": 12} |
categories: [{ category, values: [] }] | boxplot | raw values per category |
items: [] | waterfall, financial_boxes | {"category": "Revenue", "value": 100, "is_anchor": true} |
nodes + links | sankey | links reference node ids; must form a DAG |
columns + rows | table | typed columns (string/number/currency/…) |
Embedding the card
Drop the returned embed_url into an iframe (add ?dark_mode=true/false to theme it). For full embedding guidance — dynamic resizing, theme matching, glanceable mode — see Embedding Knowledge Cards.
<iframe src="https://tako.com/embed/CARD_ID" width="600" height="400" frameborder="0"></iframe>
Preview images (ZDR cards)
ZDR cards don’t persist visualization data, so they have no standing preview image. Set image_ttl_minutes (1–1440) at creation to get a temporary image_url. Customize it with query params: dark_mode, width, height, hideFooter. After the TTL expires the image endpoint returns 410 Gone. (image_ttl_minutes is ignored for standard cards, which already have persistent images.)
Tips & errors
- Gzip large payloads. For request bodies over ~1 MB, gzip the body (
Content-Encoding: gzip) — Thin-Viz accepts it and it compresses well (up to ~10×).
- Auth:
X-API-Key header, not a bearer token.
Errors return a bare { "error": "..." } body:
| Status | Meaning | Fix |
|---|
400 | Invalid request (bad component config, unknown component_type, wrong data shape). | Check the component_type against the enum and the data shape table above. |
404 | Referenced resource not found. | Verify any IDs in the request. |
500 | Server error. | Retry; if it persists, contact support. |