Skip to main content
POST
/
v1
/
agents
curl --request POST \
  --url https://api.coval.dev/v1/agents \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '
{
  "display_name": "Customer Support Voice Agent",
  "model_type": "MODEL_TYPE_VOICE",
  "phone_number": "+12345678901",
  "prompt": "You are a helpful customer support agent...",
  "metadata": {
    "voice": "alloy",
    "model": "gpt-4o-realtime-preview"
  },
  "workflows": {
    "edges": [
      {
        "id": "edge-1",
        "source": "start",
        "target": "process-1"
      },
      {
        "id": "edge-2",
        "source": "process-1",
        "target": "end"
      }
    ],
    "nodes": [
      {
        "id": "start",
        "data": {
          "label": "Start",
          "description": "Agent is ready to handle a new call"
        },
        "type": "start",
        "position": {
          "x": 250,
          "y": 0
        }
      },
      {
        "id": "process-1",
        "data": {
          "label": "Handle Call",
          "description": "Answer, greet, and assist the customer."
        },
        "type": "process",
        "position": {
          "x": 250,
          "y": 150
        }
      },
      {
        "id": "end",
        "data": {
          "label": "End",
          "description": "Conclude the call politely."
        },
        "type": "end",
        "position": {
          "x": 250,
          "y": 300
        }
      }
    ]
  },
  "metric_ids": [
    "abc123def456ghi789jklm"
  ],
  "test_set_ids": []
}
'
{
  "agent": {
    "id": "abc123def456ghi789jklm",
    "display_name": "Customer Support Agent",
    "model_type": "MODEL_TYPE_VOICE",
    "phone_number": "+1234567890",
    "endpoint": null,
    "prompt": "You are a helpful customer support agent...",
    "metadata": {
      "voice": "alloy",
      "model": "gpt-4o-realtime-preview"
    },
    "workflows": {},
    "metric_ids": [
      "abc123def456ghi789jklm"
    ],
    "test_set_ids": [],
    "knowledge_base_ids": [],
    "create_time": "2025-10-14T12:00:00Z",
    "update_time": null
  }
}

Authorizations

x-api-key
string
header
required

API key for authentication

Body

application/json
display_name
string
required

Human-readable agent name

Required string length: 1 - 200
Example:

"Customer Support Agent"

model_type
enum<string>
required

Agent type. Active types that can be created via the v1 API:

  • MODEL_TYPE_VOICE: Inbound voice calls (requires phone_number in E.164 format or SIP address)
  • MODEL_TYPE_OUTBOUND_VOICE: Outbound voice calls (requires endpoint webhook URL)
  • MODEL_TYPE_CHAT: Text-based chat agents (requires metadata.chat_endpoint)
  • MODEL_TYPE_CHAT_A2A: A2A JSON-RPC chat agents (requires metadata.chat_endpoint)
  • MODEL_TYPE_CHAT_WEBSOCKET: Text chat over WebSocket (requires metadata.endpoint in direct mode)
  • MODEL_TYPE_SMS: SMS messaging agents (requires phone_number in E.164 format)
  • MODEL_TYPE_WEBSOCKET: WebSocket voice agents (requires metadata.endpoint wss:// URL in direct mode; metadata.initialization_json is optional)
  • MODEL_TYPE_OPENAI_REALTIME: OpenAI Realtime voice-to-voice agents
  • MODEL_TYPE_GEMINI_REALTIME: Gemini Live voice-to-voice agents
Available options:
MODEL_TYPE_VOICE,
MODEL_TYPE_OUTBOUND_VOICE,
MODEL_TYPE_CHAT,
MODEL_TYPE_CHAT_A2A,
MODEL_TYPE_CHAT_WEBSOCKET,
MODEL_TYPE_SMS,
MODEL_TYPE_WEBSOCKET,
MODEL_TYPE_OPENAI_REALTIME,
MODEL_TYPE_GEMINI_REALTIME
Example:

"MODEL_TYPE_VOICE"

phone_number
string | null

Phone number in E.164 format (e.g., +12345678901) or SIP address (e.g., sip:user@domain.com).

Required for:

  • MODEL_TYPE_VOICE agents (E.164 or SIP)
  • MODEL_TYPE_SMS agents (E.164 only)

Optional for other agent types.

Maximum string length: 200
Example:

"+12345678901"

endpoint
string | null

Webhook endpoint URL that Coval will POST to.

Required for MODEL_TYPE_OUTBOUND_VOICE agents. Must be a valid HTTP/HTTPS URL.

Maximum string length: 200
Example:

"https://api.yourcompany.com/triggers/voice-simulation"

prompt
string | null

Agent instructions/system prompt

Maximum string length: 50000
Example:

"You are a helpful customer support agent..."

metadata
object

Simulator-specific configuration (JSONB, max 10MB).

For CHAT agents:

Required:

  • chat_endpoint - Chat endpoint URL (validated, no private IPs/localhost)

Authentication:

  • authorization_header - Auth header (Bearer, X-API-Key, etc.)

Initialization:

  • initialization_endpoint - Init endpoint called before chat (validated URL)
  • initialization_payload - JSON payload for init request (max 16KB)

Custom Data:

  • custom_data - Organization/agent-level data (max 32KB JSON string)
  • custom_persona_data - Persona-specific data (max 16KB JSON string)

Headers & Format:

  • custom_headers - Additional headers with template variables, as a JSON object or JSON-encoded object string (max 16KB when encoded)
  • response_format - "chat_completions" (default) or "responses"

Request/Response Processing:

  • input_template - Custom JSON template for requests (validated JSON)
  • payload_wrapper - Wrapper field name (e.g., "data", "request")
  • response_message_path - Dot notation path to extract message
  • strip_message_timestamps - Remove timestamp fields (boolean, default: false)

Tool Calls:

  • tool_call_extraction_config - Configuration for extracting tool calls from custom responses

Dynamic Configuration:

  • persona_id - Reference persona for parameter substitution (22-char ShortUUID)

Template Variables: {{sessionId}}, {{simulation_output_id}}, {{init_response.path}}, {{persona.field}}, {{messages}}, {{latest_message}}, {{custom_data.field}}

For OUTBOUND_VOICE agents:

  • trigger_call_headers - JSON string with HTTP headers
  • trigger_call_payload - JSON string with base payload
  • phone_number_key - Field name for phone number (default: "phone_number")

For WEBSOCKET agents:

Required:

  • endpoint - WebSocket endpoint URL (must be wss://, validated). Required in direct connection mode.

Connection mode:

  • connection_mode - direct (default) or http_first. In http_first mode Coval issues an HTTP request first and dials the WebSocket URL returned in the response.
  • http_url, http_method, http_request_body, http_headers, websocket_url_response_path - HTTP-first setup fields when connection_mode=http_first.

Authentication (optional):

  • authorization_header - Auth header sent during the WebSocket handshake. Supports:
    • "Bearer <token>" → sent as Authorization: Bearer <token>
    • "Basic <base64-credentials>" → sent as Authorization: Basic <base64-credentials>
    • "X-API-Key <key>" → sent as X-API-Key: <key>
  • custom_headers - JSON object or JSON-encoded object string of additional HTTP headers for the WebSocket handshake.

Initialization & handshake (optional):

  • initialization_json - JSON object or JSON string payload sent after the WebSocket upgrade and before any ready-message wait.
  • handshake_ready_message_type - Message type to wait for before streaming audio (default session_ready in direct mode and empty in http_first; empty string skips the ready-message wait).
  • handshake_requires_session_id - Whether the ready message must include session_id (default true in direct mode and false in http_first).
  • handshake_timeout_seconds - Seconds Coval waits for the ready message (default 30).

Audio format (optional):

  • send_audio_template - JSON template for outbound audio. Must contain {{audio_data}}. Setting it exactly to {{audio_data}} sends raw PCM bytes (default {"type":"audio_chunk","data":"{{audio_data}}"}).
  • message_type_path - Dot-notation path to the field naming the inbound message kind (default type).
  • audio_message_type_value - Value identifying an audio frame; use * to treat every JSON message as audio (default audio_chunk).
  • audio_data_path - Dot-notation path to the inbound base64 audio payload (default data).
  • audio_encoding - Inbound JSON audio payload encoding: pcm (default) or mp3.
  • receive_audio_channels - 1 for mono inbound JSON PCM or 2 for legacy stereo-to-mono averaging (default 2).
  • send_sample_rate_hertz - Outbound sample rate. One of 8000, 16000, 24000, 48000 (default 16000).
  • receive_sample_rate_hertz - Inbound sample rate. One of 8000, 16000, 24000, 48000 (default 48000).
  • pipeline_sample_rate_hertz - Pipeline-internal rate; must remain 16000.
  • pace_inbound_binary_audio - Boolean, paces inbound binary PCM at real-time. Defaults on when outbound audio is configured for raw PCM bytes, off for JSON templates.
  • send_media_template - Outbound template for image attachments. Must contain {{media_data}}; may also include {{media_name}} and {{mime_type}}. Set exactly to {{media_data}} to send raw bytes, otherwise Coval base64-encodes the image into the JSON template.

Non-audio event capture (optional):

  • non_audio_event_message_types - List of message-type values to emit as WebsocketEventFrames instead of dropping. Each match carries the message type, optional event name, and original payload. Useful for cart updates, transcript fragments, or session telemetry.

Compatibility profile (optional):

  • websocket_compat_profile - One of generic or json_audio. Forces the simulator routing decision. Use json_audio for the JSON audio preset shape.
Example:
{
"chat_endpoint": "https://api.example.com/v1/chat",
"authorization_header": "Bearer sk-xxx"
}
workflows
object

Workflow configuration (JSONB, max 10MB)

Example:
{}
metric_ids
string[]

Associated metric IDs (22-char IDs)

Pattern: ^[A-Za-z0-9]{22}$
Example:
["abc123def456ghi789jklm"]
test_set_ids
string[]

Associated test set IDs (8-char IDs)

Pattern: ^[A-Za-z0-9]{8}$
Example:
["gT5wq2Hn"]
tags
string[] | null

Tags to associate with this agent. Null or omitted creates the agent with no tags. Pass [] for an empty tag list.

Example:
["production", "voice"]

Response

Agent created successfully

agent
object
required

Agent configuration resource.

Note: The active field (soft delete status) is managed internally and not exposed in API responses.