SDKs: TypeScript and Python

Two SDKs with one method per endpoint: 207 typed methods, an idempotency key on every call, retries as the service allows, and paging with limits on items and spend.

Updated 2026-10-13 · Works with API v1Open in ChatGPTOpen in Claude

Install

npm install @dataxapi/sdk
pip install dataxapi

Node 20 or later; Python 3.9 or later. Neither has a dependency. Both are generated from the catalog, so each of the 207 endpoints is a typed method with its price in its comment.

The client

import { DataXAPI } from "@dataxapi/sdk";

const dx = new DataXAPI(); // reads DATAXAPI_API_KEY
const labelled = new DataXAPI({ maxRetries: 3, source: "my-app" });
from dataxapi import DataXAPI

dx = DataXAPI()  # reads DATAXAPI_API_KEY
labelled = DataXAPI(max_retries=3, source="my-app")
TypeScriptPythonWhat it sets
apiKeyapi_keyThe key. Default: the environment variable DATAXAPI_API_KEY.
baseUrlbase_urlThe service's address. Default: DATAXAPI_BASE_URL, else https://api.dataxapi.com.
timeoutMstimeoutHow long one attempt may take: milliseconds in TypeScript, seconds in Python. Default: 65 seconds.
maxRetriesmax_retriesHow many times a request that may be retried is sent again. Default: 2.
sourcesourceA label recorded on every call: where it comes from.
endUserend_userA label recorded on every call: which of your own users it is for.

Calls

Call an endpoint by its method, or by its ID with call. Either is one call, one page, charged on its own; the answer is the envelope as the service sends it. Every call goes out under an idempotency key the SDK makes, and a retry inside the SDK reuses it.

const result = await dx.tiktok.videos.search({ query: "space station" });
console.log(result.data.items, result.meta.billing.amount);

// By ID, refused before it runs if it could cost more than $0.002.
const capped = await dx.call("tiktok.videos.search", { query: "space station" }, { maxPrice: "0.002" });
result = dx.tiktok.videos.search(query="space station")
print(result["data"]["items"], result["meta"]["billing"]["amount"])

# By ID, refused before it runs if it could cost more than $0.002.
capped = dx.call("tiktok.videos.search", query="space station", options={"max_price": "0.002"})

To walk pages, dx.pages(…) gives a page at a time and dx.items(…) an item at a time, within limits on pages, items and money: see Pagination.

The same thing on several platforms

A role is what several platforms do alike, under one name: social.posts.search is tiktok.videos.search on tiktok and youtube.videos.search on youtube. Calling by role makes the platform an argument. Across several platforms, each platform is a call of its own, charged on its own, and one that fails does not stop the others.

const one = await dx.callByRole("social.posts.search", "tiktok", { query: "space station" });

const outcomes = await dx.acrossPlatforms("social.posts.search", ["tiktok", "youtube"], { query: "space station" });
for (const each of outcomes) console.log(each.platform, each.result?.meta.billing.amount ?? each.error?.message);
one = dx.call_by_role("social.posts.search", "tiktok", query="space station")

outcomes = dx.across_platforms("social.posts.search", ["tiktok", "youtube"], query="space station")
for each in outcomes:
    print(each["platform"], each["error"] or each["result"]["meta"]["billing"]["amount"])

Errors

DataXAPIError

The service answered with an error. It carries status, code, charged, retry, retryAfterSeconds, requestId, param, problems and reason (in Python retry_after_seconds, request_id). Each code has a class of its own, such as NotFoundError and RateLimitedError.

APIConnectionError

No answer of the service's arrived: the connection failed or timed out. Whether the call ran is not known.

error.call

The call as it was sent: the endpoint, the parameters and the options, the idempotency key included.

error.unsettled

True when a sending may have run without its outcome being learnt.

When unsettled is true, send the same endpoint and parameters again with error.call.options. Under its key it is the same call: the saved result if it settled, never a second charge.

import { APIConnectionError, DataXAPI, DataXAPIError } from "@dataxapi/sdk";

const dx = new DataXAPI();
const params = { query: "space station" };
let page;
try {
  page = await dx.call("tiktok.videos.search", params);
} catch (error) {
  if ((error instanceof DataXAPIError || error instanceof APIConnectionError) && error.unsettled && error.call) {
    // The same call under the key it went out with.
    page = await dx.call("tiktok.videos.search", params, error.call.options);
  } else throw error;
}
from dataxapi import APIConnectionError, DataXAPI, DataXAPIError

dx = DataXAPI()
try:
    page = dx.call("tiktok.videos.search", query="space station")
except (DataXAPIError, APIConnectionError) as error:
    if not (error.unsettled and error.call):
        raise
    again = error.call
    page = dx.call(again["capability"], again["params"], options=again["options"])

Account, usage, calls, catalog

These are free. The catalog needs no key.

TypeScriptPythonWhat it gives
dx.account()dx.account()The balance, this key's limits and spend, the rate limit.
dx.usage({ group_by: "capability" })dx.usage(group_by="capability")Finished calls, counted and summed.
dx.calls.get(requestId)dx.calls.get(request_id)What became of a call and what it was charged.
dx.calls.result(requestId, { view: "full" })dx.calls.result(request_id, view="full")The saved result again, in any view, for 24 hours.
dx.calls.byKey(key)dx.calls.by_key(key)What an idempotency key stands for now.
dx.catalog.search({ query: "…" })dx.catalog.search("…")Finds an endpoint from a need put in words: 5 at most.