> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swarmlord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK

> The swarmlord TypeScript client.

A single package, works in Node, Bun, the browser, and edge runtimes.

```bash theme={null}
npm install swarmlord
```

## Create a client

```ts theme={null}
import { createClient } from "swarmlord";

const client = createClient({
  apiKey: process.env.SWARMLORD_API_KEY!,
  // baseUrl defaults to https://api.swarmlord.ai
});
```

## Talk to an agent

```ts theme={null}
const session = await client.agent("hello-agent").createSession();

const { value, degraded } = await session
  .send({ parts: [{ type: "text", text: "Say hi." }] })
  .result<string>();
```

`result()` resolves on the first terminal event. `degraded` is `true` if there were retries.

## Stream

```ts theme={null}
for await (const ev of session.stream({ parts: [{ type: "text", text: "Hi" }] })) {
  if (ev.type === "part.appended" && ev.part.type === "text") {
    process.stdout.write(ev.part.text);
  }
  if (ev.type === "session.completed") break;
}
```

## Multi-turn

```ts theme={null}
await session.send({ parts: [{ type: "text", text: "My name is Ada." }] }).result();
await session.send({ parts: [{ type: "text", text: "What's my name?" }] }).result();
// → "Your name is Ada."
```

## Structured output

Use [Zod](https://zod.dev) to validate the reply:

```ts theme={null}
import { z } from "zod";

const Recipe = z.object({
  title: z.string(),
  servings: z.number(),
  ingredients: z.array(z.object({ item: z.string(), quantity: z.string() })),
});

const { value: text } = await session
  .send({ parts: [{ type: "text", text: "Reply with carbonara as strict JSON." }] })
  .result<string>();

const recipe = Recipe.parse(JSON.parse(text));
```

## Attachments & artifacts

Upload a file (CSV, image, PDF, …) and get back an `r2://media/...` reference. Download resolves
that reference — or any artifact your agent produced — back to bytes.

```ts theme={null}
const csv = "month,revenue\nJan,42000\nFeb,45500\n";

// Store it. Returns { url: "r2://media/<uuid>-data.csv" }.
const { url } = await session.upload({
  filename: "data.csv",
  mime: "text/csv",
  bytes: new TextEncoder().encode(csv),
});

// Fetch it (or a chart the agent rendered) back out.
const { bytes, mime } = await session.download(url);
```

`download()` accepts either a full `r2://media/...` ref or a bare `media/...` key.

## Reconnect to a known session

```ts theme={null}
const session = client.session("25e8755c-ed87-4bcd-95fa-3963068e5c1a");
```

## Resume with replay

```ts theme={null}
import { streamSession } from "swarmlord";

const stream = streamSession(sessionId, {
  opts: { apiKey },
  sinceSeq: lastSeen,
});

for await (const ev of stream) {
  if (ev.type === "session.completed") break;
}
```

## Abort

```ts theme={null}
await session.abort();
```

## Verify incoming webhooks

```ts theme={null}
import { verifyWebhook } from "swarmlord/webhooks";

const ok = await verifyWebhook({
  secret: process.env.SWARMLORD_WEBHOOK_SECRET!,
  signature: req.headers.get("x-swarmlord-signature")!,
  body: await req.text(),
});
```

## Types

```ts theme={null}
import type { AgentEvent, Part, Terminal } from "swarmlord";
```

See the [HTTP reference](/api/http) for the raw wire protocol and [Events](/api/events) for the full event vocabulary.
