SDK v0.2 → v0.3
Breaking changes in @codespar/sdk@0.3.0 and how to migrate an existing 0.2 codebase. Create / execute / send signatures changed; 2-level tenancy shipped.
Migration — SDK v0.2 → v0.3
@codespar/sdk@0.3.0 is a breaking release aligned end-to-end with the backend's canonical wire contract. Every framework adapter (@codespar/claude, @codespar/openai, @codespar/vercel, etc.) was bumped to 0.3.0 in lockstep. This page walks through each change and shows the before / after for real code.
The 0.2 line stays on npm — your production code will not break until you bump. We recommend upgrading in one PR per service, against sandbox (csk_test_) first, then production.
Summary of breaking changes
| Before (0.2) | After (0.3) |
|---|---|
codespar.sessions.create({ servers }) | codespar.create(userId, { servers }) |
session.execute({ name, arguments }) | session.execute(name, params) |
session.send({ name, arguments }) (fire-and-forget tool call) | session.send(message) (natural-language agent loop) |
session.sendStream({ name, arguments }) | session.sendStream(message) (streams agent events) |
session.mcp() (method) | session.mcp (property) |
| No project scoping | SessionConfig.projectId + x-codespar-project header |
| TypeScript only | Python published on PyPI (codespar>=0.1.1) |
Everything else (tool result shapes, session.tools, session.connections, session.close, session.authorize, session.findTools) is unchanged.
1. Session creation takes a userId first
The session is now scoped to an end-user. Credentials, audit logs, and billing all attach to that ID.
Before
const session = await codespar.sessions.create({
servers: ["stripe", "mercadopago"],
});After
const session = await codespar.create("user_123", {
servers: ["stripe", "mercadopago"],
});Pass a real identifier from your own system (Clerk userId, Supabase auth ID, the end-customer's email hash — whatever uniquely maps to the human on whose behalf the agent acts). For server-side jobs, pick a stable synthetic ID like "cron-worker" or "webhook-processor".
Migration strategy
- Search your codebase for
sessions.create(— replace each call withcodespar.create("user_123", ...)(use your real user ID). - Where your backend already has an authenticated user context, pipe it through instead of hardcoding.
- The
user_idnow also flows into tool-call logs and is filterable in the dashboard, which helps for per-user debugging.
2. session.execute takes two positional args
No more { name, arguments } object.
Before
const result = await session.execute({
name: "codespar_pay",
arguments: {
method: "pix",
amount: 15000,
currency: "BRL",
},
});After
const result = await session.execute("codespar_pay", {
method: "pix",
amount: 15000,
currency: "BRL",
});The return shape is unchanged — same success, data, error, duration, server, tool, tool_call_id, called_at.
Adapter helpers keep working
handleToolUse (Claude), handleToolCall (OpenAI), and the framework adapters internally call session.execute — they shield you from the signature change. If you only use adapter helpers, no code-level migration is needed beyond bumping package versions.
3. send / sendStream now drive a natural-language agent loop
This is the biggest semantic shift. In 0.2 these were fire-and-forget and streaming variants of execute — taking a tool name + arguments. They are not.
In 0.3 they take a plain-text message. The backend runs a Claude tool-use loop against the session's connected servers and returns the final response plus every tool call the agent made along the way.
Before (does not work in 0.3 — throws at compile time)
await session.send({
name: "codespar_notify",
arguments: { channel: "whatsapp", to: "+55...", template: "receipt" },
});After — if you wanted an async tool call
Use session.execute — same effect without the "queued" indirection:
await session.execute("codespar_notify", {
channel: "whatsapp",
to: "+55...",
template: "receipt",
});After — if you want the natural-language agent loop (0.3's new primitive)
const result = await session.send(
"Send a receipt to +5511999887766 via WhatsApp",
);
console.log(result.message); // agent's final response
console.log(result.tool_calls); // every tool the agent invokedThe same applies to sendStream — yields an async iterable of StreamEvent values with assistant_text, tool_use, tool_result, done, error types.
Audit the difference
In 0.2, send was often used for "fire the notification and don't care about the response." In 0.3 you have two ways to express that:
- Just fire —
session.execute("codespar_notify", params). Synchronous, cheap, unambiguous. - Let the agent decide —
session.send("Tell them their order shipped"). Useful when the message template is LLM-generated.
4. session.mcp is a property, not a method
In 0.2 you called await session.mcp() to get the MCP endpoint config. In 0.3 it is a property on the session object that is set at creation time.
Before
const mcpConfig = await session.mcp();
// { transport, url, tools }After
console.log(session.mcp);
// { url, headers }The returned shape changed too — it is now just the endpoint URL + auth headers, which is what MCP clients (Claude Desktop, Cursor) actually consume. The tools list is available via session.tools() as it always was.
5. 2-level tenancy via projectId
Account → Project is now a first-class tenancy dimension. Sessions (and all downstream artifacts) live in one project.
SDK
const session = await codespar.create("user_123", {
servers: ["stripe"],
projectId: "prj_a1b2c3d4e5f6g7h8",
});HTTP
curl -X POST https://api.codespar.dev/v1/sessions \
-H "Authorization: Bearer csk_live_..." \
-H "x-codespar-project: prj_a1b2c3d4e5f6g7h8" \
...If you omit projectId / the header, the backend resolves to the account's default project (auto-created at signup). Existing 0.2 traffic continues to land there automatically — no data migration needed.
See Projects for the full tenancy model.
6. Python package on PyPI
New in 0.3 — not a breaking change, but if you were waiting for Python support:
pip install codesparfrom codespar import CodeSpar
cs = CodeSpar() # reads CODESPAR_API_KEY
with cs.create("user_123", preset="brazilian") as session:
result = session.execute("codespar_pay", {"method": "pix", "amount": 15000, "currency": "BRL"})Sync (CodeSpar) and async (AsyncCodeSpar) flavours ship in the same wheel. See Quickstart (Python).
Framework adapters
Every adapter was bumped to 0.3.0 in lockstep:
npm install @codespar/sdk@^0.3.0 @codespar/claude@^0.3.0
# or
npm install @codespar/sdk@^0.3.0 @codespar/openai@^0.3.0
# ...The adapter surfaces (getTools, handleToolUse, handleToolCall, toClaudeTool, toOpenAITool, etc.) did not change — same function names, same return shapes. The version bump is to align the peer-dep against @codespar/sdk@^0.3.0.
Checklist
- Bump
@codespar/sdkto^0.3.0inpackage.json - Bump every
@codespar/ADAPTERpackage (claude, openai, vercel, etc.) to^0.3.0in the same commit - Replace
codespar.sessions.create(withcodespar.create(userId,across the codebase - Replace the old object-form
session.executecalls with the two-positional formsession.execute(name, params) - Audit every
session.sendcall — decide:executefor a direct tool call, or pass a string message for the agent loop - Replace
await session.mcp()withsession.mcp - (Optional) Pass
projectIdon session creation if you want explicit project scoping - Run the test suite against a sandbox
csk_test_key before swapping production keys
Troubleshooting
Argument of type 'string' is not assignable to parameter of type SessionConfig
— You have codespar.sessions.create(...) somewhere. sessions is gone; use codespar.create(userId, config) directly.
Type ToolCallInput is not assignable to parameter of type string (on a session.send(...) call)
— session.send now takes a string message. If the call used to be a tool invocation, switch to session.execute(name, params).
"codespar.sessions is not a function" — Same as above, at runtime. TypeScript should have caught it — double-check your build.
Adapter import fails with peer-dep warning
— Your lockfile is pinning @codespar/sdk@^0.2.0. Run npm install @codespar/sdk@latest @codespar/claude@latest (or whichever adapter you use) to upgrade both together.
Next steps
Error Reference
Every error code the CodeSpar API can return, with HTTP status, the response shape, when it fires, and the fix. Aggregated across sessions, projects, connections, triggers, wallets, and auth surfaces.
SDK v0.3 → v0.9
Upgrading from @codespar/sdk@0.3.0 to 0.9.0. Additive release — eight new typed wrappers, two new auth types, async settlement and verification correlation, SSE streaming. No breaking changes to the 0.3 surface.