SDKs
The official libraries wrap the same HTTP API in a few lines of idiomatic code. They read your key from the environment, retry safely, tell you what every call cost, and give you typed methods for the most-used platforms.
| Language | Package | Install (available at launch) | Needs |
|---|---|---|---|
| Python | onekey | pip install onekey | Python 3.9+, sync and async |
| TypeScript / JavaScript | onekey | npm install onekey | Node 18+, or anything with fetch; no dependencies |
| Go | onekey-go | go get github.com/onekey-hq/onekey-go | Go 1.21+, standard library only |
Quickstart#
Set your key once, then make a call. Each snippet looks up a GitHub profile (1 credit) and prints the data and what the call cost.
export ONEKEY_KEY="YOUR_API_KEY"Python#
from onekey import Onekey
client = Onekey() # reads ONEKEY_KEY
env = client.github.profile(username="torvalds")
print(env.data)
print(env.meta.credits_charged, env.meta.cached)TypeScript#
import { Onekey } from "onekey";
const client = new Onekey(); // reads ONEKEY_KEY
const env = await client.github.profile({ username: "torvalds" });
console.log(env.data);
console.log(env.meta.creditsCharged, env.meta.cached);Go#
c, err := onekey.New() // reads ONEKEY_KEY
if err != nil { log.Fatal(err) }
env, err := c.Github.Profile(ctx, &onekey.GithubProfileParams{Username: "torvalds"})
if err != nil { log.Fatal(err) }
fmt.Println(string(env.Data))
fmt.Println(env.Meta.CreditsCharged, env.Meta.Cached)Configuration#
| Setting | Default | Notes |
|---|---|---|
| API key | ONEKEY_KEY environment variable | Or pass it to the constructor. Sent only in the x-api-key header, never in a URL, and hidden when you print the client. |
| Base URL | ONEKEY_BASE_URL, else https://api.onekey.dev | Override to point at another deployment or a test server. |
| Timeout | 30 seconds per attempt | Can be set per client and per call. |
| Retries | 2 | Set to 0 to turn retries off. |
client = Onekey(api_key="YOUR_API_KEY", base_url="https://api.onekey.dev", timeout=30.0, max_retries=2)const client = new Onekey({ apiKey: "YOUR_API_KEY", baseUrl: "https://api.onekey.dev", timeoutMs: 30000, maxRetries: 2 });c, _ := onekey.New(onekey.WithAPIKey("YOUR_API_KEY"), onekey.WithBaseURL("https://api.onekey.dev"), onekey.WithTimeout(30*time.Second), onekey.WithMaxRetries(2))Typed methods and the generic request#
Every platform and endpoint is reachable through one generic call, which works for all endpoints in the catalog, including ones added after the library was released:
env = client.request("github", "profile", {"username": "torvalds"})const env = await client.request("github", "profile", { username: "torvalds" });env, err := c.Request(ctx, "github", "profile", onekey.Params{"username": "torvalds"})On top of that, the libraries ship typed methods (client.github.profile(...)) for the 20 most-used platforms, 355 endpoints in this first release: GitHub, YouTube, Reddit, Hacker News, X, Instagram, TikTok, LinkedIn, Facebook, Threads, Bluesky, npm, PyPI, Wikipedia, Product Hunt, Web, Telegram, Twitch, Pinterest and Stack Exchange. Typed methods give you editor completion for parameter names, mark required parameters, and (in Go) reject a missing required parameter locally, before any request or charge. Everything else uses request.
The catalog helpers are free and need no key: client.platforms() returns every endpoint with its price and status, client.categories() the categories with platform and endpoint counts, and client.account() your credit balance.
The response#
Every call returns the standard response: success, data, meta and error. In the libraries the block is called meta (the API sends it as metadata). data is plain JSON.
| Field | Meaning |
|---|---|
credits_charged | What this call cost, or 0 for a cache hit. |
cached, stale, age_s | Whether it came from Onekey's cache and how old it is. See Caching. |
fetched_at, request_id | When it was fetched, and the id to quote to support. |
platform, endpoint | Which endpoint answered. |
In TypeScript the fields are camelCase (meta.creditsCharged, meta.requestId); in Go they are Meta.CreditsCharged and Meta.RequestID.
Pagination#
Endpoints that take a cursor (or page) parameter can be walked with a helper. Each page is a normal call and is charged like one, so always set a page limit.
for item in client.iter_items("tiktok", "comments", {"id": "123"}, max_pages=5):
print(item)for await (const item of client.iterItems("tiktok", "comments", { id: "123" }, { maxPages: 5 })) {
console.log(item);
}p := c.NewPager("tiktok", "comments", onekey.Params{"id": "123"}, &onekey.PageOptions{MaxPages: 5})
for p.Next(ctx) {
for _, item := range p.Envelope().Items() { fmt.Println(item) }
}
if err := p.Err(); err != nil { log.Fatal(err) }Retries and errors#
The libraries retry 429, 500, 502, 503, 504, timeouts and network errors, up to 2 times by default, with exponential backoff and jitter. A Retry-After header is honoured. They never retry 400, 401, 402, 403, 404 or 422, because the same request would fail the same way. Retrying is safe: failed calls are refunded, and a repeated successful call is a free cache hit. See Errors and Rate limits.
When retries run out, or the error is not retryable, you get a typed error carrying the code, HTTP status and request id:
| Error | When |
|---|---|
UnauthorizedError | 401: key missing, wrong or revoked. |
InsufficientCreditsError | 402: top up, then retry. |
NotFoundError | 404: the record does not exist (refunded). |
InvalidParamsError | 422: a parameter is missing or malformed (also raised locally for a bad platform or endpoint name). |
RateLimitedError | 429, with the seconds to wait. |
UpstreamError | 502: the source platform failed (refunded). |
ConfigurationError | No API key, raised before any request. |
from onekey import InsufficientCreditsError, RateLimitedError
try:
client.github.profile(username="torvalds")
except InsufficientCreditsError:
... # top up
except RateLimitedError as e:
print(e.retry_after, e.request_id)import { InsufficientCreditsError, RateLimitedError } from "onekey";
try {
await client.github.profile({ username: "torvalds" });
} catch (e) {
if (e instanceof InsufficientCreditsError) { /* top up */ }
else if (e instanceof RateLimitedError) console.log(e.retryAfter, e.requestId);
else throw e;
}var ke *onekey.Error
switch {
case errors.Is(err, onekey.ErrInsufficientCredits): // top up
case errors.Is(err, onekey.ErrRateLimited) && errors.As(err, &ke): time.Sleep(ke.RetryAfter)
}Async Python#
AsyncOnekey has the same surface on httpx:
import asyncio
from onekey import AsyncOnekey
async def main():
async with AsyncOnekey() as client:
env = await client.github.profile(username="torvalds")
print(env.meta.credits_charged)
asyncio.run(main())Until the libraries are published#
Use the HTTP API directly. It is a few lines in any language: see the Quickstart and the request examples on every endpoint page. Working with an AI tool instead? See the MCP server and AI agents.