API reference

Voices and models

Browse the voice and model catalogs, register custom language models, and estimate cost per minute.

These routes describe what you can put into an agent configuration: text-to-speech providers, their models and voices, the language model and speech-to-text catalogs, and your own OpenAI-compatible models. One route estimates the per-minute cost of a combination.

All routes need Authorization: Bearer <key>.

Note: The catalogs list what an agent configuration may name. Whether a given third-party provider actually works on live calls depends on the credentials and models the operator has set up for the voice engine. When the operator has configured the platform's local models, they appear first in each catalog with the provider local. A local language model is listed with "base_url": null and "hosted_by_platform": true: where it runs is not part of the catalog, and no key or address is needed to use it.

OperationMethod and path
List TTS providers for a languageGET /api/v1/voice-config/tts
List voicesGET /api/v1/voice-config/tts/voices
List languagesGET /api/v1/voice-config/languages
List all voices and modelsGET /user/model/all
Add a custom modelPOST /user/model/custom
List custom modelsGET /user/model/custom
Remove a custom modelDELETE /user/model/custom/{model_id}
Estimate the price per minuteGET /get_current_price

Operations

List TTS providers for a language

GET /api/v1/voice-config/tts

Returns the text-to-speech providers that have at least one model for a language, with those models.

Auth: API key or session token. Role: viewer and up.

ParameterInTypeRequiredDescription
languagequerystringyesLanguage code, for example en or hi.

Request

bash
curl "https://api.sevennadi.si/api/v1/voice-config/tts?language=en" \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "language": "en",
  "providers": [
    {
      "id": "d8b6e33f-f5b4-5e99-bd65-25c34a93d1df",
      "name": "ElevenLabs",
      "slug": "elevenlabs",
      "is_supported": true,
      "models": [
        {
          "id": "2c1127ca-1ba7-5975-9257-6f4321c0d7df",
          "model_id": "eleven_flash_v2_5",
          "display_name": "Eleven Flash v2.5",
          "description": "Ultra-low latency model in 32 languages.",
          "display_order": 1,
          "quality_tier": "flash",
          "is_supported": true,
          "default": false
        }
      ]
    }
  ],
  "custom_voices": {},
  "default": null
}

Errors

StatusMessage
400query.language: Field required

List voices

GET /api/v1/voice-config/tts/voices

Returns the voices of one provider and model, optionally narrowed to a language.

Auth: API key or session token. Role: viewer and up.

ParameterInTypeRequiredDescription
provider_idquerystringyesThe provider's id or its slug.
model_idquerystringyesThe model's model_id, for example eleven_flash_v2_5.
languagequerystringnoLanguage code.
pagequeryintegernoStarts at 1. Default 1.
page_sizequeryintegerno1 to 200. Default 50.

Request

bash
curl "https://api.sevennadi.si/api/v1/voice-config/tts/voices?provider_id=elevenlabs&model_id=eleven_flash_v2_5&language=hi" \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "items": [
    {
      "id": "50cb8479-fb6e-5523-a54b-a5018a6a2d5a",
      "provider_id": "d8b6e33f-f5b4-5e99-bd65-25c34a93d1df",
      "voice_id": "iWNf11sz1GrUE4ppxTOL",
      "name": "Viraj - Warm, Energetic and Lively",
      "gender": "male",
      "accent": "standard",
      "age_range": "young",
      "use_case": ["conversational"],
      "is_native": true,
      "preview_url": null,
      "source": "platform"
    }
  ]
}

The response has no total; request the next page until items comes back shorter than page_size. Use voice_id and name in the agent's synthesizer.provider_config.

Errors

StatusMessage
400query.provider_id: Field required or query.model_id: Field required
404Provider not found

List languages

GET /api/v1/voice-config/languages

Returns the language codes the catalogs use. This route is not part of the core OpenAPI document.

Auth: API key or session token. Role: viewer and up.

No parameters.

Request

bash
curl https://api.sevennadi.si/api/v1/voice-config/languages \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
[
  {"code": "hi", "name": "Hindi", "iso_639_1": "hi"},
  {"code": "en", "name": "English", "iso_639_1": "en"}
]

List all voices and models

GET /user/model/all

Returns three catalogs in one response: voices, language models (including your custom models) and speech-to-text models. This route is not part of the core OpenAPI document.

Auth: API key or session token. Role: viewer and up.

No parameters.

Request

bash
curl https://api.sevennadi.si/user/model/all \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "voices": [
    {
      "id": "50cb8479-fb6e-5523-a54b-a5018a6a2d5a",
      "voice_id": "iWNf11sz1GrUE4ppxTOL",
      "provider": "elevenlabs",
      "name": "Viraj - Warm, Energetic and Lively",
      "model": "eleven_flash_v2_5",
      "language_code": "hi",
      "accent": "Standard Male"
    }
  ],
  "llmModels": [
    {
      "id": "9acd3318-bd9b-57c2-a432-0471810ef198",
      "provider": "openai",
      "model": "gpt-4.1-mini",
      "display_name": "GPT-4.1 mini",
      "family": "openai",
      "deprecated": false,
      "custom": false,
      "base_url": null
    }
  ],
  "asrs": [
    {
      "id": "53eeb72f-a587-5db9-8886-97f4e9603470",
      "provider": "deepgram",
      "model": "nova-3",
      "name": "nova-3",
      "languages": ["en", "multi-hi", "es", "fr"],
      "supports_keywords": true,
      "supports_keyword_weights": false,
      "supports_context": false
    }
  ]
}

Your custom models appear in llmModels with "provider": "custom" and "custom": true. The lists above are shortened to one entry each.

Add a custom model

POST /user/model/custom

Registers an OpenAI-compatible language model endpoint that you host or rent. To use it, set the agent's llm_config.model to the model's name. The key is encrypted at rest and never returned. A sub-account also sees the custom models of its parent account.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
custom_model_namebodystringyesThe model name. No other model you can see may have the same name.
custom_model_urlbodystringyesBase URL, starting with https:// or http://.
custom_model_keybodystringyesAPI key for the endpoint.
custom_model_familybodystringyesModel family, for your reference.
custom_model_languagesbodystringnoLanguages the model handles, as one comma-separated string (at most 300 characters), for example hi,en.

Request

bash
curl -X POST https://api.sevennadi.si/user/model/custom \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_model_name": "bank-assistant-v2",
    "custom_model_url": "https://llm.example.test/v1",
    "custom_model_key": "<your key>",
    "custom_model_family": "llama"
  }'

Response 200 OK

json
{"message": "model added successfully", "status": "added"}

Errors

StatusMessage
400custom_model_name is required (likewise for custom_model_url, custom_model_key, custom_model_family)
400custom_model_url must be an http(s) URL
400A custom model with this name already exists
403Your role (member) can't change custom model providers. It needs admin access; ask an owner or admin of the workspace.

List custom models

GET /user/model/custom

Returns your custom models, oldest first, and those of the parent account if you are a sub-account.

Auth: API key or session token. Role: viewer and up.

No parameters.

Request

bash
curl https://api.sevennadi.si/user/model/custom \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "models": [
    {
      "id": "1f2e3d4c-5b6a-4978-8a9b-0c1d2e3f4a5b",
      "model": "bank-assistant-v2",
      "display_name": "bank-assistant-v2",
      "provider": "custom",
      "family": "llama",
      "base_url": "https://llm.example.test/v1"
    }
  ]
}

Remove a custom model

DELETE /user/model/custom/{model_id}

Deletes one of your own custom models. A sub-account cannot delete a model that belongs to its parent.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
model_idpathstring (UUID)yesThe model's id.

Request

bash
curl -X DELETE https://api.sevennadi.si/user/model/custom/1f2e3d4c-5b6a-4978-8a9b-0c1d2e3f4a5b \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{"message": "model deleted successfully", "status": "deleted"}

Errors

StatusMessage
404Model not found

Estimate the price per minute

GET /get_current_price

Estimates what one minute costs for a chosen speech-to-text, language model and text-to-speech, from your workspace's price book. It also says how many minutes the current wallet balance would cover. This is an estimate; each call is priced from its real usage when it ends. This route is not part of the core OpenAPI document.

Auth: API key or session token. Role: viewer and up.

ParameterInTypeRequiredDescription
asr_providerquerystringnoSpeech-to-text provider.
asr_modelquerystringnoSpeech-to-text model.
llm_providerquerystringnoLanguage model provider.
llm_modelquerystringnoLanguage model.
tts_providerquerystringnoText-to-speech provider.
tts_modelquerystringnoText-to-speech model.

Request

bash
curl "https://api.sevennadi.si/get_current_price?asr_provider=deepgram&asr_model=nova-2&llm_model=gpt-4o-mini&tts_provider=elevenlabs" \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "data": "0.094",
  "asr_cost": 0.008,
  "llm_cost": 0.006,
  "tts_cost": 0.05,
  "agent_cost": 0.064,
  "platform_cost": 0.02,
  "telephony_cost": 0.01,
  "total_cost": 0.094,
  "currency": "INR",
  "state": "success",
  "providers": {},
  "custom_price": false,
  "talk_time": 53
}

All costs are per minute in major units of currency. data is total_cost as a string. custom_price is true when your workspace has its own prices. talk_time is the wallet balance divided by total_cost, rounded down. The figures shown are an example of the shape; the real ones come from the operator's price book. See Billing.