---
description: Reference for the Agent base class, lifecycle hooks, SQL storage, and error handling in the Agents SDK.
title: Agents API
image: https://developers.cloudflare.com/og-docs.png
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/agents/llms.txt  
> Use this file to discover all available pages before exploring further.

# Agents API

Last updated Sep 4, 2026|Copy as Markdown| [View as Markdown](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/agents-api/index.md)| [Agent setup](https://cb4c3fd6.previews.developers.cloudflare.com/agent-setup/)

This page provides an overview of the Agents SDK. For detailed documentation on each feature, refer to the linked reference pages.

## Overview

The Agents SDK provides two main APIs:

| API | Description |
| --- | --- |
| **Server-side** `Agent` class | Encapsulates agent logic: connections, state, methods, AI models, error handling |
| **Client-side** SDK | `AgentClient`, `useAgent`, and `useAgentChat` for connecting from browsers |

Note

Agents require [Cloudflare Durable Objects](https://cb4c3fd6.previews.developers.cloudflare.com/durable-objects/). Refer to [Configuration](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/operations/configuration/) to learn how to add the required bindings.

## Agent class

An Agent is a class that extends the base `Agent` class:

```ts
import { Agent, routeAgentRequest } from "agents";

export class MyAgent extends Agent<Env, State> {
	// Your agent logic
}

export default {
	async fetch(request: Request, env: Env) {
		return (
			(await routeAgentRequest(request, env)) ||
			new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;
```

Each Agent can have millions of instances. Each instance is a separate micro-server that runs independently, allowing horizontal scaling. Instances are addressed by a unique identifier (user ID, email, ticket number, etc.).

Note

An instance of an Agent is globally unique: given the same name (or ID), you will always get the same instance of an agent.

This allows you to avoid synchronizing state across requests: if an Agent instance represents a specific user, team, channel or other entity, you can use the Agent instance to store state for that entity. There is no need to set up a centralized session store.

If the client disconnects, you can always route the client back to the exact same Agent and pick up where they left off.

## Lifecycle

```
flowchart TD
    A["onStart<br/>(instance wakes up)"] --> B["onRequest<br/>(HTTP)"]
    A --> C["onConnect<br/>(WebSocket)"]
    A --> D["onEmail"]
    C --> E["onMessage ↔ send()<br/>onError (on failure)"]
    E --> F["onClose"]

```

| Method | When it runs |
| --- | --- |
| `onStart(props?)` | When the instance starts, or wakes from hibernation. Receives optional [initialization props](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/routing/#props) passed via `getAgentByName` or `routeAgentRequest`. |
| `onRequest(request)` | For each HTTP request to the instance |
| `onConnect(connection, ctx)` | When a WebSocket connection is established |
| `onMessage(connection, message)` | For each WebSocket message received |
| `onError(connection, error)` | When a WebSocket error occurs |
| `onClose(connection, code, reason, wasClean)` | When a WebSocket connection closes |
| `onEmail(email)` | When an email is routed to the instance |
| `onStateChanged(state, source)` | When state changes (from server or client) |

## Core properties

| Property | Type | Description |
| --- | --- | --- |
| `this.env` | `Env` | Environment variables and bindings |
| `this.ctx` | `ExecutionContext` | Execution context for the request |
| `this.state` | `State` | Current persisted state |
| `this.sql` | Function | Execute SQL queries on embedded SQLite |

## Server-side API reference

| Feature | Methods | Documentation |
| --- | --- | --- |
| **State** | `setState()`, `onStateChanged()`, `initialState` | [Store and sync state](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/lifecycle/state/) |
| **Callable methods** | `@callable()` decorator | [Callable methods](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/lifecycle/callable-methods/) |
| **Scheduling** | `schedule()`, `scheduleEvery()`, `getScheduleById()`, `listSchedules()` | [Schedule tasks](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/schedule-tasks/) |
| **Durable execution** | `runFiber()`, `startFiber()`, `stash()`, `onFiberRecovered()`, `keepAlive()`, `keepAliveWhile()` | [Durable execution](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/durable-execution/) |
| **Queue** | `queue()`, `dequeue()`, `dequeueAll()`, `getQueue()` | [Queue tasks](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/queue-tasks/) |
| **WebSockets** | `onConnect()`, `onMessage()`, `onClose()`, `broadcast()` | [WebSockets](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/websockets/) |
| **HTTP/SSE** | `onRequest()` | [HTTP and SSE](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/http-sse/) |
| **Email** | `onEmail()`, `replyToEmail()` | [Email routing](https://cb4c3fd6.previews.developers.cloudflare.com/agents/communication-channels/email/) |
| **Workflows** | `runWorkflow()`, `waitForApproval()` | [Run Workflows](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/run-workflows/) |
| **MCP Client** | `addMcpServer()`, `removeMcpServer()`, `getMcpServers()` | [MCP Client API](https://cb4c3fd6.previews.developers.cloudflare.com/agents/model-context-protocol/apis/client-api/) |
| **AI Models** | Workers AI, OpenAI, Anthropic bindings | [Using AI models](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/operations/using-ai-models/) |
| **Protocol messages** | `shouldSendProtocolMessages()`, `isConnectionProtocolEnabled()` | [Protocol messages](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/protocol-messages/) |
| **Context** | `getCurrentAgent()` | [getCurrentAgent()](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/lifecycle/get-current-agent/) |
| **Tracing** | `wrapAISDK()` | [Tracing](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/operations/observability/tracing/) |
| **Diagnostics channels** | `subscribe()`, diagnostics channels | [Diagnostics channels](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/operations/observability/diagnostics-channels/) |
| **Sub-agents** | `subAgent()`, `abortSubAgent()`, `deleteSubAgent()` | [Sub-agents](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/sub-agents/) |
| **Agents as tools** | `runAgentTool()`, `clearAgentToolRuns()`, `hasAgentToolRun()` | [Agents as tools](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/agent-tools/) |
| **Agent Skills** | `skills` registry, bundled skill sources, script runners | [Agent Skills](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/agent-skills/) |
| **Sessions** | `Session.create()`, context blocks, compaction, search | [Sessions](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/lifecycle/sessions/) |
| **Think** | `Think` base class, workspace tools, lifecycle hooks, extensions | [Think](https://cb4c3fd6.previews.developers.cloudflare.com/agents/harnesses/think/) |
| **Chat SDK** | `createChatSdkState()`, `ChatSdkStateAgent` | [Chat SDK](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/chat-sdk/) |

## SQL API

Each Agent instance has an embedded SQLite database accessed via `this.sql`:

```ts
// Create tables
this.sql`CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, name TEXT)`;

// Insert data
this.sql`INSERT INTO users (id, name) VALUES (${id}, ${name})`;

// Query data
const users = this.sql<User>`SELECT * FROM users WHERE id = ${id}`;
```

For state that needs to sync with clients, use the [State API](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/lifecycle/state/) instead.

## Client-side API reference

| Feature | Methods | Documentation |
| --- | --- | --- |
| **WebSocket client** | `AgentClient` | [Client SDK](https://cb4c3fd6.previews.developers.cloudflare.com/agents/communication-channels/chat/client-sdk/) |
| **HTTP client** | `agentFetch()` | [Client SDK](https://cb4c3fd6.previews.developers.cloudflare.com/agents/communication-channels/chat/client-sdk/#http-requests-with-agentfetch) |
| **React hook** | `useAgent()` | [Client SDK](https://cb4c3fd6.previews.developers.cloudflare.com/agents/communication-channels/chat/client-sdk/#react) |
| **Chat hook** | `useAgentChat()` | [Client SDK](https://cb4c3fd6.previews.developers.cloudflare.com/agents/communication-channels/chat/client-sdk/) |
| **Agent tool events** | `useAgentToolEvents()` | [Agents as tools](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/execution/agent-tools/#render-child-timelines-in-react) |

Module-level helper exports include `agentTool()` from `agents/agent-tools`, which converts a Think or `AIChatAgent` subclass into an AI SDK tool definition.

### Quick example

```ts
import { useAgent } from "agents/react";
import type { MyAgent } from "./server";

function App() {
	const agent = useAgent<MyAgent, State>({
		agent: "my-agent",
		name: "user-123",
	});

	// Call methods on the agent
	agent.stub.someMethod();

	// Update state (syncs to server and all clients)
	agent.setState({ count: 1 });
}
```

## Chat agents

For AI chat applications, extend `AIChatAgent` instead of `Agent`:

```ts
import { AIChatAgent } from "@cloudflare/ai-chat";

class ChatAgent extends AIChatAgent {
	async onChatMessage(onFinish) {
		// this.messages contains the conversation history
		// Return a streaming response
	}
}
```

Features include:

- Built-in message persistence
- Automatic resumable streaming (reconnect mid-stream)
- Works with `useAgentChat` React hook

Refer to [Build a chat agent](https://cb4c3fd6.previews.developers.cloudflare.com/agents/examples/chat-agent/) for a complete tutorial.

## Routing

Agents are accessed via URL patterns:

```txt
https://your-worker.workers.dev/agents/:agent-name/:instance-name
```

Use `routeAgentRequest()` in your Worker to route requests:

```ts
import { routeAgentRequest } from "agents";

export default {
	async fetch(request: Request, env: Env) {
		return (
			routeAgentRequest(request, env) ||
			new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;
```

Refer to [Routing](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/routing/) for custom paths, CORS, and instance naming patterns.

## Next steps

### [Quick start](https://cb4c3fd6.previews.developers.cloudflare.com/agents/getting-started/quick-start/)

Build your first agent in about 10 minutes.

### [Configuration](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/operations/configuration/)

Learn about wrangler.jsonc setup and deployment.

### [WebSockets](https://cb4c3fd6.previews.developers.cloudflare.com/agents/runtime/communication/websockets/)

Real-time bidirectional communication with clients.

### [Build a chat agent](https://cb4c3fd6.previews.developers.cloudflare.com/agents/examples/chat-agent/)

Build AI applications with AIChatAgent.

Was this helpful?

YesNo

## On this page

[![](https://cb4c3fd6.previews.developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://cb4c3fd6.previews.developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/agents/runtime/agents-api/#page","headline":"Agents API · Cloudflare Agents docs","description":"Reference for the Agent base class, lifecycle hooks, SQL storage, and error handling in the Agents SDK.","url":"https://developers.cloudflare.com/agents/runtime/agents-api/","inLanguage":"en","image":"https://developers.cloudflare.com/og-docs.png","dateModified":"2026-09-04","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```
