AI agent endpoints

Agents

GET /api/ai-agents

Filters

type (analysis, caller, sms, other), llm_model_type (gpt, claude)

POST /api/ai-agents

Creates an agent and its first AiAgentVersion. For caller agents the record is mirrored to Retell AI via RetellAgentService, and retellAgentId is stored.

GET /api/ai-agents/{id}

Agent with its latest version.

PATCH /api/ai-agents/{id}

Updates the agent. Changes to a caller agent are pushed to Retell so the platform and the database do not drift.

DELETE /api/ai-agents/{id}

Deletes the agent and, for caller agents, the Retell agent.

POST /api/ai-agents/{id}/duplicate

Copies the agent and its latest version — the safe way to experiment without editing a production agent.

Versions

GET /api/ai-agents/{id}/versions

Lists versions. version selects one.

POST /api/ai-agents/{id}/versions

Publishes a new version, incrementing version and repointing AiAgent.latestVersionId. Versions are immutable, which is what lets a call be replayed against the exact prompt that produced it.

Analysis results

GET /api/ai-agents/analysis

Paginated CallAiAgentAnalysisResult rows for the workspace. page (default 1), pageSize (default 20, max 100).

Filters

aiAgentId, campaignId, hasIssues, dateFrom, dateTo

dateFrom / dateTo filter the analysis createdAt, not the call’s.

{
  "data": [
    {
      "id": "uuid",
      "call_id": "uuid",
      "call_created_at": "2026-01-01T00:00:00.000Z",
      "created_at": "2026-01-02T00:00:00.000Z",
      "target_phone_number": "+1234567890",
      "campaign_id": "uuid",
      "campaign_name": "Campaign Name",
      "ai_agent_id": "uuid",
      "ai_agent_name": "Analysis Agent",
      "agent_score": 8,
      "correct_disposition": true,
      "suggested_disposition": null,
      "summary": "…",
      "issues": []
    }
  ],
  "total": 100,
  "page": 1,
  "pageSize": 20
}

Both timestamps are returned because they answer different questions: when the conversation happened versus when it was last graded.

Issues

GET /api/ai-agents/issues

Flattens the issues arrays from every analysis result into a searchable list.

Filters

name, priority (critical, high, low), agentName, agentVersion, dateFrom, dateTo, page, pageSize

POST /api/ai-agents/issues/suggest-prompt

Runs PromptSuggestionService to propose a prompt revision that addresses the selected issue.

Test cases

GET /api/test-cases

Filters

search, disposition, hasRecording, page, limit

POST /api/test-cases

Creates a case, optionally from a sourceCallId, capturing the transcript and the ground-truth fields.

GET|PATCH|DELETE /api/test-cases/{id}

POST /api/test-cases/run

Runs cases against a caller agent version through TestCaseRunnerService.

interface TestCaseRunResult {
  testCaseId: string
  testCaseName: string | null
  recordingUrl: string | null
  passed: boolean          // true only when every evaluated field passes
  skipped: boolean         // true when the transcript is missing
  fields: Array<{
    field: string
    expected: string | boolean | null
    predicted: string | boolean | null
    pass: boolean | null   // null = ground truth not asserted, field excluded
  }>
  error?: string
}

Evaluated fields are the intersection of the post-call analysis schema and the test-case ground-truth columns: disposition, next_action, call_screening_detected, is_amazon_seller. String comparison is case-insensitive; booleans are strict.

POST /api/test-cases/suggest-prompt

Proposes a prompt revision from failing cases.

Retell voices

GET /api/retell/voices

Proxies Retell’s voice catalogue for the agent editor. Option lists for voice models, LLM models and expressive emotion tags live in lib/retellai/agent-config.ts.