The Sery SDK
The sery SDK lets any script or app query your data mesh by address — official clients for Python (pip install sery) and TypeScript / JavaScript (npm install @seryai/sdk). You write one SQL statement that references sources by a sery:// URI; Sery resolves each address to the machine that owns the data, runs the query there, and returns only the result rows. Raw files never move through Sery — the query goes to the data, not the other way around.
The walkthrough below is in Python; the JavaScript / TypeScript equivalent has its own section further down.
It talks to data.sery.ai, the public data API (separate from the dashboard's api.sery.ai). Requires a workspace API key and the Plus plan.
Install
# Python pip install sery # add sery[pandas] for .to_pandas() # TypeScript / JavaScript (zero deps; Node >= 18, browser, edge, Deno, Bun) npm install @seryai/sdk
Authenticate
Create a workspace API key at Settings → API Keys (keys start with sery_; the data API is a Plus feature). Pass it to the client:
import sery client = sery.Client(api_key="sery_...") # base_url defaults to https://data.sery.ai
Discover sources
catalog() lists every addressable source in your workspace, each with the sery:// address you pass to query() and its column schema:
for src in client.catalog():
print(src.sery_uri, "—", src.machine, src.file_format)
# sery://sam-laptop/local/sales/orders.parquet — sam-laptop parquetAn address is sery://<machine>/<protocol>/<path> — the machine's name or stable id, a protocol (local, s3, https), and the file path. Anything from catalog() is guaranteed to resolve.
Run a query
df = client.query("""
SELECT customer, SUM(amount) AS total
FROM 'sery://sam-laptop/local/sales/orders.parquet'
GROUP BY customer
ORDER BY total DESC
""").to_pandas()The result object also exposes raw access:
result = client.query("SELECT * FROM 'sery://my-mac/local/data.parquet' LIMIT 5")
result.columns # ['id', 'name', ...]
result.rows # [[1, 'a'], [2, 'b'], ...]
for row in result: # iterate as dicts
print(row["name"])
result.incomplete # True if a machine didn't respond
result.warnings # human-readable warnings to surfaceWhen incomplete is True, a targeted machine was offline — check warnings before trusting an aggregate, since a SUM/COUNT may undercount.
JavaScript / TypeScript
The same API in TypeScript — zero dependencies (uses the global fetch), so it runs in Node, the browser, edge runtimes, Deno, and Bun.
import { Client } from "@seryai/sdk";
const client = new Client({ apiKey: "sery_..." }); // base: https://data.sery.ai
// Discover sources
for (const src of await client.catalog()) {
console.log(src.seryUri, src.machine, src.fileFormat);
}
// Run a query
const result = await client.query(`
SELECT customer, SUM(amount) AS total
FROM 'sery://sam-laptop/local/sales/orders.parquet'
GROUP BY customer
ORDER BY total DESC
`);
console.table(result.toObjects()); // [{ customer, total }, ...]
result.incomplete; // true if a machine didn't respond
result.warnings; // surface these before trusting aggregatesErrors are typed classes mirroring the Python ones — catch with instanceof:
import { AmbiguousMachine } from "@seryai/sdk";
try {
await client.query("SELECT * FROM 'sery://laptop/local/x.parquet'");
} catch (e) {
if (e instanceof AmbiguousMachine) {
for (const c of e.candidates) console.log(c.label, c.machine_id);
}
}Errors
Every failure is a typed exception (Python sery.errors / TypeScript named exports):
| Exception | When |
|---|---|
AuthError | missing / invalid API key (401) |
QueryError | no sery:// refs, bad address, unsupported protocol (400) |
MachineNotFound | unknown machine (404) |
AmbiguousMachine | a name matched >1 machine — .candidates lists machine ids (409) |
CrossMachineJoinUnsupported | the query spans machines — .machines (422) |
MachinesUnavailable | every targeted machine offline — .failures (503) |
try:
client.query("SELECT * FROM 'sery://laptop/local/x.parquet'")
except sery.AmbiguousMachine as e:
for c in e.candidates:
print(c["label"], c["machine_id"]) # re-issue with the machine_idLimits
All sources in one query must live on the same machine — cross-machine joins raise CrossMachineJoinUnsupported for now. Routable protocols today: local, s3, https. The data API is rate-limited per workspace and requires the Plus plan.
Source on GitHub: seryai/sery-sdk-python.
Ready to get started?
Download Sery Link, pick a folder, ask your first question. No account required.
Download Sery Link