Skip to main content
POST
/
v1
/
conversations:submit
curl --request POST \ --url https://api.coval.dev/v1/conversations:submit \ --header 'Content-Type: application/json' \ --header 'X-API-Key: <api-key>' \ --data @- <<EOF { "transcript": [ { "role": "user", "content": "Hi, I'd like to check my account balance" }, { "role": "assistant", "content": "I can help you with that. Let me pull up your account." }, { "role": "assistant", "content": "Your current balance is $1,247.53" }, { "role": "user", "content": "Thank you!" } ], "external_conversation_id": "external-call-7x8z9a", "occurred_at": "2025-11-03T14:32:00Z", "metadata": { "campaign": "q4-support", "channel": "phone", "customer_tier": "premium" } } EOF
{ "conversation": { "name": "conversations/gk3jK9mPq2xRt5vW8yZaBc", "conversation_id": "gk3jK9mPq2xRt5vW8yZaBc", "status": "PENDING", "create_time": "2025-11-03T14:32:30Z", "external_conversation_id": "external-call-7x8z9a", "occurred_at": "2025-11-03T14:32:00Z", "has_audio": true, "agent_id": null, "persona_id": null, "metadata": { "campaign": "q4-support", "channel": "phone", "customer_tier": "premium" } } }

Authorizations

X-API-Key
string
header
required

API key for authentication.

Body

application/json

Request to submit a conversation for monitoring evaluation.

Requirements:

  • At least one of: transcript, audio_url, or upload_id must be provided
  • audio_url and upload_id are mutually exclusive

Payload Size Limit: The combined queued payload is subject to a 256 KB limit (including large metadata values); oversized payloads return 413 PAYLOAD_TOO_LARGE.

Best Practices:

  • Provide both transcript and audio_url (or upload_id) when available (enables audio metrics)
  • Include start_time and end_time in transcript messages when submitting audio_url to avoid automatic retranscription
  • Include external_conversation_id for correlation with external systems
  • Add metadata for conditional metrics and analytics

Audio + Transcript Behavior:

  • If you submit both transcript and audio_url:
    • WITH timing (start_time/end_time on each message): Transcript is used as-is, audio metrics computed from timing
    • WITHOUT timing: Audio is automatically transcribed and diarized, provided transcript is ignored for metrics
transcript
object[]

Conversation transcript as array of messages

Minimum array length: 1
audio_url
string<uri>

Presigned URL to audio file from any cloud provider.

Audio Validation Requirements:

  • Formats: WAV or MP3 ONLY (detected via magic bytes, not file extension)
  • Channels: Stereo (recommended) or mono. Stereo assigns speaker roles deterministically from channel position (channel 0 = agent, channel 1 = user); mono infers roles by classifying transcript content, which is typically accurate but less reliable than channel-based mapping.
  • Duration: 5 seconds minimum, 1 hour (3600 seconds) maximum
  • File Size: 200 MB maximum
  • Validation: Audio is validated BEFORE processing begins
  • Rejected Formats: MP4, M4A, FLAC, OGG, AAC, etc.

Supported URL Formats:

Validation Errors (400 INVALID_ARGUMENT):

  • "Audio file is empty."
  • "Unsupported audio format: {format}. Only WAV and MP3 files are supported."
  • "Audio too short: {X} seconds. Minimum duration is 5 seconds."
  • "Audio too long: {X} minutes. Maximum duration is 60 minutes."
  • "Audio file too large: {X} MB. Maximum size is 200 MB."
  • "Invalid or corrupt audio file. Unable to detect audio format. Supported formats: WAV and MP3."
  • "Invalid or corrupt audio file. Unable to read audio metadata."
  • "Audio URL not found (404)" or "Failed to retrieve audio from URL"
Example:

"https://recordings.s3.amazonaws.com/call-abc.wav?X-Amz-Algorithm=..."

upload_id
string

Reference to a previously issued direct upload from POST /v1/audio:upload.

Use this when you've uploaded audio bytes directly via a Coval-issued presigned PUT URL. The Coval backend resolves the staged upload, validates it, and promotes it into managed recordings storage.

Mutually exclusive with audio and audio_url — provide exactly one audio source.

Validation Errors:

  • 404 NOT_FOUND: upload_id does not exist, has expired, has already been consumed, or belongs to a different organization (404 is returned in all four cases to avoid leaking ID existence across organizations).
  • 400 INVALID_ARGUMENT: Mutually exclusive audio sources provided.
Pattern: ^upl_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"upl_01HRAB8N9G7Q4Y3K2J5W6X1ZTC"

metrics
string[]

List of metric IDs to evaluate (22–26 character IDs).

If not provided, uses your default metrics configured in the Coval dashboard.

Required string length: 22 - 26
Example:
[
  "29BlkepvvX19ebbLDB0y6Q",
  "mymKvEg6ZA65srXbTX5wSM",
  "fstokU4ev5UmT8sUBexiwV"
]
metadata
object

Custom metadata for conditional metrics and tracking.

Used for:

  • Triggering conditional metrics
  • Filtering conversations
  • Custom analytics and reporting
Example:
{
  "campaign": "q4-support",
  "customer_tier": "premium",
  "region": "us-west"
}
external_conversation_id
string

External conversation ID from your system.

Stored as conversation_id in customer_metadata JSONField. Can be used to correlate with external systems (Twilio, Vonage, etc).

Example:

"external-call-7x8z9a"

occurred_at
string<date-time>

When the conversation actually occurred (ISO 8601)

Example:

"2025-11-03T14:32:00Z"

agent_id
string | null

Agent resource ID (22-character ShortUUID) to associate with this conversation.

Must reference an existing agent within your organization. The agent is validated at submission time:

  • 400 INVALID_ARGUMENT: Malformed ID (wrong length or characters).
  • 404 NOT_FOUND: Agent does not exist or belongs to a different organization.
Pattern: ^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$
Example:

"gk3jK9mPq2xRt5vW8yZaBc"

Response

Conversation submitted successfully

conversation
object
required

Conversation resource object.