Masheev API
Server-side API for managing contacts, conversations, messages, inboxes, AI agents, and more. The API uses tRPC — install @masheev/client for type-safe access.
Quick Start
npm install @masheev/client
Server-Side (Node.js / API Routes)
import { apiClient, authClient } from "@masheev/client/server";
// List conversations
const conversations = await apiClient.conversations.list.query({
status: "open",
limit: 20,
});
// Send a message
await apiClient.messages.create.mutate({
conversationId: "conv_...",
role: "agent",
content: "Thanks for reaching out! Let me help with that.",
});
React (Client-Side)
import { apiClient, authClient } from "@masheev/client/react";
function ConversationList() {
const { data } = apiClient.conversations.list.useQuery({ status: "open" });
return data?.map((c) => <div key={c.id}>{c.subject}</div>);
}
Next.js (TanStack Start)
import { apiClient } from "@masheev/client/tanstack";
React Native
import { apiClient } from "@masheev/client/native";
Authentication
The API uses session-based authentication via Better Auth. For server-to-server integrations, use API keys:
// API key in Authorization header
fetch("https://api.masheev.com/api/...", {
headers: {
Authorization: "Bearer YOUR_API_KEY",
},
});
Generate API keys in the Masheev dashboard: Settings > Developers > API Keys
API Reference
Each domain is a separate reference file with full endpoint details, input schemas, and response types.
| Domain |
Endpoints |
Reference |
| Contacts |
list, get, create, update, merge, GDPR delete |
references/contacts.md |
| Conversations |
list, get, update, batchUpdate, archive |
references/conversations.md |
| Messages |
list, get, create |
references/messages.md |
| Inboxes |
list, get, create, update, delete |
references/inboxes.md |
| AI Agents |
list, get, create, update, delete |
references/ai-agents.md |
| Webhooks |
list, create, update, delete, test, regenerateSecret |
See masheev-webhooks skill |
| Knowledge |
list, create, sync, delete, search |
references/knowledge.md |
| Automations |
list, get, create, update, delete, activate |
references/automations.md |
| Billing |
plans, balance, budget, topup, invoices |
references/billing.md |
| Organization |
list, get, update, inviteUser, removeUser |
references/org.md |
Data Model
Key Entities
| Entity |
ID Prefix |
Description |
| Organization |
org_ |
Your account / workspace |
| Inbox |
inb_ |
A channel endpoint (chat, WhatsApp, email, etc.) |
| Contact |
con_ |
A customer or visitor |
| Conversation |
conv_ |
A thread between a contact and your team/AI |
| Message |
msg_ |
A single message within a conversation |
| AI Agent |
aia_ |
An AI agent configuration |
| Webhook |
wh_ |
A webhook subscription |
Common Enums
type Channel = "voice" | "sms" | "whatsapp" | "chat" | "email" | "instagram" | "google_reviews";
type ConversationStatus = "open" | "pending" | "snoozed" | "resolved";
type Priority = "low" | "medium" | "high" | "urgent";
type MessageRole = "contact" | "ai" | "agent" | "system";
type MessageStatus = "pending" | "sent" | "delivered" | "read" | "failed";
type AssigneeType = "ai" | "agent" | "unassigned";
Common Patterns
Pagination
// Cursor-based pagination
let cursor: string | undefined;
const allContacts = [];
do {
const page = await apiClient.contacts.list.query({
limit: 100,
cursor,
});
allContacts.push(...page.items);
cursor = page.nextCursor;
} while (cursor);
Rate Limiting
The API enforces rate limits per IP and per user. When rate-limited, you receive a 429 response.
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error: any) {
if (error.data?.httpStatus === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new Error("Max retries exceeded");
}
Error Handling
tRPC errors include structured data:
try {
await apiClient.contacts.create.mutate({ ... });
} catch (error) {
if (error instanceof TRPCClientError) {
console.error(error.message); // Human-readable message
console.error(error.data?.code); // "NOT_FOUND", "FORBIDDEN", etc.
console.error(error.data?.zodError); // Validation errors (if input was invalid)
}
}
1---2name: masheev-api3description: Use when calling the Masheev API for contacts, conversations, messages, inboxes, AI agents, knowledge base, or any server-to-server integration. Covers authentication with API keys, the @masheev/client tRPC client, REST endpoints, pagination, rate limiting, and common CRUD operations. Use this skill whenever someone asks to "call the Masheev API", "create contacts", "list conversations", "send messages", "manage inboxes", or integrate Masheev into their backend. Also use when setting up @masheev/client in Node.js, React, Next.js, or React Native.4license: Apache-2.05---67# Masheev API89Server-side API for managing contacts, conversations, messages, inboxes, AI agents, and more. The API uses tRPC — install `@masheev/client` for type-safe access.1011## Quick Start1213```bash14npm install @masheev/client15```1617### Server-Side (Node.js / API Routes)1819```typescript20import { apiClient, authClient } from "@masheev/client/server";2122// List conversations23const conversations = await apiClient.conversations.list.query({24 status: "open",25 limit: 20,26});2728// Send a message29await apiClient.messages.create.mutate({30 conversationId: "conv_...",31 role: "agent",32 content: "Thanks for reaching out! Let me help with that.",33});34```3536### React (Client-Side)3738```typescript39import { apiClient, authClient } from "@masheev/client/react";4041function ConversationList() {42 const { data } = apiClient.conversations.list.useQuery({ status: "open" });43 return data?.map((c) => <div key={c.id}>{c.subject}</div>);44}45```4647### Next.js (TanStack Start)4849```typescript50import { apiClient } from "@masheev/client/tanstack";51```5253### React Native5455```typescript56import { apiClient } from "@masheev/client/native";57```5859## Authentication6061The API uses session-based authentication via Better Auth. For server-to-server integrations, use API keys:6263```typescript64// API key in Authorization header65fetch("https://api.masheev.com/api/...", {66 headers: {67 Authorization: "Bearer YOUR_API_KEY",68 },69});70```7172Generate API keys in the Masheev dashboard: **Settings > Developers > API Keys**7374## API Reference7576Each domain is a separate reference file with full endpoint details, input schemas, and response types.7778| Domain | Endpoints | Reference |79|--------|-----------|-----------|80| Contacts | list, get, create, update, merge, GDPR delete | [references/contacts.md](./references/contacts.md) |81| Conversations | list, get, update, batchUpdate, archive | [references/conversations.md](./references/conversations.md) |82| Messages | list, get, create | [references/messages.md](./references/messages.md) |83| Inboxes | list, get, create, update, delete | [references/inboxes.md](./references/inboxes.md) |84| AI Agents | list, get, create, update, delete | [references/ai-agents.md](./references/ai-agents.md) |85| Webhooks | list, create, update, delete, test, regenerateSecret | See masheev-webhooks skill |86| Knowledge | list, create, sync, delete, search | [references/knowledge.md](./references/knowledge.md) |87| Automations | list, get, create, update, delete, activate | [references/automations.md](./references/automations.md) |88| Billing | plans, balance, budget, topup, invoices | [references/billing.md](./references/billing.md) |89| Organization | list, get, update, inviteUser, removeUser | [references/org.md](./references/org.md) |9091## Data Model9293### Key Entities9495| Entity | ID Prefix | Description |96|--------|-----------|-------------|97| Organization | `org_` | Your account / workspace |98| Inbox | `inb_` | A channel endpoint (chat, WhatsApp, email, etc.) |99| Contact | `con_` | A customer or visitor |100| Conversation | `conv_` | A thread between a contact and your team/AI |101| Message | `msg_` | A single message within a conversation |102| AI Agent | `aia_` | An AI agent configuration |103| Webhook | `wh_` | A webhook subscription |104105### Common Enums106107```typescript108type Channel = "voice" | "sms" | "whatsapp" | "chat" | "email" | "instagram" | "google_reviews";109type ConversationStatus = "open" | "pending" | "snoozed" | "resolved";110type Priority = "low" | "medium" | "high" | "urgent";111type MessageRole = "contact" | "ai" | "agent" | "system";112type MessageStatus = "pending" | "sent" | "delivered" | "read" | "failed";113type AssigneeType = "ai" | "agent" | "unassigned";114```115116## Common Patterns117118### Pagination119120```typescript121// Cursor-based pagination122let cursor: string | undefined;123const allContacts = [];124125do {126 const page = await apiClient.contacts.list.query({127 limit: 100,128 cursor,129 });130 allContacts.push(...page.items);131 cursor = page.nextCursor;132} while (cursor);133```134135### Rate Limiting136137The API enforces rate limits per IP and per user. When rate-limited, you receive a 429 response.138139```typescript140async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {141 for (let attempt = 0; attempt < maxRetries; attempt++) {142 try {143 return await fn();144 } catch (error: any) {145 if (error.data?.httpStatus === 429 && attempt < maxRetries - 1) {146 const delay = Math.pow(2, attempt) * 1000; // Exponential backoff147 await new Promise((r) => setTimeout(r, delay));148 continue;149 }150 throw error;151 }152 }153 throw new Error("Max retries exceeded");154}155```156157### Error Handling158159tRPC errors include structured data:160161```typescript162try {163 await apiClient.contacts.create.mutate({ ... });164} catch (error) {165 if (error instanceof TRPCClientError) {166 console.error(error.message); // Human-readable message167 console.error(error.data?.code); // "NOT_FOUND", "FORBIDDEN", etc.168 console.error(error.data?.zodError); // Validation errors (if input was invalid)169 }170}171```