Get started
SDKs and CLI
Clients for Python and TypeScript, and a trivda command line. They wrap every operation in the API reference, type the licence and provenance on every passage, retry safely and report what each search cost.
Python
pip install trivda
export TRIVDA_URL="https://13-63-0-55.sslip.io"
export TRIVDA_API_KEY="sk_test_..." # a sandbox key while you build
from trivda import Trivda
client = Trivda() # reads TRIVDA_URL and TRIVDA_API_KEY
result = client.search("How often should the compressor be serviced?", top_k=5)
for hit in result.results:
print(hit.rank, round(hit.score, 2), hit.license.spdx, hit.citation.source_uri)
print(" ", hit.text[:160])
print("cost EUR", result.cost.query_cost_eur, "| credits left", result.cost.credits_remaining)
Its one dependency is httpx. Errors are exceptions named after the status: InsufficientFundsError (402), RateLimitError (429, with retry_after), AuthenticationError (401) and so on, each with the server's detail.
TypeScript and JavaScript
npm install trivda
import { Trivda } from "trivda";
const client = new Trivda(); // reads TRIVDA_URL and TRIVDA_API_KEY
const result = await client.search("How often should the compressor be serviced?", { topK: 5 });
for (const hit of result.results ?? []) {
console.log(hit.rank, hit.license?.spdx, hit.citation?.source_uri);
}
console.log("cost EUR", result.cost.queryCostEur);
No runtime dependencies: it uses the platform's fetch. ESM and CommonJS (require("trivda")) both work, with types. Methods are the operation ids in camelCase: listDatasets, usageWallet, uploadDataset.
What the clients do for you
- One method per operation, named after its operation id in the OpenAPI spec:
search,list_datasets,usage_walletin Python. - Idempotency. Every search sends an
Idempotency-Key: yours if you pass one, otherwise a new UUID. A retry reuses it, so it is never charged twice. See Idempotency-Key. - Retries with exponential backoff on 429, 500, 502, 503 and 504, twice by default, waiting the
Retry-Afterseconds when the server sends them. Uploads and other changes are retried only on 429, which is refused before anything runs. - Cost.
result.costholdsX-Query-Cost,X-Tokens-Used,X-Credits-Remainingand whether the response was a replay. - Pagination.
iter_datasets()(iterDatasets()) followsnext_cursorthrough every page ofGET /api/v1/datasets. - Forward compatible. Fields the server adds later are kept, never dropped.
Command line
The Python package installs a trivda command. It reads the same two environment variables, or takes --base-url and --api-key.
| Command | Does |
|---|---|
trivda search "<question>" --top-k 5 | Search, and print each passage with its licence and the cost. |
trivda datasets list --all | List the datasets you can see, every page. |
trivda balance | Wallet credits, earnings and free searches. |
trivda upload ./reports --dataset-id annual-reports --recursive | Upload a file, or every file in a folder, into one of your datasets. Private unless --offered. |
trivda keys whoami | The organisation, key and scopes in use, and whether the key is a sandbox key. |
Add --json to any command for the API's JSON. The exit code is 1 when the API refused, with the reason printed.
Sandbox keys
A sandbox key starts with sk_test_. It works with the same routes and the same request and response shapes as a live key, but every answer comes from a fixed set of synthetic data. Use it to build and test before you spend credits.
- It never reads real data and is never charged:
X-Query-Costis0.000000and the wallet does not move. - Every response says so: the header
X-Sandbox: true, and"sandbox": truein every JSON body, errors included. - Passages are marked
content_class: "synthetic", their sources are underhttps://sandbox.invalid/and their datasets start withsandbox-. - The same request gets the same results, so you can write tests against them. An unknown
domainreturns no results, to try the empty case. - Rate limits,
Idempotency-Keyreplays, 422 validation and the dataset cursor behave as they do live. Uploads are read and discarded. - A sandbox key cannot create or revoke keys, and routes outside the public API answer 404.
Create one on the dashboard's API keys page with the Sandbox key switch, or with POST /api/v1/api-keys and "sandbox": true. GET /api/v1/api-keys/current tells you which kind of key a script is using. See Authentication.