curl --request POST \
--url https://api.coval.dev/v1/personas \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"name": "Friendly Spanish Customer",
"persona_prompt": "You are a friendly Spanish-speaking customer calling for technical support...",
"voice_name": "marina",
"language_code": "es-ES",
"background_sound": "office",
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM"
}
'import requests
url = "https://api.coval.dev/v1/personas"
payload = {
"name": "Friendly Spanish Customer",
"persona_prompt": "You are a friendly Spanish-speaking customer calling for technical support...",
"voice_name": "marina",
"language_code": "es-ES",
"background_sound": "office",
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Friendly Spanish Customer',
persona_prompt: 'You are a friendly Spanish-speaking customer calling for technical support...',
voice_name: 'marina',
language_code: 'es-ES',
background_sound: 'office',
wait_seconds: 0.5,
conversation_initiation: 'speak_first',
interruption_rate: 'MEDIUM'
})
};
fetch('https://api.coval.dev/v1/personas', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.coval.dev/v1/personas",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Friendly Spanish Customer',
'persona_prompt' => 'You are a friendly Spanish-speaking customer calling for technical support...',
'voice_name' => 'marina',
'language_code' => 'es-ES',
'background_sound' => 'office',
'wait_seconds' => 0.5,
'conversation_initiation' => 'speak_first',
'interruption_rate' => 'MEDIUM'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.coval.dev/v1/personas"
payload := strings.NewReader("{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.coval.dev/v1/personas")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.coval.dev/v1/personas")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}"
response = http.request(request)
puts response.read_body{
"persona": {
"created_at": "2023-11-07T05:31:56Z",
"created_by": "<string>",
"updated_at": "2023-11-07T05:31:56Z",
"updated_by": "<string>",
"resource_name": "personas/3zfmuDbVQsi4GaseDtiVcS",
"id": "3zfmuDbVQsi4GaseDtiVcS",
"name": "Friendly Customer",
"create_time": "2025-01-24T10:00:00Z",
"silent_mode": true,
"multi_phone_config": {
"phone_number_index": 2,
"phone_number_name": "<string>"
},
"initialization_parameters": {},
"custom_persona_data": "<string>",
"voice": "alloy",
"custom_voice_id": "<string>",
"persona_prompt": "You are a friendly customer calling for technical support...",
"voice_name": "aria",
"language_code": "en-US",
"background_sound": "office",
"background_sound_volume": 0.3,
"voice_volume": 1.25,
"voice_speed": 0.85,
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM",
"multi_language_stt": true,
"hold_music_timeout_seconds": 15,
"situate_speaker": "speakerphone-hard",
"audio_degradation": {
"preset": "cell-poor",
"preset_version": 1
},
"tags": [
"voice",
"english"
],
"update_time": "2025-01-24T12:30:00Z"
}
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "Invalid language_code 'en-ZZ'"
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "Missing or invalid API key"
}
}{
"error": {
"code": "INTERNAL",
"message": "An unexpected error occurred"
}
}Create persona
Create a new simulated persona with specified voice characteristics and behavior configuration.
curl --request POST \
--url https://api.coval.dev/v1/personas \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"name": "Friendly Spanish Customer",
"persona_prompt": "You are a friendly Spanish-speaking customer calling for technical support...",
"voice_name": "marina",
"language_code": "es-ES",
"background_sound": "office",
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM"
}
'import requests
url = "https://api.coval.dev/v1/personas"
payload = {
"name": "Friendly Spanish Customer",
"persona_prompt": "You are a friendly Spanish-speaking customer calling for technical support...",
"voice_name": "marina",
"language_code": "es-ES",
"background_sound": "office",
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Friendly Spanish Customer',
persona_prompt: 'You are a friendly Spanish-speaking customer calling for technical support...',
voice_name: 'marina',
language_code: 'es-ES',
background_sound: 'office',
wait_seconds: 0.5,
conversation_initiation: 'speak_first',
interruption_rate: 'MEDIUM'
})
};
fetch('https://api.coval.dev/v1/personas', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.coval.dev/v1/personas",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Friendly Spanish Customer',
'persona_prompt' => 'You are a friendly Spanish-speaking customer calling for technical support...',
'voice_name' => 'marina',
'language_code' => 'es-ES',
'background_sound' => 'office',
'wait_seconds' => 0.5,
'conversation_initiation' => 'speak_first',
'interruption_rate' => 'MEDIUM'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.coval.dev/v1/personas"
payload := strings.NewReader("{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.coval.dev/v1/personas")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.coval.dev/v1/personas")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Friendly Spanish Customer\",\n \"persona_prompt\": \"You are a friendly Spanish-speaking customer calling for technical support...\",\n \"voice_name\": \"marina\",\n \"language_code\": \"es-ES\",\n \"background_sound\": \"office\",\n \"wait_seconds\": 0.5,\n \"conversation_initiation\": \"speak_first\",\n \"interruption_rate\": \"MEDIUM\"\n}"
response = http.request(request)
puts response.read_body{
"persona": {
"created_at": "2023-11-07T05:31:56Z",
"created_by": "<string>",
"updated_at": "2023-11-07T05:31:56Z",
"updated_by": "<string>",
"resource_name": "personas/3zfmuDbVQsi4GaseDtiVcS",
"id": "3zfmuDbVQsi4GaseDtiVcS",
"name": "Friendly Customer",
"create_time": "2025-01-24T10:00:00Z",
"silent_mode": true,
"multi_phone_config": {
"phone_number_index": 2,
"phone_number_name": "<string>"
},
"initialization_parameters": {},
"custom_persona_data": "<string>",
"voice": "alloy",
"custom_voice_id": "<string>",
"persona_prompt": "You are a friendly customer calling for technical support...",
"voice_name": "aria",
"language_code": "en-US",
"background_sound": "office",
"background_sound_volume": 0.3,
"voice_volume": 1.25,
"voice_speed": 0.85,
"wait_seconds": 0.5,
"conversation_initiation": "speak_first",
"interruption_rate": "MEDIUM",
"multi_language_stt": true,
"hold_music_timeout_seconds": 15,
"situate_speaker": "speakerphone-hard",
"audio_degradation": {
"preset": "cell-poor",
"preset_version": 1
},
"tags": [
"voice",
"english"
],
"update_time": "2025-01-24T12:30:00Z"
}
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "Invalid language_code 'en-ZZ'"
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "Missing or invalid API key"
}
}{
"error": {
"code": "INTERNAL",
"message": "An unexpected error occurred"
}
}Authorizations
API key for authentication
Headers
Workspace that scopes this operation. When omitted, the organization's active default workspace is used when one can be resolved.
1 - 26Body
- Silent persona
- Persona with prompt
Keep the persona silent for the whole simulation. Null clears the override.
true Human-readable persona name
1 - 200"Friendly Customer"
Coval voice name. Use GET /personas/voices to discover available voices and their supported language codes.
"aria"
BCP-47 language code for voice synthesis. Must be supported by the selected voice. Use GET /personas/voices to discover valid voice and language combinations.
"en-US"
Caller number selection from GET /v1/personas/phone-numbers. Omit to let the simulation select a random available number. Null clears it.
Show child attributes
Show child attributes
Persona-level initialization parameters. Null clears; an empty object replaces existing parameters. String values substitute into the initialization payload as JSON-escaped text (quote the "{{persona.key}}" placeholder); all other JSON values substitute as their JSON encoding.
Additional serialized JSON object sent as the chat request's customPersonaData, overriding the agent-level customPersonaData. Included only when the HTTP text agent does not configure input_template; a template-configured agent shapes its own request and does not receive it. Must parse as a JSON object and stay under 16 KiB. Null clears it.
16383Agent voice override for OpenAI Realtime endpoint simulations. Null clears it.
alloy, ash, ballad, coral, echo, marin, sage, shimmer, verse Server-issued custom voice reference belonging to this organization. Null selects the built-in voice again.
1Instructions describing persona behavior and personality. Required unless silent_mode is true.
"You are a friendly customer calling for support..."
Built-in background sound id, or custom:<background_sound_id> for an active custom sound returned by GET /personas/background-sounds.
100^(off|office|lounge|crowd|airport|bus|playground|doorbell|train-arrival|portable-air-conditioner|skatepark|small-dog-bark|cafe|ferry-and-announcement|heavy-rain|moderate-wind|newborn-baby-crying|office-with-alarm|street-with-sirens|construction-work|backchanneling|custom:[A-Za-z0-9_-]+)$"office"
Volume level for background sound (>= 0.0, no upper limit). Default is provider-controlled when omitted.
x >= 00.3
Voice gain multiplier. 0.0 is silent, 1.0 is unchanged, and 2.0 is double volume.
0 <= x <= 21.25
Voice speed multiplier accepted and stored from 0.25 to 2.0. 1.0 is unchanged. The selected voice may enforce a narrower effective range or ignore speed changes.
0.25 <= x <= 20.85
Response delay in seconds
0.1 <= x <= 20.5
Who initiates the conversation
speak_first, wait_for_user "speak_first"
How often the persona interrupts the agent. While the agent is speaking, the persona forces a new turn once about 90 seconds (LOW), 45 seconds (MEDIUM), or 30 seconds (HIGH) have passed since the call started or since its last interruption. NONE never interrupts. This is a timer, not a semantic barge-in.
NONE, LOW, MEDIUM, HIGH "MEDIUM"
Enable multilingual speech-to-text so callers speaking languages other than the primary language_code are still transcribed accurately.
true
Disconnect after this many seconds of no speech (5-300)
5 <= x <= 300Persona placement preset.
- speakerphone-easy: User speaking from a distance from the microphone
- speakerphone-hard: User speaking from a distance from the microphone in an acoustically challenging environment.
speakerphone-easy, speakerphone-hard Channel degradation preset.
Show child attributes
Show child attributes
Tags to associate with this persona. Null or omitted creates the persona with no tags. Pass [] for an empty tag list.
20200\S["voice", "english"]
Response
Persona created successfully
Persona resource representation returned by API responses.
Show child attributes
Show child attributes
Was this page helpful?