API quickstart
Use your server to create a conversation, then connect audio to the EVA Speech Engine over a WebSocket.
Base URL: https://api.evacompany.co
1. Create an API key
In the dashboard, select your workspace and open Developers → API Keys. Create a key using the Run calls preset. Copy it once and store it in your server’s secret configuration as EVA_API_KEY.
This preset grants agents:read, conversations:read, and conversations:write. It does not allow changing agents or creating other keys.
2. Choose a published EVA version
Create and publish an EVA agent in the dashboard. Fetch your agents and their versions:
bash
curl --fail-with-body 'https://api.evacompany.co/v1/agents?limit=20' \
-H "Authorization: Bearer $EVA_API_KEY"
curl --fail-with-body "https://api.evacompany.co/v1/agents/$EVA_AGENT_ID/versions?limit=20" \
-H "Authorization: Bearer $EVA_API_KEY"Both endpoints return JSON arrays. Use the published version’s id as EVA_AGENT_VERSION_ID; the agent ID alone is not sufficient. Choose an EVA engine version. Cartesia-hosted agent streaming uses the dashboard/calling integration instead.
3. Create a conversation
bash
curl --fail-with-body 'https://api.evacompany.co/v1/conversations' \
-H "Authorization: Bearer $EVA_API_KEY" \
-H 'Content-Type: application/json' \
--data "{\"agent_version_id\":\"$EVA_AGENT_VERSION_ID\"}"The 201 response has this shape. Values below are placeholders:
json
{
"id": "conv_example",
"agent_id": "agent_example",
"agent_version_id": "av_example",
"status": "ready",
"stream_url": "wss://api.evacompany.co/v1/conversations/conv_example/stream",
"stream_token": "ONE_TIME_STREAM_TOKEN",
"expires_in_seconds": 60
}Use the returned expires_in_seconds; do not assume the example’s lifetime is fixed. Treat the response as sensitive and do not log it. A bootstrap response means the conversation can connect, not that the speech session has started.
4. Connect audio
Connect to the returned stream_url with token set to the URL-encoded stream_token. This token is single-use. Send the following JSON immediately after the socket opens:
json
{
"type": "session.start",
"audio_format": {
"encoding": "pcm_s16le",
"sample_rate": 16000,
"channels": 1,
"sample_width": 2
},
"server_audio_versions": [1]
}Wait for session.started before sending microphone audio. Send binary 16 kHz, mono, signed 16-bit little-endian PCM, without WAV headers. A 20 ms input frame is 640 bytes; send frames at their real-time pace.
Incoming text frames contain JSON events. Incoming binary frames contain generation-tagged assistant audio, not bare PCM when version 1 is negotiated. Read Realtime audio before implementing playback and interruption handling.
5. End and review
Send {"type":"session.end"} to end the session. Use your API key to retrieve saved turns:
bash
curl --fail-with-body "https://api.evacompany.co/v1/conversations/$EVA_CONVERSATION_ID/turns" \
-H "Authorization: Bearer $EVA_API_KEY"Conversation material and post-call results can finish in the background. API-created calls currently do not save audio recordings.
Browser applications
Keep the permanent API key on your server. Have your server create the conversation and pass only its short-lived stream connection details to the authorized client. Verify that the client may use that workspace/agent before creating the conversation. Redact query strings from connection logs because the stream token is a credential.
The dashboard’s cookie-authenticated /stream/browser protocol is separate; do not mix its handshake with the developer stream.
