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

# TypeScript SDK

> Create profiles, submit runs, stream events, and manage Orca from TypeScript.

The TypeScript SDK exports `OrcapodsClient` and generated request/response types under the `Orcapods` namespace. It is generated into `sdks/typescript`.

<Note>
  This repository currently contains the generated TypeScript source. If your deployment publishes it as an npm package, replace the local import path below with that package name.
</Note>

***

## Client setup

```typescript theme={null}
import { OrcapodsClient } from "../sdks/typescript";

const client = new OrcapodsClient({
  baseUrl: process.env.ORCA_BASE_URL ?? "https://api.orcapods.ai",
  apiKey: process.env.ORCA_API_KEY,
  timeoutInSeconds: 120,
});
```

Useful client options:

| Option             | Purpose                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------- |
| `baseUrl`          | Override the conductor URL                                                              |
| `apiKey`           | Bearer token sent as `Authorization: Bearer ao_...`; the tenant is derived from the key |
| `headers`          | Add custom deployment headers                                                           |
| `timeoutInSeconds` | Default request timeout                                                                 |
| `maxRetries`       | Default retry count                                                                     |
| `fetch`            | Use a custom `fetch` implementation                                                     |
| `logging`          | Configure SDK logging                                                                   |

Per-request options are the second argument:

```typescript theme={null}
await client.profiles.list({
  timeoutInSeconds: 10,
  maxRetries: 1,
});
```

***

## Create a profile

Profiles define the agent runtime, model, prompt, tools, skills, and optional MCP servers.

```typescript theme={null}
await client.profiles.create({
  name: "researcher",
  runtime: "general",
  model: "anthropic:claude-sonnet-4-6",
  systemPrompt: "You are a research assistant. Be concise and cite sources.",
  tools: ["@default", "web_search", "web_extract"],
});
```

Use these common runtime/model patterns:

| Runtime   | Model format                                            | Typical use                                             |
| --------- | ------------------------------------------------------- | ------------------------------------------------------- |
| `general` | `anthropic:...`, `openai:...`, `google:...`, `groq:...` | Multi-provider agents through the Vercel AI SDK sidecar |
| `claude`  | Claude model names                                      | Claude-specific sidecar behavior                        |
| `codex`   | Codex/OpenAI coding model names                         | Coding-focused sidecar behavior                         |

***

## Submit a run

The API can mint `runId` and `sessionId`. The current generated TypeScript type still requires `id` and `sessionId`, so pass empty strings when you want Orca to assign them. If you supply either identifier, it must be 1-128 characters and use only letters, numbers, underscores, or hyphens.

```typescript theme={null}
const run = await client.runs.create({
  id: "",
  profile: "researcher",
  sessionId: "",
  title: "SDK onboarding",
  prompt: "Explain what Orca profiles and runs are in three bullets.",
});

console.log(run.runId, run.sessionId);
```

Reuse a session by passing the previous `sessionId`:

```typescript theme={null}
const followup = await client.runs.create({
  id: "",
  profile: "researcher",
  sessionId: run.sessionId,
  title: "Follow-up",
  prompt: "Now turn that into onboarding copy for a new user.",
});
```

***

## Stream run events

`runs.stream` opens the Conductor SSE endpoint. Use a longer timeout for streams that may stay open while an agent is working.

<Note>
  The generated stream return type is `Stream<string>`, but Orca sends JSON `Event` objects in each SSE `data:` payload. Cast or parse the frames as `Orcapods.Event` in application code.
</Note>

```typescript theme={null}
import { Orcapods, OrcapodsClient } from "../sdks/typescript";

const client = new OrcapodsClient({ baseUrl: "https://api.orcapods.ai" });

const created = await client.runs.create({
  id: "",
  profile: "researcher",
  sessionId: "",
  title: "Streaming example",
  prompt: "Write a short onboarding checklist.",
});

const stream = await client.runs.stream(
  { id: created.runId },
  { timeoutInSeconds: 300 },
);

for await (const event of stream as AsyncIterable<Orcapods.Event>) {
  switch (event.type) {
    case "assistant":
    case "result":
      console.log(event.message);
      break;
    case "tool_call":
      console.log("tool:", event.toolName);
      break;
    case "error":
      throw new Error(event.message ?? "run failed");
  }
}
```

Use `runs.replayEvents({ id })` when you want the persisted event log instead of a live SSE connection.

***

## Read raw response metadata

Every SDK call returns an `HttpResponsePromise`. Await it for parsed data, or call `withRawResponse()` when you need headers and status metadata.

```typescript theme={null}
const response = await client.profiles.list().withRawResponse();

console.log(response.rawResponse.status);
console.log(response.rawResponse.headers);
console.log(response.data);
```

For endpoints not yet generated into a resource client, use the passthrough `fetch` method. Relative paths resolve against the configured base URL.

```typescript theme={null}
const response = await client.fetch("/healthz");
console.log(await response.text());
```

***

## Error handling

Known status codes throw generated subclasses such as `BadRequestError`, `ConflictError`, and `NotFoundError`. Other failed status codes throw `OrcapodsError`.

```typescript theme={null}
import { Orcapods, OrcapodsClient, OrcapodsError } from "../sdks/typescript";

try {
  await client.profiles.create({
    name: "researcher",
    runtime: "general",
  });
} catch (error) {
  if (error instanceof Orcapods.ConflictError) {
    console.log("Profile already exists");
  } else if (error instanceof OrcapodsError) {
    console.error(error.statusCode, error.body);
  } else {
    throw error;
  }
}
```

***

## Common calls

```typescript theme={null}
await client.misc.health();
await client.misc.seedOrca();
await client.misc.listCapabilityBundles();

await client.profiles.list();
await client.sessions.list();
await client.runs.list();
await client.runs.retrieve({ id: "run-..." });
await client.runs.cancel({ id: "run-..." });

await client.skills.list();
await client.mcp.list();
await client.memory.getBank();
await client.storage.info();
await client.topology.retrieve();
await client.stats.summary();
```

See the [SDK method map](/sdk/reference) for the full generated surface.

***

## VirtualFS TypeScript SDK

`@agent-orc/vfs` is the standalone VirtualFS HTTP client for TypeScript, and `@agent-orc/claude-vfs` is the Claude Messages Bash tool adapter that routes through it. Both packages live under `virtualfs/sdk/` and target the `/vfs/...` HTTP API directly rather than the conductor.

See [VirtualFS SDKs](/virtualfs/sdks) for installation, mount factories, typed file ops, the Vercel AI SDK / OpenAI tool bundle, the in-package `SandboxClient` facade, and Claude Bash tool integration.

## Strict mount validation

Every mount the client declares is checked against the server's live mount table. Call `await ws.validate()` before doing real work — typically right after constructing `Workspace` — so a misconfigured server fails fast instead of silently routing reads to the wrong store.

```typescript theme={null}
import { Workspace, r2, MountMismatch, MountUnavailable } from "@agent-orc/vfs";

const ws = new Workspace(
  {
    "/": r2({ bucket: "agent-orc-prod", endpoint: "https://<acct>.r2.cloudflarestorage.com" }),
  },
  { baseUrl: process.env.VFS_BASE_URL!, token: process.env.VFS_TOKEN! }
);

try {
  await ws.validate();
} catch (err) {
  if (err instanceof MountMismatch) {
    // declared path missing on server, or kind/bucket/endpoint mismatch
    throw err;
  }
  if (err instanceof MountUnavailable) {
    // server has the mount but backend failed to initialize; err carries reason
    throw err;
  }
}
```

Validation rejects with:

* `MountMismatch` — a declared path is not registered on the server, or the backend kind / bucket / endpoint does not match what the server reports.
* `MountUnavailable` — the server has the mount but its backend failed to initialize at boot; the server-reported `reason` is included.

The `r2()` factory signature:

```typescript theme={null}
r2(config: {
  bucket: string;
  endpoint?: string;   // S3-compatible endpoint URL; omit for default AWS S3
  prefix?: string;     // optional key prefix inside the bucket
}): R2Mount
```
