Coval Audio API
Upload audio for evaluation and access conversation audio files
Upload audio for evaluation and access conversation audio files
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/coval-audio-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Coval Agents Audio API
version: 1.0.0
description: '
Manage configurations for simulations and evaluations.
'
contact:
name: Coval API Support
email: support@coval.dev
url: https://docs.coval.ai
license:
name: Proprietary
url: https://coval.dev/terms
servers:
- url: https://api.coval.dev/v1
description: Production API
security:
- ApiKeyAuth: []
tags:
- name: Audio
description: Upload audio for evaluation and access conversation audio files
paths:
/audio:upload:
post:
tags:
- Audio
summary: Upload audio
description: 'Issue an opaque `upload_id` and a short-lived presigned PUT URL for direct audio upload.
'
operationId: createAudioUpload
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAudioUploadRequest'
examples:
wavDefault:
summary: Default WAV upload (no body required)
value: {}
mp3Explicit:
summary: MP3 upload with size hint
value:
content_type: audio/mp3
expected_size_bytes: 12582912
responses:
'200':
description: Presigned upload URL issued
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAudioUploadResponse'
examples:
success:
summary: Successful issuance
value:
upload_id: upl_01HRAB8N9G7Q4Y3K2J5W6X1ZTC
upload_url: https://uploads.coval.dev/8fce4e70/upl_01HRAB8N9G7Q4Y3K2J5W6X1ZTC?signature=...
expires_at: '2025-11-03T15:32:00Z'
max_size_bytes: 104857600
content_type: audio/wav
'400':
$ref: '#/components/responses/InvalidArgument'
'401':
$ref: '#/components/responses/Unauthenticated'
'500':
$ref: '#/components/responses/InternalError'
/conversations/{conversation_id}/audio:
get:
tags:
- Audio
summary: Get conversation audio
description: 'Retrieve a presigned URL for downloading conversation audio.
'
operationId: getConversationAudio
parameters:
- name: conversation_id
in: path
description: Unique conversation identifier
required: true
schema:
type: string
minLength: 22
maxLength: 26
example: gk3jK9mPq2xRt5vW8yZaBc
responses:
'200':
description: Presigned audio URL
content:
application/json:
schema:
$ref: '#/components/schemas/GetConversationAudioResponse'
examples:
success:
summary: Presigned URL returned
value:
audio_url: https://coval-audio-prod.s3.us-east-2.amazonaws.com/audio/2025/11/03/gk3jK9mPq2xRt5vW8yZaBc.wav?X-Amz-Signature=...
peaks_url: https://coval-audio-prod.s3.us-east-2.amazonaws.com/audio/2025/11/03/gk3jK9mPq2xRt5vW8yZaBc.peaks.json?X-Amz-Signature=...
conversation_id: gk3jK9mPq2xRt5vW8yZaBc
url_expires_in_seconds: 3600
'404':
description: Conversation not found or has no audio
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
notFound:
summary: Conversation not found
value:
error:
code: NOT_FOUND
message: Conversation not found
details: []
noAudio:
summary: No audio file available
value:
error:
code: NOT_FOUND
message: Conversation has no audio file available
details:
- field: audio
description: No audio was provided when this conversation was submitted
'401':
$ref: '#/components/responses/Unauthenticated'
'500':
$ref: '#/components/responses/InternalError'
components:
responses:
InvalidArgument:
description: Invalid request arguments
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
missingInput:
summary: Missing required input
value:
error:
code: INVALID_ARGUMENT
message: Missing required input data
details:
- field: transcript
description: At least one of transcript or audio_url must be provided
invalidFilter:
summary: Invalid filter expression
value:
error:
code: INVALID_ARGUMENT
message: Invalid filter expression
details:
- field: filter
description: 'Unknown field ''invalid_field''. Valid fields: status, create_time, occurred_at, external_conversation_id'
invalidPageSize:
summary: Invalid page_size
value:
error:
code: INVALID_ARGUMENT
message: Invalid page_size
details:
- field: page_size
description: page_size must be between 1 and 250
audioFormatInvalid:
summary: Unsupported audio format
value:
error:
code: INVALID_ARGUMENT
message: 'Unsupported audio format: MP4. Only WAV and MP3 files are supported.'
details:
- field: audio_url
description: Audio format detected as MP4 via magic byte analysis. Convert to WAV or MP3.
audioTooShort:
summary: Audio duration too short
value:
error:
code: INVALID_ARGUMENT
message: 'Audio too short: 3.0 seconds. Minimum duration is 5 seconds.'
details:
- field: audio_url
description: Audio file duration is below the 5 second minimum requirement
audioTooLong:
summary: Audio duration too long
value:
error:
code: INVALID_ARGUMENT
message: 'Audio too long: 75.0 minutes. Maximum duration is 60 minutes.'
details:
- field: audio_url
description: Audio file duration exceeds the 1 hour maximum limit
audioTooLarge:
summary: Audio file size too large
value:
error:
code: INVALID_ARGUMENT
message: 'Audio file too large: 250.0 MB. Maximum size is 200 MB.'
details:
- field: audio_url
description: Audio file size exceeds 200 MB limit
audioEmpty:
summary: Empty audio file
value:
error:
code: INVALID_ARGUMENT
message: Audio file is empty.
details:
- field: audio_url
description: Audio file contains no data
audioCorrupt:
summary: Corrupt or invalid audio file
value:
error:
code: INVALID_ARGUMENT
message: Invalid or corrupt audio file. Unable to read audio metadata.
details:
- field: audio_url
description: Audio file headers could not be read or are corrupted
Unauthenticated:
description: Missing or invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error:
code: UNAUTHENTICATED
message: Invalid or missing API key
details: []
InternalError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error:
code: INTERNAL_ERROR
message: An internal error occurred while processing the request
details: []
schemas:
GetConversationAudioResponse:
type: object
required:
- audio_url
- conversation_id
- url_expires_in_seconds
properties:
audio_url:
type: string
format: uri
description: 'Presigned S3 URL for downloading audio file.
URL is valid for duration specified in url_expires_in_seconds.
No authentication required to access this URL.
'
example: https://coval-audio-prod.s3.us-east-2.amazonaws.com/audio/2025/11/03/gk3jK9mPq2xRt5vW8yZaBc.wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&...
peaks_url:
type:
- string
- 'null'
format: uri
description: 'Presigned S3 URL for precomputed waveform peaks JSON (valid for 1 hour).
Contains an array of up to 800 [min, max] amplitude pairs for waveform visualization.
Null for older recordings without precomputed peaks. May return 404 if peaks
were not generated for this recording.
'
example: https://coval-audio-prod.s3.us-east-2.amazonaws.com/audio/2025/11/03/gk3jK9mPq2xRt5vW8yZaBc.peaks.json?X-Amz-Algorithm=AWS4-HMAC-SHA256&...
conversation_id:
type: string
description: Conversation identifier
example: gk3jK9mPq2xRt5vW8yZaBc
url_expires_in_seconds:
type: integer
description: Number of seconds until presigned URL expires
example: 3600
description: 'Response containing presigned URL for audio download.
'
CreateAudioUploadResponse:
type: object
required:
- upload_id
- upload_url
- expires_at
- max_size_bytes
- content_type
properties:
upload_id:
type: string
pattern: ^upl_[0-9A-HJKMNP-TV-Z]{26}$
description: 'Opaque upload identifier. Pass this as `upload_id` on
`POST /v1/conversations:submit` after you''ve uploaded bytes to
`upload_url`.
'
example: upl_01HRAB8N9G7Q4Y3K2J5W6X1ZTC
upload_url:
type: string
format: uri
description: 'Short-lived presigned PUT URL. PUT the audio bytes here with
the matching `Content-Type` header from `content_type`.
'
example: https://uploads.coval.dev/8fce4e70/upl_01HRAB8N9G7Q4Y3K2J5W6X1ZTC?signature=...
expires_at:
type: string
format: date-time
description: 'Absolute UTC timestamp at which the presigned URL stops being
valid. The `upload_id` itself remains resolvable for 7 days from
issuance, but you cannot upload bytes after this timestamp.
'
example: '2025-11-03T15:32:00Z'
max_size_bytes:
type: integer
description: Hard upper bound on the uploaded payload size, in bytes.
example: 104857600
content_type:
type: string
enum:
- audio/wav
- audio/mp3
description: 'Content-Type the client must send on the PUT request. Equal to
the `content_type` requested (or default `audio/wav`).
'
example: audio/wav
description: 'Response for `POST /v1/audio:upload`.
'
ErrorResponse:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
description: Error code
enum:
- INVALID_ARGUMENT
- UNAUTHENTICATED
- NOT_FOUND
- ALREADY_EXISTS
- PAYLOAD_TOO_LARGE
- INTERNAL_ERROR
example: INVALID_ARGUMENT
message:
type: string
description: Human-readable error message
example: Missing required input data
details:
type: array
items:
$ref: '#/components/schemas/ErrorDetail'
description: Additional error details
default: []
ErrorDetail:
type: object
properties:
field:
type: string
description: Field that caused the error
example: transcript
description:
type: string
description: Detailed description of the error
example: At least one of transcript, audio, or audio_url must be provided
CreateAudioUploadRequest:
type: object
properties:
content_type:
type: string
enum:
- audio/wav
- audio/mp3
default: audio/wav
description: 'MIME type of the audio that will be uploaded. MUST match the
`Content-Type` header on your subsequent `PUT` request, otherwise
the upload will be rejected.
'
example: audio/wav
expected_size_bytes:
type: integer
minimum: 1
maximum: 104857600
description: 'Optional client-declared size hint in bytes. The presigned URL
always enforces the 100 MB hard cap regardless of this value.
'
example: 12582912
description: 'Request body for `POST /v1/audio:upload`. All fields are optional;
an empty body issues a WAV upload URL.
'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: API key for authentication
x-visibility: external