---
title: "TypeScript SDK Overview"
description: "Call an eve agent from TypeScript with Client, sessions, auth, and health checks."
---

The `eve/client` entrypoint is the typed client for eve's default HTTP API. Use it from scripts, server-to-server integrations, tests, evals, backend jobs, or custom UIs that want the session protocol without hand-writing the POST and NDJSON (newline-delimited JSON) stream loop.

For browser chat UIs, start with [`useEveAgent`](../frontend/overview). For wire-level details, read [Sessions, runs & streaming](../../concepts/sessions-runs-and-streaming). The client sits between those two: lower level than the frontend hooks, higher level than raw HTTP.

## Create a client

A `Client` binds one host, auth policy, and header policy:

```ts
import { Client } from "eve/client";

const client = new Client({
  host: "http://127.0.0.1:2000",
});
```

`host` is the URL where the eve routes are mounted. In a same-origin browser integration this is often `""`; scripts and backend services usually name the full URL. Any query parameters on `host` are included on every request, including session POSTs and event streams. Request-specific parameters, such as a stream cursor, take precedence when names overlap.

## Check health

Use `health()` when a script needs to fail early before creating a session:

```ts
const health = await client.health();
console.log(health.status, health.workflowId);
```

Non-2xx responses throw `ClientError`, which carries the HTTP `status` and response `body`.

## Inspect an agent

Use `info()` to inspect a development agent. The client parses and validates the complete response before returning it:

```ts
const info = await client.info();
console.log(info.agent.name, info.agent.model.id);
```

## Authentication

Pass `auth` when the [eve channel](../../channels/eve) route requires credentials:

```ts
const client = new Client({
  host: "https://agent.example.com",
  auth: {
    bearer: async () => await getAccessToken(),
  },
});
```

Bearer values and Basic auth passwords can be strings or functions. Functions run before every HTTP call, including stream reconnects:

```ts
const client = new Client({
  host: "https://agent.example.com",
  auth: {
    basic: {
      username: "agent-client",
      password: async () => await getRotatingSecret(),
    },
  },
});
```

For a Vercel OIDC-protected deployment, use `vercelOidc`. The client resolves the token once per request and sends it as both the bearer credential and Vercel's trusted-OIDC header:

```ts
import { getVercelOidcToken } from "@vercel/oidc";

const client = new Client({
  host: "https://agent.example.com",
  auth: {
    vercelOidc: {
      token: async () => await getVercelOidcToken(),
    },
  },
});
```

Use `headers` for route-specific credentials such as bypass tokens or tenant hints. Like `auth`, it can be static or dynamic:

```ts
const client = new Client({
  host: "https://agent.example.com",
  headers: async () => ({
    "x-vercel-protection-bypass": await getBypassToken(),
  }),
  redirect: "manual",
});
```

Set `redirect` to `"manual"` or `"error"` on credential-bearing clients so fetch cannot forward custom authorization headers to another origin. The policy applies to inspection requests, custom fetches, session creation, and event streams.

Per-request headers can be attached to an individual turn:

```ts
const response = await session.send("Run the check.", {
  headers: { "x-request-id": requestId },
});

await response.result();
```

Per-request headers override client-level values with the same name. For example, a turn can set its application user's `Authorization` header while `vercelOidc` continues to send the deployment-protection credential in `x-vercel-trusted-oidc-idp-token`.

## Sessions

For an ID-addressed session, create it explicitly with the first message:

```ts
const { session, response } = await client.sessions.create({ message: "Summarize account A." });
await response.result();

await (await session.send("Now list the risks.")).result();
await session.compact();
await session.clear();
```

If you already know the durable ID, attach a fixed handle without performing I/O:

```ts
const session = client.sessions.attach("wrun_A");
```

The fixed client handle exposes the full lifecycle around that ID. The calls below show the available shapes independently:

```ts
const response = await session.send("Continue the analysis.");
await response.result();

await session.cancel({ turnId: "turn_123" });
await session.compact();
await session.clear();

for await (const event of session.stream({ follow: false })) {
  console.log(event.type);
}

await session.reset({ reason: "User requested a fresh session" });
```

`client.sessions` stores only the session ID and stream cursor. Every method calls an ID-addressed `/eve/v1/session/:sessionId/...` route. Sending through a handle for an unknown or terminal ID fails instead of creating a replacement, and reset leaves the handle pinned to the retired ID.

A client can own many independent fixed sessions at once:

```ts
const { session: alice, response: aliceResponse } = await client.sessions.create({
  message: "Summarize account A.",
});
const { session: bob, response: bobResponse } = await client.sessions.create({
  message: "Summarize account B.",
});

await Promise.all([aliceResponse.result(), bobResponse.result()]);
```

The next pages cover the session lifecycle:

- [Messages](./messages): send turns and collect results
- [Continuations](./continuations): persist and resume sessions
- [Streaming](./streaming): render events as they arrive
- [Output schema](./output-schema): request structured results

## What to read next

- [eve channel](../../channels/eve): the HTTP API this client calls
- [Sessions, runs & streaming](../../concepts/sessions-runs-and-streaming): the raw HTTP contract
- [Frontend](../frontend/overview): browser UI with `useEveAgent`
