curl --request POST \
--url https://tako.com/api/v1/contents \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"url": "https://tako.com/card/abc123",
"mode": "url",
"content_format": "csv",
"max_rows": 100,
"offset": 100,
"max_chars": 50000,
"quote_only": false,
"premium": false,
"max_cost_usd": 0.5,
"highlights": {
"query": "funded backlog fiscal 2027 guidance",
"max_characters": 4000
},
"zdr": true
}
'import requests
url = "https://tako.com/api/v1/contents"
payload = {
"url": "https://tako.com/card/abc123",
"mode": "url",
"content_format": "csv",
"max_rows": 100,
"offset": 100,
"max_chars": 50000,
"quote_only": False,
"premium": False,
"max_cost_usd": 0.5,
"highlights": {
"query": "funded backlog fiscal 2027 guidance",
"max_characters": 4000
},
"zdr": True
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://tako.com/card/abc123',
mode: 'url',
content_format: 'csv',
max_rows: 100,
offset: 100,
max_chars: 50000,
quote_only: false,
premium: false,
max_cost_usd: 0.5,
highlights: {query: 'funded backlog fiscal 2027 guidance', max_characters: 4000},
zdr: true
})
};
fetch('https://tako.com/api/v1/contents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tako.com/api/v1/contents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://tako.com/card/abc123',
'mode' => 'url',
'content_format' => 'csv',
'max_rows' => 100,
'offset' => 100,
'max_chars' => 50000,
'quote_only' => false,
'premium' => false,
'max_cost_usd' => 0.5,
'highlights' => [
'query' => 'funded backlog fiscal 2027 guidance',
'max_characters' => 4000
],
'zdr' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tako.com/api/v1/contents"
payload := strings.NewReader("{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tako.com/api/v1/contents")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tako.com/api/v1/contents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<string>",
"contents": [
{
"source_url": "<string>",
"content_format": "csv",
"cost": 0,
"data": "<string>",
"records": [
{}
],
"dataset": {
"columns": [
{
"name": "<string>",
"type": "string",
"unit": "<string>"
}
],
"rows": [
[
"<string>"
]
],
"total_rows": 123,
"truncated": true,
"ref": "<string>",
"sources": [
{
"name": "<string>",
"index": "data"
}
],
"provenance": "query",
"redacted_cells": {}
},
"card_data": {},
"card_data_schema": {},
"url": "<string>",
"expires_at": "<string>",
"total_rows": 123,
"total_matching": 123,
"truncated": false,
"export_pricing": {
"baseline_usd": 123,
"row_cpm_usd": 123,
"max_rows_ceiling": 123,
"premium_row_cpm_usd": {},
"free_rows": 0,
"variable_cost_max_usd": 123
},
"manifest": [
{
"name": "<string>",
"metric": "<string>",
"entity": "<string>",
"unit": "<string>",
"dtype": "string",
"premium_class": "person_contact"
}
],
"premium": false,
"premium_rows": {},
"redacted_cells": {},
"description": "<string>",
"offset": 123,
"delivery": "quote"
}
],
"usage": {
"total_cost_usd": 123,
"compute": {
"cost_usd": 123
},
"data": {
"cost_usd": 123,
"datasets": 123,
"data_points": 123
},
"variable_cost": {
"cost_usd": 123
}
}
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "RATE_LIMIT_EXCEEDED"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}Contents
Download the data behind a search result
curl --request POST \
--url https://tako.com/api/v1/contents \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"url": "https://tako.com/card/abc123",
"mode": "url",
"content_format": "csv",
"max_rows": 100,
"offset": 100,
"max_chars": 50000,
"quote_only": false,
"premium": false,
"max_cost_usd": 0.5,
"highlights": {
"query": "funded backlog fiscal 2027 guidance",
"max_characters": 4000
},
"zdr": true
}
'import requests
url = "https://tako.com/api/v1/contents"
payload = {
"url": "https://tako.com/card/abc123",
"mode": "url",
"content_format": "csv",
"max_rows": 100,
"offset": 100,
"max_chars": 50000,
"quote_only": False,
"premium": False,
"max_cost_usd": 0.5,
"highlights": {
"query": "funded backlog fiscal 2027 guidance",
"max_characters": 4000
},
"zdr": True
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://tako.com/card/abc123',
mode: 'url',
content_format: 'csv',
max_rows: 100,
offset: 100,
max_chars: 50000,
quote_only: false,
premium: false,
max_cost_usd: 0.5,
highlights: {query: 'funded backlog fiscal 2027 guidance', max_characters: 4000},
zdr: true
})
};
fetch('https://tako.com/api/v1/contents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tako.com/api/v1/contents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://tako.com/card/abc123',
'mode' => 'url',
'content_format' => 'csv',
'max_rows' => 100,
'offset' => 100,
'max_chars' => 50000,
'quote_only' => false,
'premium' => false,
'max_cost_usd' => 0.5,
'highlights' => [
'query' => 'funded backlog fiscal 2027 guidance',
'max_characters' => 4000
],
'zdr' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tako.com/api/v1/contents"
payload := strings.NewReader("{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tako.com/api/v1/contents")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tako.com/api/v1/contents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://tako.com/card/abc123\",\n \"mode\": \"url\",\n \"content_format\": \"csv\",\n \"max_rows\": 100,\n \"offset\": 100,\n \"max_chars\": 50000,\n \"quote_only\": false,\n \"premium\": false,\n \"max_cost_usd\": 0.5,\n \"highlights\": {\n \"query\": \"funded backlog fiscal 2027 guidance\",\n \"max_characters\": 4000\n },\n \"zdr\": true\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<string>",
"contents": [
{
"source_url": "<string>",
"content_format": "csv",
"cost": 0,
"data": "<string>",
"records": [
{}
],
"dataset": {
"columns": [
{
"name": "<string>",
"type": "string",
"unit": "<string>"
}
],
"rows": [
[
"<string>"
]
],
"total_rows": 123,
"truncated": true,
"ref": "<string>",
"sources": [
{
"name": "<string>",
"index": "data"
}
],
"provenance": "query",
"redacted_cells": {}
},
"card_data": {},
"card_data_schema": {},
"url": "<string>",
"expires_at": "<string>",
"total_rows": 123,
"total_matching": 123,
"truncated": false,
"export_pricing": {
"baseline_usd": 123,
"row_cpm_usd": 123,
"max_rows_ceiling": 123,
"premium_row_cpm_usd": {},
"free_rows": 0,
"variable_cost_max_usd": 123
},
"manifest": [
{
"name": "<string>",
"metric": "<string>",
"entity": "<string>",
"unit": "<string>",
"dtype": "string",
"premium_class": "person_contact"
}
],
"premium": false,
"premium_rows": {},
"redacted_cells": {},
"description": "<string>",
"offset": 123,
"delivery": "quote"
}
],
"usage": {
"total_cost_usd": 123,
"compute": {
"cost_usd": 123
},
"data": {
"cost_usd": 123,
"datasets": 123,
"data_points": 123
},
"variable_cost": {
"cost_usd": 123
}
}
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}{
"error_message": "<string>",
"error_type": "RATE_LIMIT_EXCEEDED"
}{
"error_message": "<string>",
"error_type": "BAD_REQUEST"
}Notes
- To authenticate, you’ll need a Tako API key. It’s best practice to store it as an environment variable to avoid hardcoding sensitive credentials in your code.
- Contents downloads the data behind a result returned by Search or Answer. Pass the result’s URL and Tako returns a short-lived download URL — a CSV of a Tako card’s data, or the extracted text of any other web page.
- You don’t pass a
format; Tako detects the right content from the URL and the response reports what it produced.
content descriptor in the Search or Answer response. Use that result’s URL here — a card’s webpage_url or a web result’s url.Authorizations
Body
Request body for POST /api/v1/contents.
The caller passes the result URL it wants downloadable content for, and
the endpoint detects the right content from the URL itself. A Tako card
URL resolves to the card's underlying data. Any other URL resolves to
the page's extracted full text. mode controls delivery: url returns a
presigned download link, and inline returns the content in the
response. content_format selects the card serialization
(csv, json_records, json_compact, or card_json); web URLs ignore it
(always text).
The result URL to fetch downloadable content for (a TakoCard.webpage_url or a WebResult.url). A Tako card URL yields a CSV of the card's data; any other URL yields the page's extracted text.
"https://tako.com/card/abc123"
Delivery mode. 'url' returns a presigned download link. 'inline' returns the content in the response body: card data up to 2,000 rows unless max_rows asks for more, up to the card's export_pricing.max_rows_ceiling, at most 100,000 (with total_rows and truncated reported), or web text.
url, inline Serialization for Tako card data: 'csv', 'json_records', 'json_compact', or 'card_json' (a rich card-type-specific JSON object; not all card types support it). Ignored for web URLs (always text).
csv, json_records, json_compact, card_json Optional cap on the rows a Tako card export returns and is priced against. When omitted, it depends on mode: 'url' returns the whole card, up to the card's export_pricing.max_rows_ceiling (at most 100,000 rows), and 'inline' returns up to 2,000 rows. Tako clamps larger values to that ceiling. When a card holds more rows than the cap, csv, json_records, and json_compact keep the rows with the latest dates, counting back from the card's latest date even when that date is in the future, as on a forecast. A card without a date column keeps its first rows instead. Sports cards cut differently: a league schedule keeps the tab the card shows, then the tabs nearest to it, and a game, standings, or team stats card keeps an even share of each table. The kept rows stay in the card's own order. card_json cuts each card type its own way: a price or indicator series keeps its newest readings, a forecast or ranking keeps its first records, and those sports cards keep rows from the same tabs and tables as their csv. Every row returned bills at the per-1,000-row rate, on top of the flat per-export baseline. Tako never bills more rows than it returns, so a card holding fewer rows than this cap bills only what it holds. Every card format returns the rows up to this cap and bills them, including card_json. Web URLs ignore this field. A card export can hold up to 100,000 rows. Don't read a large export directly into a model's context: at about 15 tokens per row, 10,000 rows cost about 150,000 tokens. Write the export to a file, on disk or in memory, and have the agent parse it with code. Give the model only the rows or results it needs.
x >= 1100
Number of rows to skip before the export starts, counted in the card's own row order. Use it with max_rows to export one slice of a long list, such as rows 100 to 149 with offset=100 and max_rows=50. It works only on cards whose export keeps their first rows. A card with a date column, a sports card, or content_format=card_json answers 422 to any offset above 0, because those exports don't keep rows in a fixed order from the top: a dated card keeps its newest rows, a sports card keeps rows by tab or table, and card_json cuts each card type its own way. offset plus max_rows can't reach past the card's export_pricing.max_rows_ceiling. An offset at or past the card's last row returns an empty payload with total_rows set, and an API-key caller isn't charged for it. To page through a card, stop when a call returns fewer rows than max_rows: truncated stays true on a card that lists a capped slice of a larger set. The row order isn't guaranteed to stay the same between calls, so check the rows you receive, for example by name. Web URLs ignore this field.
0 <= x <= 100000100
Character cap on extracted web page text. Ignored for Tako card URLs (they use max_rows). Omit it and Tako returns the full page text, up to the maximum this field allows. To truncate, pass a smaller value.
1 <= x <= 100000050000
When true, return only the price of the export (cost + export_pricing) without fetching content or charging. The response item's payload and url fields are null, and the request is free. One exception: a card_json quote returns 'card_data_schema', the shape the export would deliver. The item's delivery field reads 'quote'. max_rows shapes the quote. An omitted max_rows defaults the way a real export does: the whole card for mode 'url', and 2,000 rows for 'inline'. The quote reads mode only for that default. A quote ignores offset when pricing, so it stays an upper bound, and it can't tell whether the card has a date column: a quote with offset above 0 can succeed on a card whose export then answers 422. Every format prices a quote from max_rows, so a quote is instant and makes no call to a data provider. A quote is an upper bound on the charge: an export of a card with fewer rows than the cap bills less. For a card with data from a source priced per unit, the quote also covers the most that data can charge, which export_pricing reports as variable_cost_max_usd. A card_json export is truncated to max_rows like every other format, so the charge can never exceed the quote for the same cap. A card_json quote reports no total_rows, because it does not build the payload. The same export-safe gate applies, so an unexportable card still returns 403, and a card type with no card_json shape still returns 422.
When true, reveal premium cells and bill them. A card's premium columns (see manifest[].premium_class) are withheld by default: a withheld cell reads [premium: withheld] in CSV and is null in JSON formats. This is the only way to receive their values. Some cards link each row to a card for that single record. To reveal one record's premium cells, request the URL in that row's tako_url column with premium=true. To reveal them for every record the card's export returns, up to max_rows, request the card itself. The export then charges export_pricing.premium_row_cpm_usd[class] per 1,000 premium records, on top of the standard row rate. A premium record is a distinct company or person that the delivered rows hold a value for in a column of that class; premium_rows on the item reports the counts. The flag has no effect on a card without premium columns and on web URLs, and is rejected with content_format=card_json. Over the Machine Payments Protocol (MPP), premium=true is refused with a 403 before any charge, unless quote_only is also true.
The most this call can cost, in USD: the export's base price, its row charge, premium records, and per-unit data charges. Before Tako builds the export or reads vendor data, it prices the call the way quote_only does. That price is an upper bound, so Tako can refuse a call whose actual charge would have fit. If the price is above this cap, Tako returns a 422 with error_type COST_CAP_EXCEEDED and the price in quoted_cost_usd, and charges nothing. To get under the cap, lower max_rows or raise max_cost_usd. The cap covers what Tako charges for the response. It doesn't cover a later variable-cost charge for high monthly volume from a source. Omit it for no cap. A quote_only request and an MPP request ignore it.
0 <= x <= 10000000.5
Return only the passages of a web page that match highlights.query, instead of its full text. The passages arrive in the same text payload, joined with ' … ', and max_chars doesn't apply. Tako card URLs reject it, and so do accounts whose web provider can't return highlights. It bills at the same flat rate as full text.
Show child attributes
Show child attributes
Request zero data retention. Set it to true and Tako keeps no copy of the URL in its logs, and fetches a web page only through its zero-data-retention provider. Available only to accounts that Tako has enabled; any other account gets a 403. To turn it on, contact support@tako.com. Omit it for standard retention.
Response
Downloadable content for a result: a presigned URL plus format and cost metadata. For a quote_only request the item instead carries only the price (cost + export_pricing) with all payload and url fields null.
Response for POST /api/v1/contents.
contents is a list so that the contract stays stable if a single result
ever yields multiple artifacts. Today it always carries exactly one
item.
Unique identifier for this request.
Downloadable artifacts for the requested URL.
Show child attributes
Show child attributes
Usage for one metered request. total_cost_usd is always present (the
total quoted charge). compute, data, and variable_cost are the
additive breakdown; each appears only where it applies. total_cost_usd always equals the sum
of the components that appear.
Show child attributes
Show child attributes