Node.js SDK
The official Jettson SDK for Node.js. Native fetch, zero runtime deps, full type coverage.
Three lines, one agent. The Node SDK is the fastest path from npm install to a running agent.
Install
npm install @jettson/sdkRequires Node 18 or later. Uses native fetch — no runtime dependencies.
Quickstart
import { Jettson } from "@jettson/sdk";
const jettson = new Jettson({ apiKey: process.env.JETTSON_API_KEY! });
const agent = await jettson.agents.spawn({
task: "Browse https://news.ycombinator.com and return the top story title.",
});
const result = await jettson.agents.wait(agent.agent_id);
console.log(result.final_result);Get an API key at /console/api-keys.
Constructor
new Jettson({
apiKey: string, // required
baseUrl?: string, // default: "https://jettson.dev/api/v1"
maxRetries?: number, // default: 3
})| Option | Default | Notes |
| --- | --- | --- |
| apiKey (required) | — | Bearer token. Read it from env. |
| baseUrl | https://jettson.dev/api/v1 | Override for testing. |
| maxRetries | 3 | Retries on 429 + 5xx. Set to 0 for first-failure semantics. |
Agents
agents.spawn(input)
const agent = await jettson.agents.spawn({
task: "Research linear.app",
name: "research-run-001", // optional
region: "lhr", // optional — "iad" | "lhr" | "syd"
idempotencyKey: "spawn:abc:1", // optional — dedupe accidental retries
});Returns immediately with status: "spawning".
agents.wait(agentId, options?)
const result = await jettson.agents.wait(agent.agent_id, {
timeoutMs: 5 * 60 * 1000, // default
pollIntervalMs: 1000, // initial
maxPollIntervalMs: 5000, // ceiling (exponential backoff)
});Polls until status is completed / error / stopped. Throws AgentTimeoutError if the deadline lapses.
agents.get(agentId)
const agent = await jettson.agents.get("ag_…");agents.list(options?)
let cursor: string | undefined;
do {
const page = await jettson.agents.list({ limit: 50, cursor });
for (const a of page.data) console.log(a.agent_id, a.status);
cursor = page.next_cursor ?? undefined;
} while (cursor);agents.cancel(agentId)
await jettson.agents.cancel("ag_…");Idempotent. Terminal agents return 200 unchanged.
Memory
memory.put(input)
await jettson.memory.put({
key: "brand_color",
value: "Brand primary color is #FF5733",
namespace: "user_profile",
importance: 8,
tags: ["brand"],
expiresInDays: 90, // optional
});memory.get(key, options?)
const m = await jettson.memory.get("brand_color", { namespace: "user_profile" });
if (m) console.log(m.value);Returns null (not an error) if no memory matches.
memory.search(input)
const results = await jettson.memory.search({
query: "what color is the brand?",
namespace: "user_profile",
mode: "hybrid", // "hybrid" | "semantic" | "keyword"
limit: 10,
minScore: 0.4,
});Returns an array of MemorySearchResult with score and breakdown per row.
memory.list(options?) / memory.delete(key, options?) / memory.dedupe(options?) / memory.consolidate(options?) / memory.namespaces() / memory.export() / memory.import(memories)
All ten public-API memory endpoints are covered. Signatures mirror the Memory API reference.
Error handling
Every HTTP failure surfaces as a typed error. Catch the base class to handle anything, or narrow:
import {
JettsonAuthError,
JettsonRateLimitError,
JettsonQuotaExceededError,
JettsonValidationError,
JettsonNotFoundError,
JettsonServerError,
JettsonNetworkError,
AgentTimeoutError,
} from "@jettson/sdk";
try {
await jettson.agents.spawn({ task: "…" });
} catch (err) {
if (err instanceof JettsonRateLimitError) {
console.log(`Backing off ${err.retryAfterSeconds}s`);
} else if (err instanceof JettsonQuotaExceededError) {
console.log(`Hit quota: ${err.used}/${err.limit} on ${err.plan}`);
} else {
throw err;
}
}Idempotent spawns
If your code might retry a spawn because of a network blip on the way to Jettson, pass an idempotency key:
await jettson.agents.spawn({
task: "…",
idempotencyKey: `spawn:${userId}:${requestId}`,
});The server returns the same agent for repeat calls inside a short window.
Regions
Multi-region warm pool is live in iad / lhr / syd. Pin a region per spawn:
await jettson.agents.spawn({ task: "…", region: "lhr" });If you don't specify one, the server tries iad first then falls back to other regions before cold-spawning.
Retries
Automatic retries on:
- 429 — honors
Retry-Afterheader (3 attempts) - 5xx — exponential backoff 1s → 2s → 4s (3 attempts)
- Network failure — one retry after the initial backoff
// Disable retries
new Jettson({ apiKey, maxRetries: 0 });TypeScript types
Everything is exported:
import type {
Agent,
AgentListResponse,
AgentStatus,
Memory,
MemorySearchResult,
MemorySearchMode,
NamespaceInfo,
Region,
// …and all error classes
} from "@jettson/sdk";Source
github.com/jettsondev/jettson-sdk-node — MIT, ~1k LOC + tests. Read it.
Related
- Python SDK
- API reference — the surface the SDK wraps
- Memory concepts — what
memory.*is really doing under the hood