API Reference
Complete reference for all 37 API endpoints. All /api/dashboard/* routes require Clerk authentication. Webhook routes use signature verification.
Endpoints
Authentication
All /api/dashboard/* routes require a valid Clerk session. Webhook routes verify signatures. Demo routes are public. All errors return { "error": "..." }.
Campaigns
/api/dashboard/campaignsList campaigns for the current organization.
| Param | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | 25 | Items per page (max 100) |
| status | string | all | Filter: draft, active, paused, completed, or all |
{
"campaigns": [
{
"id": "uuid",
"name": "Q1 Outreach",
"status": "draft",
"channels": ["voice", "telegram"],
"channelPriority": ["telegram", "voice", "email"],
"leadCount": 150,
"createdAt": "2025-01-15T10:00:00Z"
}
],
"pagination": { "page": 1, "limit": 25, "total": 42, "totalPages": 2 }
}/api/dashboard/campaignsCreate a new campaign. Name is required.
{
"name": "Q1 Outreach",
"scriptId": "uuid (optional)",
"channels": ["voice", "telegram", "email"],
"channelPriority": ["telegram", "voice", "email"]
}/api/dashboard/campaigns/[id]Get a single campaign with lead statistics.
/api/dashboard/campaigns/[id]Update a campaign. All fields are optional.
/api/dashboard/campaigns/[id]Delete a campaign.
/api/dashboard/campaigns/[id]/executeExecute a campaign -- process all assigned leads through configured channels.
{
"success": true,
"progress": {
"total": 50,
"processed": 50,
"succeeded": 42,
"failed": 8,
"results": [
{ "leadId": "uuid", "channel": "telegram", "status": "sent" },
{ "leadId": "uuid", "channel": "voice", "status": "failed", "error": "No answer" }
]
}
}/api/dashboard/campaigns/[id]/startSet campaign status to active.
/api/dashboard/campaigns/[id]/pauseSet campaign status to paused.
/api/dashboard/campaigns/[id]/leadsList leads assigned to a campaign.
| Param | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | 100 | Items per page |
/api/dashboard/campaigns/[id]/leadsAssign leads to a campaign.
{ "leadIds": ["uuid1", "uuid2", "uuid3"] }/api/dashboard/campaigns/[id]/leadsRemove leads from a campaign.
Leads
/api/dashboard/leadsList leads with search and filtering.
| Param | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | 25 | Items per page (max 100) |
| search | string | -- | Search across name, email, phone, company, telegram |
| status | string | all | Filter: new, contacted, qualified, converted, rejected |
{
"leads": [
{
"id": "uuid",
"firstName": "John",
"lastName": "Doe",
"phone": "+380501234567",
"email": "john@example.com",
"telegramUsername": "johndoe",
"company": "Acme Inc",
"status": "new"
}
],
"pagination": { "page": 1, "limit": 25, "total": 500, "totalPages": 20 }
}/api/dashboard/leadsCreate a single lead. At least one contact field is required.
/api/dashboard/leads/[id]Get a single lead.
/api/dashboard/leads/[id]Update a lead. All fields are optional.
/api/dashboard/leads/[id]Delete a lead.
/api/dashboard/leads/importImport leads from a CSV file. Rows without contact info are skipped.
Request: multipart/form-data with a file field containing a .csv file.
CSV columns: firstName, lastName, phone, email, telegramUsername, company, timezone
Scripts
/api/dashboard/scriptsList all scripts for the organization.
/api/dashboard/scriptsCreate a new script. Name is required.
{
"name": "Cold Call Script v2",
"content": "Full script text here...",
"objectionHandlers": [
"If they say 'too expensive': Emphasize ROI and offer a trial"
]
}/api/dashboard/scripts/[id]Get a single script.
/api/dashboard/scripts/[id]Update a script. All fields are optional.
/api/dashboard/scripts/[id]Delete a script.
Voice Configuration
/api/dashboard/voiceGet the voice configuration for the organization. Creates a default if none exists.
{
"id": "uuid",
"voiceId": "B31Kx7rXmNnYqp1QWHR2",
"selectedVoices": ["olena"],
"language": "uk",
"personality": "professional",
"speed": 1.0
}/api/dashboard/voiceUpdate voice configuration.
/api/dashboard/voice/syncSync current voice config and latest script to the Railway voice agent.
Call Logs
/api/dashboard/callsList call logs with pagination.
| Param | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | 50 | Items per page |
/api/dashboard/calls/[id]Get a single call log with full transcript.
Phone Numbers
/api/dashboard/numbersList all phone numbers for the organization.
/api/dashboard/numbersPurchase a phone number via Twilio.
{ "phoneNumber": "+14155551234", "label": "Sales Line" }/api/dashboard/numbers/availableSearch for available phone numbers to purchase.
| Param | Type | Default | Description |
|---|---|---|---|
| country | string | US | Two-letter country code |
| areaCode | string | -- | Area code to filter by |
/api/dashboard/numbers/[id]Get a single phone number.
/api/dashboard/numbers/[id]Update a phone number's label or campaign assignment.
/api/dashboard/numbers/[id]Release a phone number from Twilio and delete from database.
/api/dashboard/email/sendSend an email to a lead via Resend.
{
"leadId": "uuid",
"subject": "Quick question about your workflow",
"body": "Hi John, I wanted to reach out...",
"toEmail": "john@example.com"
}/api/dashboard/email/generateGenerate an AI-written email using OpenRouter (Gemini 2.0 Flash).
{
"leadName": "John",
"companyName": "Acme Inc",
"scriptId": "uuid (optional)",
"type": "initial | followup | final"
}/api/dashboard/email/testSend a test email to the authenticated user's email address.
/api/dashboard/email/messagesList sent email messages.
Telegram
/api/dashboard/telegram/accountsList Telegram accounts assigned to the current organization.
{
"accounts": [
{
"id": "uuid",
"phone": "+380501234567",
"username": "sales_agent_1",
"status": "active",
"dailyMessageCount": 15,
"maxDailyMessages": 30
}
]
}Billing
/api/dashboard/billing/checkoutCreate a Stripe checkout session for a subscription plan.
{ "planId": "starter | growth | enterprise" }| Plan | Amount |
|---|---|
| Starter | $40/mo |
| Growth | $99/mo |
| Enterprise | $299/mo |
/api/dashboard/billing/portalCreate a Stripe billing portal session.
/api/dashboard/billing/usageGet current month's usage statistics and plan limits.
{
"minutes": 150,
"telegramMessages": 42,
"emails": 200,
"plan": "starter",
"limits": { "minutes": 500, "telegram": 100, "emails": 500 }
}/api/dashboard/billing/liqpayCreate a LiqPay payment for Ukrainian users (UAH).
/api/dashboard/billing/payment-methodsCheck which payment methods are configured.
Analytics
/api/dashboard/analyticsComprehensive cross-channel analytics for the organization.
Returns voice stats, telegram stats, email stats, activity chart (7 days), top 5 campaigns, lead status breakdown, and recent 10 activities.
Channel Configuration
/api/dashboard/channelsList all channel configurations for the organization.
/api/dashboard/channelsCreate or update a channel configuration. Uses upsert on (org_id, channel).
{
"channel": "email",
"config": {
"fromEmail": "sales@yourdomain.com",
"fromName": "Sales Team",
"replyTo": "sales@yourdomain.com"
}
}Settings / API Keys
/api/dashboard/settings/api-keysList API keys for the organization (prefix + last4 only).
/api/dashboard/settings/api-keysGenerate a new API key. Full key is returned ONLY in this response.
{
"key": "tp_live_a1b2c3d4e5f6...",
"id": "uuid",
"name": "Production Key",
"prefix": "tp_live_a1b2",
"last4": "w3x4"
}/api/dashboard/settings/api-keys?id=uuidDelete an API key.
Webhooks
/api/webhook/stripeStripe webhook handler. Processes subscription lifecycle events.
| Event | Action |
|---|---|
| checkout.session.completed | Activate subscription, set plan |
| customer.subscription.updated | Update plan; downgrade on cancel |
| customer.subscription.deleted | Downgrade to free plan |
| invoice.payment_failed | Log error (Stripe retries) |
/api/webhook/liqpayLiqPay webhook handler. Processes payment callbacks with signature verification.
Demo
/api/demo/emailSend a demo email from the landing page. Rate limited to one per address per hour.
/api/demo/statusCheck which channels are currently available/configured.
Error Responses
All endpoints return errors in a consistent format:
{ "error": "Description of the error" }| Code | Meaning |
|---|---|
| 400 | Bad request (validation error) |
| 401 | Unauthorized (missing or invalid Clerk session) |
| 404 | Resource not found (or does not belong to this org) |
| 429 | Rate limited |
| 500 | Internal server error |
| 502 | External service error (voice agent, telegram worker) |
| 503 | Service not configured (missing API keys) |