Installation #
Pick a client library, set environment variables, and verify the integration with a single GET.
DataDistillers exposes a plain HTTP/JSON API. Any language with a fetch-shaped HTTP client can talk to it. There is no SDK lock-in. The snippets below cover the most common language ecosystems.
You don't need an SDK
The whole API is two patterns: HTTP Basic auth on every call, and JSON in / JSON out. A direct integration is usually the right call; you avoid the dependency, the versioning surface, and the wrapper-bug debugging.
curl -u "$DD_KEY:$DD_SECRET" \ https://api.datadistillers.com/api/v1/wallet
If the response is a JSON WalletStatusResponse, your client and credentials
are configured correctly. Skip to Quickstart.
Environment variables
Two variables cover every integration:
DD_KEY=dk_live_… # API key (HTTP Basic username) DD_SECRET=sk_… # API key secret (HTTP Basic password)
For local development, drop them in .env.local. For production, use your
platform's secret store. Never commit either to git.
| Where the secret lives | Good fit for |
|---|---|
| AWS Secrets Manager / Parameter Store | EC2, ECS, Lambda |
| GCP Secret Manager | Cloud Run, GKE |
| HashiCorp Vault | Self-hosted, multi-cloud |
| Doppler / Infisical | Small teams, language-agnostic |
| GitHub Actions encrypted secrets | CI-only workloads |
Python
Standard library covers it; requests or httpx are nicer.
pip install requests
import os, requests
session = requests.Session()
session.auth = (os.environ['DD_KEY'], os.environ['DD_SECRET'])
session.headers['User-Agent'] = 'my-app/1.0'
BASE = 'https://api.datadistillers.com/api/v1'
# Verify
r = session.get(f'{BASE}/wallet')
r.raise_for_status()
print(r.json())
For async, swap to httpx.AsyncClient(auth=(key, secret)). Same shape.
Node.js / TypeScript
Node 18+ ships fetch natively. No dependency required.
const BASE = 'https://api.datadistillers.com/api/v1';
const auth = 'Basic ' + Buffer
.from(`${process.env.DD_KEY}:${process.env.DD_SECRET}`)
.toString('base64');
export async function dd<T>(path: string, init: RequestInit = {}): Promise<T> {
const r = await fetch(`${BASE}${path}`, {
...init,
headers: {
Authorization: auth,
'Content-Type': 'application/json',
...init.headers,
},
});
if (!r.ok) throw new Error(`${r.status} ${await r.text()}`);
return r.json() as Promise<T>;
}
// Verify
console.log(await dd('/wallet'));
A six-line wrapper covers every endpoint. Resist the urge to grow it into an SDK.
Go
package dd
import (
"encoding/json"
"net/http"
"os"
)
const Base = "https://api.datadistillers.com/api/v1"
var client = &http.Client{}
func Do(method, path string, body []byte, out any) error {
req, _ := http.NewRequest(method, Base+path, nil)
req.SetBasicAuth(os.Getenv("DD_KEY"), os.Getenv("DD_SECRET"))
res, err := client.Do(req)
if err != nil { return err }
defer res.Body.Close()
return json.NewDecoder(res.Body).Decode(out)
}
Verifying the integration
GET /wallet is the cheapest authenticated endpoint. Use it as a smoke test
in CI, in deploy hooks, or as a readiness check after rotating credentials.
HTTP=$(curl -s -o /dev/null -w '%{http_code}' \
-u "$DD_KEY:$DD_SECRET" \
https://api.datadistillers.com/api/v1/wallet)
[ "$HTTP" = "200" ] || { echo "auth broken: $HTTP"; exit 1; }
A 200 confirms the credentials work and the wallet is queryable. A 401
means the credentials are wrong. A 5xx means the API is down; page on it
the same way you would your own services.
Machine-readable tool catalogue
For LLM-driven tool use or codegen, the API exposes a tool catalogue at:
GET https://api.datadistillers.com/api/v1/llms.txt
Newer integrations (function-calling agents, MCP servers) can consume this directly to discover endpoints without parsing the OpenAPI spec.