SDK installation
The Driftstack SDKs expose the same resources and methods in every language, with full type definitions. Pick the language that fits your stack.
TypeScript / Node.js
Status: published on npm. Pre-1.0 — the API contract is stable but the SDK shape may shift before 1.0. While the SDK is 0.x, a minor version can change the surface and a patch never does.
Install:
npm install @driftstack/sdk
# or
pnpm add @driftstack/sdk
# or
yarn add @driftstack/sdk
Requirements: Node.js ≥ 18 (uses native fetch). Works in any modern runtime exposing fetch and node:crypto (Bun, Deno via npm specifier). Both module systems work: import gives you the ESM build, require() the CommonJS one, each with its own type declarations.
Versions: install normally. The line above writes a caret range, and for a 0.x package npm resolves a caret to PATCH releases only — which is what you want. Read the changelog before moving to a new minor. Pin an exact version only if you need a byte-for-byte reproducible build, and note that your lockfile already gives you one.
Configure:
import { Driftstack } from '@driftstack/sdk';
const client = new Driftstack({
apiKey: process.env.DRIFTSTACK_API_KEY!,
baseUrl: 'https://api.driftstack.dev', // optional override
timeoutMs: 30_000,
retry: {
maxAttempts: 3,
initialDelayMs: 200,
maxDelayMs: 10_000,
},
});
Resources (every method is fully typed):
client.sessions.create(body?);
client.sessions.list(query?);
client.sessions.iterate(opts?);
client.sessions.navigate(id, body);
client.sessions.interact(id, body);
client.sessions.wait(id, body);
client.sessions.getState(id);
client.sessions.capture(id, body);
client.sessions.destroy(id);
client.agentSessions.create(body, opts?); // body.proxy_id is required
client.agentSessions.list(query?);
client.agentSessions.iterate(opts?);
client.agentSessions.get(id);
// Send a task; returns plan-executed | clarify | refuse | stopped | logged-manual — branch on kind.
client.agentSessions.message(id, userMessage, opts?);
client.agentSessions.runSteps(id, steps, opts?); // run your own steps (navigate, tap, type, ...) with no AI turn
client.agentSessions.registerSecret(id, body); // a credential your steps type later; never echoed back
client.agentSessions.listFrames(id); // the page's numbered frames, for steps inside an iframe
client.agentSessions.getCapture(id, captureId); // a screenshot the agent took: { contentType, bytes }
client.agentSessions.transcript(id, opts?); // the conversation so far, then live
client.agentSessions.stop(id); // stop the running task; its message() returns kind 'stopped'
client.agentSessions.close(id);
client.agentSessions.livekitToken(id); // a fresh live-video token for a running session
client.agentSessions.resume(id, body?);
client.agentSessions.setEgress(id, proxyId, applyPoint?); // not available yet
client.recipes.create(body); // snapshot an agent-session intent_log
client.recipes.list(query?);
client.recipes.iterate(opts?);
client.recipes.get(id);
client.recipes.delete(id);
client.profiles.create(body);
client.profiles.list(query?);
client.profiles.get(id);
client.profiles.launch(id, body?); // start a session on this profile
client.profiles.clone(id, body?); // a new profile with the same settings
client.profiles.export(id); // metadata-only JSON envelope
client.profiles.import(body); // mint a profile from an envelope
client.profiles.delete(id);
client.profileSnapshots.capture(profileId, body); // body.label is required (1-120 characters)
client.profileSnapshots.listForProfile(profileId, query?);
client.profileSnapshots.list(query?);
client.profileSnapshots.iterate(opts?);
client.profileSnapshots.get(snapshotId);
client.profileSnapshots.restore(snapshotId, body); // body.name is required: the new profile's name
client.profileSnapshots.delete(snapshotId);
client.webhooks.create(body);
client.webhooks.list();
client.webhooks.get(id);
client.webhooks.update(id, body); // partial update
client.webhooks.delete(id);
client.webhooks.listDeliveries(webhookId, query?);
client.webhooks.iterateDeliveries(webhookId, opts?);
client.webhooks.replayDelivery(deliveryId);
client.webhooks.rotateSecret(id); // 24h grace dual-sign
client.webhooks.sendTest(id); // synthetic test.ping
client.archetypes.list(); // list the device + iOS + Safari combinations you can choose from
client.egress.attachToSession(sessionId, body); // retired: answers 410; pass proxy_id at create
client.egress.getSessionProxy(sessionId); // retired: answers 410
client.egress.listProxies();
client.egress.createProxy(body);
client.egress.updateProxy(id, body);
client.egress.deleteProxy(id);
client.egress.testProxy(id);
client.usage.current();
client.usage.series(opts?); // usage per day; opts.days
client.account.whoami(); // the account, key, tier and scopes behind this key
client.account.rateLimits();
client.account.limits(); // the rate and counted limits, with usage
client.account.getBundledLlmStatus();
client.support.list(query?); // your Help conversations, newest first
client.support.create(body, opts?); // ask a question or report a problem; opts.idempotencyKey
client.support.get(id); // one conversation with its messages
client.support.addMessage(id, body); // a follow-up from you (reopens a closed conversation)
client.support.markRead(id);
client.support.close(id);
API keys, team members, billing and orders, sign-in, two-factor, email preferences and legal acceptance are managed in the Driftstack dashboard, not through the SDKs.
Errors: every error extends DriftstackError. Catch the base for blanket handling, or specific subclasses (RateLimitError, ConcurrencyLimitError, ValidationError, AuthError) for granular logic.
Python
Status: published on PyPI, pre-1.0, and classified Alpha. Use requirements constraints or a lockfile for reproducible deployments.
Install:
pip install driftstack-sdk
The distribution name is driftstack-sdk; the import name is driftstack.
Requirements: Python 3.10+.
Versions: install normally. In a requirements file, write the compatible-release specifier driftstack-sdk~=0.5.0 — it takes patch releases and stops before the next minor, which is what you want, because while the SDK is 0.x a minor version can change the surface and a patch never does. Read the changelog before moving to a new minor. Pin an exact version only if you need a byte-for-byte reproducible build, and note that a lockfile already gives you one.
Configure (sync):
import os
from driftstack import Driftstack
with Driftstack(api_key=os.environ["DRIFTSTACK_API_KEY"]) as client:
me = client.account.whoami()
print(me["account_id"])
Configure (async):
import asyncio
import os
from driftstack import AsyncDriftstack
async def main():
async with AsyncDriftstack(api_key=os.environ["DRIFTSTACK_API_KEY"]) as client:
me = await client.account.whoami()
print(me["account_id"])
asyncio.run(main())
Resources:
| Accessor | Methods |
|---|---|
client.sessions |
create, list, iterate, get, navigate, interact, wait, get_state, capture, extract, destroy; search and login are not available yet |
client.agent_sessions |
create, list, iterate, get, message, stop, close, livekit_token, resume (sync + async); set_egress is not available yet |
client.recipes |
create, list, iterate, get, delete (recipe management only; no execute method) |
client.profiles |
create, list, get, delete |
client.usage |
current_period |
client.webhooks |
create, list, get, update , delete, list_deliveries, iterate_deliveries, replay_delivery , rotate_secret , send_test |
client.account |
whoami, rate_limits, limits, get_bundled_llm_status; me is deprecated |
client.profile_snapshots |
capture, list_for_profile, list, iterate, get, restore, delete |
client.archetypes |
list |
client.egress |
list_proxies, create_proxy, update_proxy, delete_proxy, test_proxy; attach_to_session and get_session_proxy are retired (they answer 410; choose the proxy when you create the session) |
client.support |
list, create, get, add_message, mark_read, close (Help conversations) |
client.support reaches the same conversations as Help in the desktop app and the dashboard. Email support on every plan, the trial too.
Inputs accept either a Pydantic model OR a plain dict. sessions, usage, webhooks, archetypes and support return typed Pydantic models; every other resource — agent_sessions included — returns plain dicts that mirror the API’s JSON, so read them with result["field"].
sessions.search and sessions.login are typed in every SDK, but every
deployment answers them with 503 today. See Sessions
for both response branches.
Go
Status: published as a tagged pre-1.0 module. Commit go.mod and go.sum for reproducible deployments.
Install:
go get github.com/driftstackdev/driftstack-go@latest
Requirements: Go 1.22+ (the toolchain floor declared in go.mod).
Versions: install normally. The version you go get is written into your go.mod and does not move until you run go get -u — which is what you want, because while the module is 0.x a minor version can change the surface and a patch never does. Read the changelog before moving to a new minor. go.sum already makes the build reproducible, so there is nothing further to pin.
Configure:
package main
import (
"context"
"log"
"os"
driftstack "github.com/driftstackdev/driftstack-go"
)
func main() {
client := driftstack.New(os.Getenv("DRIFTSTACK_API_KEY"))
defer client.Close()
ctx := context.Background()
me, err := client.Account.Whoami(ctx)
if err != nil {
log.Fatal(err)
}
log.Println(me.AccountID)
}
The Go SDK is single-package, has zero non-stdlib runtime dependencies, and is context-aware throughout.
Resources: the Go client exposes the same resource accessors as the TypeScript and Python surfaces:
client.Sessions client.AgentSessions client.Recipes
client.Profiles client.ProfileSnapshots client.Archetypes
client.Webhooks client.Usage client.Egress
client.Account client.Support
Method names are the exported CamelCase form of the Python table above — client.webhooks.list_deliveries(id) is client.Webhooks.ListDeliveries(ctx, id) — and every call takes ctx as its first argument and returns a (value, error) pair.
Versioning across SDKs
The HTTP API and the SDKs version independently. SDKs at any version stay compatible with the live API contract; SDK upgrades unlock newer fields and new resource methods, but won’t break older method calls. See SDK versioning policy for the full guarantee.
What ships
| Capability | TS | Python | Go | Notes |
|---|---|---|---|---|
| Sessions | ✅ | ✅ | ✅ | Full CRUD + navigate/interact/wait/capture/getState/extract; search/login are not available yet |
| Agent sessions | ✅ | ✅ | ✅ | create/get/message/runSteps/stop/close/resume |
| Recipes | ✅ | ✅ | ✅ | create/list/get/delete; no execute method |
| Profiles | ✅ | ✅ | ✅ | Create, list, get, delete |
| Profile snapshots | ✅ | ✅ | ✅ | capture/list/restore/delete |
| Webhooks | ✅ | ✅ | ✅ | CRUD + delivery introspection + replayDelivery + rotateSecret |
| Usage | ✅ | ✅ | ✅ | Current-period read + 30-day daily series |
| Account | ✅ | ✅ | ✅ | whoami (account, key, tier, scopes) + rate limits + AI spend |
| Support | ✅ | ✅ | ✅ | Help conversations: list/create/get/addMessage/markRead/close |
On hosted Driftstack the step calls in the Sessions row do not run: a
create needs proxy_id, and navigate, interact, wait, capture, getState and
extract answer 503 driver-not-integrated. Drive pages on hosted with agent
sessions: runSteps for steps you write, message for a task in plain
words. See
Step-by-step operations on the hosted service.
Next steps
- Quickstart — first session in under five minutes.
- Profile management — persistent profiles across sessions.
- Session lifecycle — full state diagram and recovery semantics.