Quickstart
Ten minutes, four steps
The fourth step is the one that matters. The first three are the same as any HTTP API.
- 01
Get a key
Create one in the dashboard. The raw key is shown once and stored as a SHA-256 hash, so if you lose it, rotate rather than recover.
- 02
Make a call
Every endpoint is a GET with your key in the x-api-key header. Responses are JSON in a fixed envelope.
- 03
Read the accounting
Headers on every response tell you what the call cost and whether it was served from cache — no separate usage endpoint needed to find out.
- 04
Stop polling
Once you are checking the same targets repeatedly, subscribe instead. Polls we run for you are free; you are charged when the data moves.
1. Get a key
Create a key in the dashboard. Keys are stored hashed — we cannot show you an existing key again, only issue a new one. Give each environment its own key and a daily spend cap so a loop in staging cannot drain production credits.
2. Make a call
export API="${API:-https://api.truescrape.com}"
export KEY="sk_live_..."
curl "$API/v1/youtube/channel?handle=@mkbhd" \
-H "x-api-key: $KEY"3. Read the accounting
Every response carries what it cost, what is left, and whether it came from cache. You never have to make a second call to find out what the first one did.
HTTP/1.1 200 OK
x-request-id: req_01JB8Z3M6QW2K9
x-credits-charged: 1
x-credits-remaining: 998
x-cache: MISS
x-response-time: 412msAdding cache_max_age is the single highest-leverage change you can make to a bill. It says how stale a copy you will accept; anything older is fetched live.
# Say how stale a copy you will accept.
# A hit costs nothing and never touches the platform.
curl "$API/v1/youtube/channel?handle=@mkbhd&cache_max_age=7d" \
-H "x-api-key: $KEY"
# x-cache: HIT
# x-credits-charged: 0The same call from code
const response = await fetch(
`${API}/v1/youtube/transcript?url=8XkPqR2nLvE&cache_max_age=7d`,
{ headers: { 'x-api-key': KEY } },
);
const body = await response.json();
if (!body.success) {
// Failures are never charged. Retry the retryable ones.
throw new Error(`${body.error.code}: ${body.error.message}`);
}
console.log(body.data.text); // the whole transcript
console.log(body.meta.creditsCharged); // 0 on a cache hitimport os, httpx
API = os.environ["API"]
KEY = os.environ["KEY"]
r = httpx.get(
f"{API}/v1/youtube/transcript",
params={"url": "8XkPqR2nLvE", "cache_max_age": "7d"},
headers={"x-api-key": KEY},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"]["text"])4. Stop polling
This is the step people skip, and it is the one that changes the bill. If you are checking the same creator every hour to see whether they posted, subscribe once and let us tell you.
curl -X POST "$API/v1/subscriptions" \
-H "x-api-key: $KEY" \
-H "content-type: application/json" \
-d '{
"endpoint": "youtube.channel",
"params": { "handle": "@mkbhd" },
"webhook_url": "https://you.example/hooks/social"
}'Deliveries are signed, retried with backoff, and moved to a dead-letter queue when your endpoint stays down. Jobs, batches & webhooks covers the delivery semantics in full.