API Reference
The Karnyx REST API provides programmatic access to meetings, transcripts, action items, search, webhooks, and bot management. All endpoints return JSON and require JWT authentication unless marked as public.
Base URL
https://api.karnyx.ai/v1
# Development
http://localhost:3001All API paths in this reference are relative to the base URL. For local development, the API runs on port 3001 by default. Interactive API documentation is available at /api/docs (Swagger UI).
Authentication
All API requests (except public endpoints like health checks and status) require a valid JWT Bearer token in the Authorization header.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Obtaining a Token
POST /auth/login
Content-Type: application/json
{
"email": "user@company.com",
"password": "your-password"
}
// Response 200
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "clx...",
"email": "user@company.com",
"name": "Jane Doe",
"role": "OWNER",
"organizationId": "clx..."
}
}SSO Authentication
/auth/sso/authorize endpoint instead. See the Admin Guide for SSO setup details.Rate Limits
| Scope | Limit | Window |
|---|---|---|
| Global (all endpoints) | 100 requests | 1 minute |
| Auth endpoints (/auth/*) | 5 requests | 1 minute |
| Search (POST /search) | 30 requests | 1 minute |
When a rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating seconds until the next request can be made.
Meetings
Meetings are the core resource in Karnyx. Each meeting contains metadata, participants, transcripts, notes, action items, and AI-generated summaries.
List Meetings
GET /meetings?limit=20&offset=0&status=completed
// Response 200
{
"data": [
{
"id": "clx...",
"title": "Weekly Product Sync",
"startTime": "2026-02-22T14:00:00Z",
"endTime": "2026-02-22T14:45:00Z",
"status": "COMPLETED",
"participantCount": 4,
"hasTranscript": true,
"hasSummary": true,
"visibility": "ORG"
}
],
"total": 156,
"limit": 20,
"offset": 0
}Get Meeting Detail
GET /meetings/clx.../
// Response 200
{
"data": {
"id": "clx...",
"title": "Weekly Product Sync",
"startTime": "2026-02-22T14:00:00Z",
"endTime": "2026-02-22T14:45:00Z",
"status": "COMPLETED",
"visibility": "ORG",
"participants": [...],
"summary": { "overview": "...", "decisions": [...], "topics": [...] },
"actionItemCount": 3,
"noteCount": 5
}
}Get Upcoming & Recent
GET /meetings/upcoming // Next 7 days from calendar
GET /meetings/recent // Last 10 completed meetingsAction Items
List Action Items
GET /action-items?status=pending&assignee=me&limit=20
// Response 200
{
"data": [
{
"id": "clx...",
"title": "Draft PRD for calendar sync feature",
"status": "PENDING",
"priority": "HIGH",
"dueDate": "2026-02-28T00:00:00Z",
"assigneeId": "clx...",
"meetingId": "clx...",
"source": "AI",
"createdAt": "2026-02-22T14:45:00Z"
}
],
"total": 42
}Toggle Status
PUT /action-items/clx.../toggle
// Response 200
{
"data": {
"id": "clx...",
"status": "COMPLETED", // toggled from PENDING → COMPLETED
"completedAt": "2026-02-22T16:30:00Z"
}
}Bulk Status Update
PUT /action-items/bulk-status
Content-Type: application/json
{
"ids": ["clx...", "clx...", "clx..."],
"status": "COMPLETED"
}
// Response 200
{ "updated": 3 }Search
Full-text search across meetings, transcripts, notes, action items, and participants. Supports both keyword and semantic (vector) search.
POST /search
Content-Type: application/json
{
"query": "Q1 roadmap priorities",
"types": ["meeting", "transcript", "action_item"],
"limit": 20,
"dateFrom": "2026-01-01T00:00:00Z",
"dateTo": "2026-02-28T23:59:59Z"
}
// Response 200
{
"results": {
"meetings": [{ "id": "...", "title": "...", "score": 0.92 }],
"transcripts": [{ "meetingId": "...", "text": "...", "score": 0.87 }],
"actionItems": [{ "id": "...", "title": "...", "score": 0.84 }]
},
"total": 15
}Bot Mode
Deploy meeting bots to Zoom, Google Meet, and Microsoft Teams via the Recall.ai integration.
Deploy a Bot
POST /bot/deploy
Content-Type: application/json
{
"meetingUrl": "https://zoom.us/j/1234567890",
"botName": "Karnyx Note Taker",
"meetingId": "clx..." // optional: link to existing meeting
}
// Response 201
{
"data": {
"id": "bot_...",
"platform": "ZOOM",
"status": "JOINING",
"meetingUrl": "https://zoom.us/j/1234567890",
"createdAt": "2026-02-22T14:00:00Z"
}
}Get Bot Status
GET /bot/bot_.../status
// Response 200
{
"data": {
"id": "bot_...",
"status": "IN_MEETING", // JOINING | IN_MEETING | PROCESSING | DONE | ERROR
"platform": "ZOOM",
"joinedAt": "2026-02-22T14:00:15Z",
"participantCount": 4
}
}Get Bot Transcript
GET /bot/bot_.../transcript
// Response 200
{
"data": [
{
"speaker": "Jane Doe",
"text": "Let's review the Q1 priorities...",
"startTime": 0.0,
"endTime": 3.5
}
]
}Webhooks
Manage outgoing webhook subscriptions. See the Webhooks & Zapier guide for detailed setup instructions.
POST /webhooks
Content-Type: application/json
{
"url": "https://hooks.zapier.com/hooks/catch/123456/abcdef",
"events": ["meeting.completed", "action_item.created"],
"name": "Zapier Integration",
"active": true
}
// Response 201
{
"data": {
"id": "wh_...",
"url": "https://hooks.zapier.com/...",
"events": ["meeting.completed", "action_item.created"],
"secret": "whsec_...", // Use this to verify HMAC signatures
"active": true
}
}Error Handling
All errors follow a consistent JSON format with a status code, message, and optional error type.
// 400 Bad Request
{
"statusCode": 400,
"message": ["title must be a string", "email must be an email"],
"error": "Bad Request"
}
// 401 Unauthorized
{
"statusCode": 401,
"message": "Unauthorized"
}
// 403 Forbidden
{
"statusCode": 403,
"message": "Insufficient permissions. Required role: ADMIN"
}
// 404 Not Found
{
"statusCode": 404,
"message": "Meeting with ID "clx..." not found"
}
// 429 Too Many Requests
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests"
}Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created — resource successfully created |
| 204 | No Content — successful deletion |
| 400 | Bad Request — validation errors in request body |
| 401 | Unauthorized — missing or invalid JWT token |
| 402 | Payment Required — usage limit exceeded for your plan |
| 403 | Forbidden — insufficient role or meeting access denied |
| 404 | Not Found — resource does not exist or is not in your org |
| 429 | Too Many Requests — rate limit exceeded |
| 500 | Internal Server Error — unexpected server failure (reported to Sentry) |
WebSocket API
Karnyx provides a Socket.io WebSocket for real-time features including live transcript streaming, capture control, participant presence, and audio level visualization.
import { io } from "socket.io-client";
const socket = io("wss://api.karnyx.ai", {
auth: { token: "your-jwt-token" },
transports: ["websocket"],
});
// Join a meeting room
socket.emit("meeting:join", { meetingId: "clx..." });
// Listen for live transcript segments
socket.on("transcript:segment", (segment) => {
console.log(segment.speaker, segment.text);
});
// Listen for capture status changes
socket.on("capture:status", (status) => {
console.log(status.state); // "recording" | "paused" | "stopped"
});WebSocket Authentication
auth object during connection. Connections without a valid token are immediately rejected.Interactive API Explorer
A full interactive Swagger UI is available in development at http://localhost:3001/api/docs. It provides complete endpoint documentation, request/response schemas, and a try-it-out feature for testing API calls directly from the browser.
Production Access