The @agentstate/sdk package provides a typed client for the AgentState API. It wraps all REST endpoints in async methods with full TypeScript types.
npm install @agentstate/sdk
# or
bun add @agentstate/sdkimport { AgentState } from "@agentstate/sdk";
const client = new AgentState({
apiKey: process.env.AGENTSTATE_API_KEY!,
baseUrl: "https://agentstate.app/api", // optional, this is the default
});The SDK uses the standard fetch API with no platform-specific dependencies. It works in:
- Node.js 18+
- Bun
- Deno
- Cloudflare Workers
- Browsers
| Method | Returns | Description |
|---|---|---|
createConversation(data) |
ConversationWithMessages |
Create with optional title, external_id, metadata, messages |
getConversation(id) |
ConversationWithMessages |
Get conversation with all messages |
getConversationByExternalId(eid) |
ConversationWithMessages |
Lookup by your external ID |
listConversations(params?) |
ListResponse<Conversation> |
List with cursor pagination |
updateConversation(id, data) |
Conversation |
Update title and/or metadata |
deleteConversation(id) |
void |
Delete conversation and all messages |
appendMessages(id, messages) |
{ messages: Message[] } |
Append messages to conversation |
listMessages(id, params?) |
ListResponse<Message> |
List messages with pagination |
generateTitle(id) |
{ title: string } |
AI-generated title from message content |
generateFollowUps(id) |
{ questions: string[] } |
AI-generated follow-up questions |
exportConversations(ids?) |
{ data: ConversationWithMessages[], count: number } |
Bulk export (all or by IDs) |
listConversations(params?)
limit— number of results (default: server-defined)cursor— pagination cursor from a previous responseorder—"asc"or"desc"
listMessages(conversationId, params?)
limit— number of resultsafter— message ID cursor for forward pagination
createConversation(data)
external_id— your own ID for idempotent lookupstitle— conversation titlemetadata— arbitrary JSON objectmessages— initial messages (each withrole,content, optionalmetadataandtoken_count)
All API errors throw AgentStateError with structured fields:
import { AgentState, AgentStateError } from "@agentstate/sdk";
try {
await client.getConversation("nonexistent");
} catch (err) {
if (err instanceof AgentStateError) {
console.log(err.code); // "NOT_FOUND"
console.log(err.status); // 404
console.log(err.message); // "Conversation not found"
}
}Common error codes:
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST |
Invalid request body or parameters |
| 401 | UNAUTHORIZED |
Missing or invalid API key |
| 404 | NOT_FOUND |
Resource does not exist |
| 429 | RATE_LIMITED |
Too many requests |
| 500 | INTERNAL_ERROR |
Server error |
import { AgentState } from "@agentstate/sdk";
const client = new AgentState({ apiKey: process.env.AGENTSTATE_API_KEY! });
// Create a conversation with initial messages
const conv = await client.createConversation({
title: "Support chat",
metadata: { agent: "helpdesk-v2" },
messages: [
{ role: "user", content: "How do I reset my password?" },
{ role: "assistant", content: "Go to Settings > Security > Reset Password." },
],
});
// Append more messages
await client.appendMessages(conv.id, [
{ role: "user", content: "Thanks, that worked!" },
]);
// Get the full conversation
const full = await client.getConversation(conv.id);
console.log(full.messages.length); // 3
// Update metadata
await client.updateConversation(conv.id, {
metadata: { agent: "helpdesk-v2", resolved: true },
});
// Delete when done
await client.deleteConversation(conv.id);let cursor: string | undefined;
do {
const page = await client.listConversations({ limit: 50, cursor });
for (const conv of page.data) {
console.log(conv.id, conv.title);
}
cursor = page.pagination.next_cursor ?? undefined;
} while (cursor);// Create with your own ID
await client.createConversation({
external_id: "thread_abc123",
title: "Slack thread",
});
// Later, look it up by that ID
const conv = await client.getConversationByExternalId("thread_abc123");// Generate a title from the conversation content
const { title } = await client.generateTitle(conv.id);
console.log(title); // "Password Reset Help"
// Get follow-up question suggestions
const { questions } = await client.generateFollowUps(conv.id);
console.log(questions);
// ["Would you like to enable two-factor authentication?", ...]// Export all conversations
const all = await client.exportConversations();
console.log(`Exported ${all.count} conversations`);
// Export specific conversations
const subset = await client.exportConversations(["id1", "id2"]);The following operations are available through the REST API but not yet wrapped in the SDK:
- Search conversations —
GET /v1/conversations/search - Bulk delete —
POST /v1/conversations/bulk-delete - Tags management — all tag endpoints
- Analytics —
GET /v1/projects/:id/analytics - Conversation analytics —
GET /v1/conversations/:id/analytics - Public analytics summary —
GET /v1/analytics/summary - Public analytics timeseries —
GET /v1/analytics/timeseries - Public analytics tags —
GET /v1/analytics/tags
Use the REST API directly for these. See the API Reference for details.
- API Reference — full REST API documentation
- Integration Guide — framework-specific examples (LangChain, Vercel AI SDK, etc.)