# 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.

## Install

TypeScript

```bash
npm install @dataxapi/sdk
```

Python

```bash
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

TypeScript

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

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

Python

```python
from dataxapi import DataXAPI

dx = DataXAPI()  # reads DATAXAPI_API_KEY
labelled = DataXAPI(max_retries=3, source="my-app")
```

| TypeScript | Python | What it sets |
| --- | --- | --- |
| `apiKey` | `api_key` | The key. Default: the environment variable `DATAXAPI_API_KEY`. |
| `baseUrl` | `base_url` | The service's address. Default: `DATAXAPI_BASE_URL`, else `https://api.dataxapi.com`. |
| `timeoutMs` | `timeout` | How long one attempt may take: milliseconds in TypeScript, seconds in Python. Default: 65 seconds. |
| `maxRetries` | `max_retries` | How many times a request that may be retried is sent again. Default: 2. |
| `source` | `source` | A label recorded on every call: where it comes from. |
| `endUser` | `end_user` | A 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.

TypeScript

```ts
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" });
```

Python

```python
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](https://dataxapi.com/docs/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.

TypeScript

```ts
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);
```

Python

```python
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.

TypeScript

```ts
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;
}
```

Python

```python
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.

| TypeScript | Python | What 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. |

---

Catalog revision c48ce454ae6c4c65. [HTML version](https://dataxapi.com/docs/sdk/)
