# Community AI SDK > Official documentation for Community AI Client SDK ## Error Handling Handle errors gracefully in your integration. ### Error Format Errors include HTTP status and response body: ```typescript try { await client.chat({ externalUserId: 'user-123', message: 'Hello' }) } catch (error) { console.error('Status:', error.status) console.error('Body:', error.body) } ``` ### Common Status Codes | Status | Description | | ------ | ------------------------------------------------- | | `400` | Missing required fields (externalUserId, message) | | `401` | Invalid, missing, or revoked API key | | `403` | User is blocked | | `404` | Conversation or community not found | | `500` | Internal server error | ### Best Practices ```typescript async function sendMessage(userId: string, message: string) { try { return await client.chat({ externalUserId: userId, message }) } catch (error) { if (error.status === 401) { // Handle authentication error throw new Error('Invalid API key') } if (error.status === 403) { // Handle blocked user throw new Error('User is blocked') } // Re-throw unknown errors throw error } } ``` ## Image Attachments Send images along with your messages for visual AI understanding. ### Supported Formats * JPEG, PNG, GIF, WebP * Maximum one image per message * Public URLs or Base64-encoded data ### Using Image URLs ```typescript const response = await client.chat({ externalUserId: 'user-123', message: 'Describe this image', imageUrl: 'https://example.com/photo.jpg' }) ``` ### Using Base64 ```typescript const response = await client.chat({ externalUserId: 'user-123', message: 'What do you see?', imageBase64: 'data:image/jpeg;base64,/9j/4AAQ...' }) ``` :::info If both `imageUrl` and `imageBase64` are provided, `imageUrl` takes precedence. ::: ## Tool Calls Community AI supports custom tools that extend the AI's capabilities. ### How Tools Work When the AI needs to perform an action, it can call tools configured in your community. There are two modes: #### Webhook Mode Your endpoint receives the tool call and returns a result immediately. ```json { "toolId": "...", "name": "create_ticket", "mode": "webhook", "args": { "title": "Bug report", "priority": "high" }, "context": { "communityId": "...", "externalUserId": "user-123" } } ``` #### Ack Mode Tool call is recorded for asynchronous processing. ### Accessing Tool Calls Tool calls appear in the message history: ```typescript const history = await client.getHistory('user-123') for (const message of history.messages) { if (Array.isArray(message.content)) { for (const part of message.content) { if (part.type === 'tool-call') { console.log(`Tool: ${part.name}`, part.args) } } } } ``` ## Installation Install the Community AI SDK using your preferred package manager. ### npm ```bash npm install @anthropic/community-ai-sdk ``` ### yarn ```bash yarn add @anthropic/community-ai-sdk ``` ### pnpm ```bash pnpm add @anthropic/community-ai-sdk ``` ### bun ```bash bun add @anthropic/community-ai-sdk ``` ### Next Steps Once installed, head to the [Quick Start](/getting-started/quick-start) guide to create your first integration. ## Quick Start Get up and running with Community AI SDK in minutes. ### Prerequisites * An API key from your Community AI dashboard * Node.js 18+ or Bun runtime ### Create a Client ```typescript import { createClient } from '@anthropic/community-ai-sdk' const client = createClient({ apiKey: process.env.COMMUNITY_AI_API_KEY! }) ``` ### Send a Message ```typescript const response = await client.chat({ externalUserId: 'user-123', message: 'What can you help me with?' }) console.log(response.response) // The AI assistant's response ``` ### Retrieve History ```typescript const history = await client.getHistory('user-123') for (const message of history.messages) { console.log(`${message.role}: ${message.content}`) } ``` ### Next Steps * Learn about [Image Attachments](/guides/images) * Explore [Tool Calls](/guides/tools) * See the full [API Reference](/api/create-client) ## chat Send a message and receive an AI response. ### Usage ```typescript const response = await client.chat({ externalUserId: 'user-123', message: 'Hello, how can you help me?' }) ``` ### Parameters | Parameter | Type | Required | Description | | ---------------- | -------- | -------- | ----------------------------------------- | | `externalUserId` | `string` | Yes | Your application's user identifier | | `message` | `string` | Yes | The message text to send | | `imageUrl` | `string` | No | Public URL of an image to attach | | `imageBase64` | `string` | No | Base64-encoded image data | | `metadata` | `object` | No | Custom metadata to store with the message | ### Response ```typescript interface ChatResponse { success: true response: string // The AI assistant's reply messages: StoredMessage[] // Full conversation history } ``` ### Example with Image ```typescript const response = await client.chat({ externalUserId: 'user-123', message: 'What is in this image?', imageUrl: 'https://example.com/photo.jpg' }) ``` ## createClient Creates a new Community AI client instance. ### Usage ```typescript import { createClient } from '@anthropic/community-ai-sdk' const client = createClient({ apiKey: 'caik_your_api_key', baseUrl: 'https://mahalle.ai' // optional }) ``` ### Options | Parameter | Type | Required | Description | | --------- | -------------- | -------- | ----------------------------------------------------------------- | | `apiKey` | `string` | Yes | Your Community AI API key (starts with `caik_`) | | `baseUrl` | `string` | No | API base URL. Defaults to `https://mahalle.ai` | | `fetch` | `typeof fetch` | No | Custom fetch implementation for environments without native fetch | ### Returns Returns a `CommunityAIClient` instance with the following methods: * [`chat()`](/api/chat) * [`getHistory()`](/api/get-history) * [`listConversations()`](/api/list-conversations) * [`getConversation()`](/api/get-conversation) * [`improveSystemPrompt()`](/api/improve-system-prompt) ## getConversation Get full details of a specific conversation including all messages. ### Usage ```typescript const result = await client.getConversation('conversation-uuid') ``` ### Parameters | Parameter | Type | Required | Description | | ---------------- | -------- | -------- | ---------------------------- | | `conversationId` | `string` | Yes | The UUID of the conversation | ### Response ```typescript interface GetConversationResponse { success: true conversation: ConversationDetails } interface ConversationDetails { id: string externalUserId: string title?: string channel: string lastMessageAt: string createdAt: string messages: StoredMessage[] } ``` ### Example ```typescript const { conversation } = await client.getConversation('abc-123-def') console.log(`User: ${conversation.externalUserId}`) console.log(`Messages: ${conversation.messages.length}`) ``` ## getHistory Retrieve conversation history for a specific user. ### Usage ```typescript const history = await client.getHistory('user-123', { limit: 50 }) ``` ### Parameters | Parameter | Type | Required | Description | | ---------------- | -------- | -------- | ------------------------------------------------- | | `externalUserId` | `string` | Yes | Your application's user identifier | | `options.limit` | `number` | No | Maximum number of messages to return. Default: 50 | ### Response ```typescript interface HistoryResponse { success: true messages: StoredMessage[] } ``` ### Example ```typescript const history = await client.getHistory('user-123') for (const message of history.messages) { console.log(`[${message.role}]: ${message.content}`) } ``` ## improveSystemPrompt Use AI to refine your community's system prompt using natural language. ### Usage ```typescript const result = await client.improveSystemPrompt( 'Make the assistant more concise and friendly' ) ``` ### Parameters | Parameter | Type | Required | Description | | ------------- | -------- | -------- | -------------------------------------------------------------- | | `requestText` | `string` | Yes | Natural language description of desired changes (min 10 chars) | ### Response ```typescript interface ImprovePromptResponse { success: true systemPrompt: string // The new, improved system prompt } ``` ### Example ```typescript const { systemPrompt } = await client.improveSystemPrompt( 'Add expertise in customer support and make responses shorter' ) console.log('New prompt:', systemPrompt) ``` :::warning This method updates your community's system prompt immediately. Changes affect all future conversations. ::: ## listConversations List all conversations in your community with pagination. ### Usage ```typescript const result = await client.listConversations({ limit: 20, offset: 0 }) ``` ### Parameters | Parameter | Type | Required | Description | | ---------------- | -------- | -------- | -------------------------------------------- | | `options.limit` | `number` | No | Maximum conversations to return. Default: 50 | | `options.offset` | `number` | No | Number of conversations to skip. Default: 0 | ### Response ```typescript interface ListConversationsResponse { success: true conversations: Conversation[] } interface Conversation { id: string externalUserId: string title?: string channel: string lastMessageAt: string createdAt: string } ``` ### Example ```typescript const { conversations } = await client.listConversations({ limit: 10 }) for (const conv of conversations) { console.log(`${conv.externalUserId}: ${conv.title}`) } ```