Agents
Agents are the reusable voice personas that power calls. Each agent stores its prompt, persona/playbook structure, provider routing, post-call defaults, and feature flags.
List Agents
Returns a paginated list of agents for the authenticated tenant.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max records to return (max 500) |
offset | integer | 0 | Records to skip |
Example Request
curl "https://api.rymi.live/v1/agents?limit=10&offset=0" \
-H "Authorization: Bearer YOUR_API_KEY"const { agents } = await rymi.agents.list({ limit: 10, offset: 0 });result = rymi.agents.list(limit=10, offset=0)Response 200
{
"agents": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Priya - Sales Specialist",
"voice": "Aoede",
"llm_provider": "gemini",
"llm_model": "gemini-2.5-flash",
"agent_kind": "custom",
"language": "en-US",
"created_at": "2026-03-01T10:00:00Z"
}
],
"total": 1,
"offset": 0,
"limit": 10
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
Model and Voice Catalog
Returns the model catalog and voice list available for agent configuration. Populate dropdowns and pickers from this before you create or update an agent.
Example Request
curl https://api.rymi.live/v1/agents/llm-options \
-H "Authorization: Bearer YOUR_API_KEY"const { models, voices } = await rymi.agents.llmOptions();result = rymi.agents.llm_options()Response 200
{
"models": [
{
"provider": "google",
"provider_name": "Google",
"model_id": "gemini-2.5-flash",
"label": "Gemini 2.5 Flash",
"type": ["llm"],
"plan_locked": false,
"required_plan": null,
"byok_required": false,
"byok_provider_id": null,
"modality": "standard",
"latency_ms": null,
"cost_per_min": null,
"reasoning_supported": false
}
],
"voices": [
{
"id": "voice_aoede",
"provider": "google",
"name": "Aoede",
"label": "Aoede",
"gender": "Female",
"supported_model_ids": ["gemini-2.5-flash"],
"is_active": true,
"byok_required": false,
"byok_provider_id": null
}
]
}Each model uses model_id as its identifier and provider as the provider key. The type array records which roles the entry can fill (llm, stt, tts). Voice entries carry the human-readable label, gender, and supported_model_ids (the models a voice is compatible with). byok_required is true when the provider requires your own key.
Agent Kind
Every agent is one of two kinds, set with agent_kind on create or update. The kind also determines how the agent is billed. See Pricing model.
| Kind | API Value | Stack | Billing |
|---|---|---|---|
| Custom (default) | custom | You choose the STT, LLM, and TTS models (and optional fallbacks). | Component cost (sum of each model's per-minute rate) + a flat $0.02/min platform fee |
| Managed | managed | A ready-made, locked stack chosen for you. Set managed_sku_id to the chosen SKU. | The SKU's fixed published price_per_min |
List the available managed SKUs (with prices and their locked stacks) via GET /v1/managed-skus. For custom agents, call GET /v1/agents/llm-options for valid model and voice IDs.
Language Routing
The language field is the primary language the agent starts with. The supported_languages field lists every language this agent may run.
- Use an explicit locale such as
en-USorhi-INforlanguage. - Include one or more locales in
supported_languages. - For custom agents, Rymi resolves a valid STT, LLM, and TTS stack for each selected language before the agent is saved.
- Automatic language detection and mid-call dynamic rerouting are not default MVP behavior.
- Routing is derived from the selected languages and supported provider capabilities. Public API clients do not need to manage provider routing tables.
Create Agent
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | Human-readable agent name (100 characters or fewer recommended; not enforced by the API) |
system_prompt | string | No | — | Raw system prompt. If you omit persona and playbook, Rymi can extract structure from this prompt |
voice | string | No | Aoede | TTS voice ID from GET /v1/agents/llm-options |
language | string | No | en-US | Primary call language locale (for example, en-US, hi-IN) |
supported_languages | string[] | No | [language] | Locales this agent may run. The API resolves a valid stack for each selected language |
agent_kind | string | No | custom | custom (you pick the stack) or managed (Rymi Managed SKU). See Agent Kind |
managed_sku_id | string | null | No | null | Required when agent_kind is managed: the SKU ID from GET /v1/managed-skus. Must be null for custom agents |
llm_provider | string | No | Stack default | gemini, openai, anthropic, or sarvam |
llm_model | string | No | Stack default | LLM model ID (a realtime model bundles STT/TTS) |
stt_provider | string | No | Stack default | Speech-to-text provider |
stt_model | string | No | Stack default | STT model ID |
tts_provider | string | No | Stack default | Text-to-speech provider |
tts_model | string | No | Stack default | TTS model ID |
llm_fallback_provider | string | null | No | — | Secondary LLM provider used if the primary fails. null clears it |
llm_fallback_model | string | null | No | — | Secondary LLM model. null clears it |
stt_fallback_provider | string | null | No | — | Secondary STT provider. null clears it |
stt_fallback_model | string | null | No | — | Secondary STT model. null clears it |
tts_fallback_provider | string | null | No | — | Secondary TTS provider. null clears it |
tts_fallback_model | string | null | No | — | Secondary TTS model. null clears it |
custom_llm_url | string | null | No | — | Self-hosted LLM endpoint (https:// or wss://). Enterprise only; null clears |
custom_voice_url | string | null | No | — | Self-hosted TTS endpoint. Enterprise only; null clears |
custom_voice_mode | string | No | rymi | Wire format for custom_voice_url: rymi or openai-compat |
custom_transcriber_url | string | null | No | — | Self-hosted STT endpoint. Enterprise only; null clears |
persona | Persona object | No | — | Structured role, tone, audience, and voice config |
playbook | Playbook object | No | — | Opener, qualification flow, scripts, CTA, and escalation rules |
advanced | advanced object | No | — | Runtime tuning (endpointing, turn timing) |
features | Features object | No | — | Feature flags (recording, transcription) |
post_call | Post-call object | No | — | Default post-call intelligence config |
provider_config | object | No | — | Read-only. Server-derived from the resolved stack + supported languages on every write; ignored if sent as input and cannot be set via the API |
Persona Object
| Field | Type | Description |
|---|---|---|
role | string | Agent's role description (e.g., "Insurance sales specialist") |
toneOverride | string | Speaking style (e.g., "warm and concise") |
audienceDescription | string | Who the agent talks to |
voiceConfig | object | Voice settings: { "voiceId": "Aoede", "language": "en-US", "bargeInEnabled": true } |
successCriteria | string[] | What a successful call looks like |
callerPersonas | object[] | Caller type variants: { type, approach } |
The full persona shape (company fields, knowledge base) is in the Configuration Reference below.
Playbook Object
| Field | Type | Description |
|---|---|---|
opener | string | Opening message the agent uses to start the conversation |
qualificationFlow | object[] | Questions and what to listen for: { question, listensFor } |
requiredSlots | object[] | Data to collect: { name, description, required } |
objectionHandlers | object[] | How to handle pushback: { trigger, response } |
scripts | object[] | Canned responses for specific situations: { title, when, content } |
closingCTA | string | Primary call-to-action the agent drives toward |
fallbackCTA | string | Fallback if the primary CTA fails |
escalationRule | string | When/how to escalate to a human |
endCallMessage | string | Closing message or sign-off script |
advanced object
Runtime tuning: turn timing, speech detection, and safety limits. See the Configuration Reference for the full field list (maxCallDuration, silencePromptDelay, smartEndpointing, STT options, …).
Features Object
| Field | Type | Default | Description |
|---|---|---|---|
recording_enabled | boolean | false | Record both sides of each call |
transcription_enabled | boolean | true | Transcribe and store each call |
require_consent | boolean | true | Announce recording at call start |
Post-call Object
| Field | Type | Default | Description |
|---|---|---|---|
summary.enabled | boolean | true | Generate a summary after each call |
summary.prompt | string | — | Custom instructions for the summary LLM (e.g. "highlight objections") |
structured_extraction.json_schema | object | — | JSON Schema defining the structured data to extract from the transcript |
structured_extraction.prompt | string | — | Custom instructions for the extraction LLM (auto-generated from schema if omitted) |
evaluation.rubric | string | — | Numbered list of quality criteria for call scoring |
model.provider | string | — | LLM provider for post-call analysis: gemini or openai. Defaults to platform setting |
model.model | string | — | Specific model ID (e.g. gemini-2.5-flash, gpt-4o-mini). Defaults to platform setting |
Example: Minimal
curl -X POST https://api.rymi.live/v1/agents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Agent"
}'Example: Full Configuration
curl -X POST https://api.rymi.live/v1/agents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Priya - Sales Specialist",
"system_prompt": "You are Priya, a friendly insurance sales agent who speaks Hindi with a Delhi accent.",
"voice": "Aoede",
"language": "hi-IN",
"llm_provider": "gemini",
"llm_model": "gemini-2.5-flash",
"persona": {
"role": "Insurance sales specialist",
"toneOverride": "warm, patient, and persuasive",
"audienceDescription": "Hindi-speaking consumers in North India",
"voiceConfig": { "voiceId": "Aoede", "language": "hi-IN", "bargeInEnabled": true },
"successCriteria": ["Lead qualified", "Follow-up call booked"]
},
"playbook": {
"opener": "Namaste! Main Priya hoon, Acme Insurance se. Kaise madad kar sakti hoon?",
"qualificationFlow": [
{ "question": "What type of coverage are you looking for?", "listensFor": "Interest in health insurance" },
{ "question": "How many family members need coverage?", "listensFor": "Family size and decision-maker status" }
],
"objectionHandlers": [
{ "trigger": "Premium feels too expensive", "response": "Acknowledge, then compare against out-of-pocket hospital costs." }
],
"closingCTA": "Book a follow-up call with our advisor",
"escalationRule": "Transfer to a human when the customer requests a supervisor",
"endCallMessage": "Thank you for your time! We will send the policy details to your email."
},
"advanced": {
"maxCallDuration": 600,
"silencePromptDelay": 8,
"smartEndpointing": true
},
"features": {
"recording_enabled": true,
"transcription_enabled": true,
"require_consent": true
},
"post_call": {
"summary": { "enabled": true },
"structured_extraction": {
"json_schema": {
"type": "object",
"properties": {
"interested_plan": { "type": "string" },
"family_size": { "type": "integer" },
"booked_followup": { "type": "boolean" }
}
}
},
"evaluation": {
"rubric": "1. Did the agent qualify the lead?\n2. Did the agent book a follow-up?"
}
}
}'Response 201
{
"status": "created",
"id": "550e8400-e29b-41d4-a716-446655440000"
}Errors
| Status | Meaning |
|---|---|
400 | Validation error (missing name, invalid agent_kind/managed_sku_id, etc.) |
401 | Missing or invalid API key |
402 | Insufficient credits |
Get Agent
Returns the full agent configuration including the compiled prompt.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | uuid | Agent ID |
Example Request
curl https://api.rymi.live/v1/agents/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY"const agent = await rymi.agents.retrieve("550e8400-e29b-41d4-a716-446655440000");agent = rymi.agents.retrieve("550e8400-e29b-41d4-a716-446655440000")Response 200
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Priya - Sales Specialist",
"voice": "Aoede",
"language": "hi-IN",
"persona": {
"role": "Insurance sales specialist",
"toneOverride": "warm and persuasive",
"audienceDescription": "Hindi-speaking consumers in North India",
"voiceConfig": { "voiceId": "Aoede", "language": "hi-IN" }
},
"playbook": {
"opener": "Namaste! Main Priya hoon, Acme Insurance se.",
"closingCTA": "Book a follow-up call with our advisor"
},
"compiled_prompt": "You are Priya...",
"llm_provider": "gemini",
"llm_model": "gemini-2.5-flash",
"agent_kind": "custom",
"managed_sku_id": null,
"features": {
"recording_enabled": true,
"transcription_enabled": true
},
"post_call": {
"summary": { "enabled": true },
"evaluation": { "rubric": null }
},
"updated_at": "2026-03-01T10:00:00Z"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
404 | Agent not found for this tenant |
Update Agent
Pass only the fields you want to change. Unspecified fields remain unchanged. PUT and PATCH behave identically: both apply a partial update to the agent.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | uuid | Agent ID |
Request Body
Accepts the same fields as Create Agent. All fields are optional.
Example Request
curl -X PUT https://api.rymi.live/v1/agents/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"system_prompt": "Updated instructions for handling renewals...",
"post_call": {
"summary": { "enabled": true },
"structured_extraction": {
"json_schema": {
"type": "object",
"properties": {
"renewal_confirmed": { "type": "boolean" }
}
}
}
}
}'const result = await rymi.agents.update("550e8400-e29b-41d4-a716-446655440000", {
system_prompt: "Updated instructions for handling renewals...",
post_call: {
summary: { enabled: true },
structured_extraction: {
json_schema: {
type: "object",
properties: {
renewal_confirmed: { type: "boolean" },
},
},
},
},
});result = rymi.agents.update(
"550e8400-e29b-41d4-a716-446655440000",
system_prompt="Updated instructions for handling renewals...",
post_call={
"summary": {"enabled": True},
"structured_extraction": {
"json_schema": {
"type": "object",
"properties": {
"renewal_confirmed": {"type": "boolean"},
},
}
},
},
)Response 200
{
"status": "updated"
}Errors
| Status | Meaning |
|---|---|
400 | Validation error |
401 | Missing or invalid API key |
404 | Agent not found for this tenant |
Clone Agent
Creates a duplicate of an existing agent. The clone gets " (Copy)" appended to its name and is otherwise identical: same persona, playbook, advanced config, post-call settings, and provider stack. The original is unchanged.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | uuid | Agent ID to clone |
Example Request
curl -X POST https://api.rymi.live/v1/agents/550e8400-e29b-41d4-a716-446655440000/clone \
-H "Authorization: Bearer YOUR_API_KEY"const clone = await rymi.agents.clone("550e8400-e29b-41d4-a716-446655440000");clone = rymi.agents.clone("550e8400-e29b-41d4-a716-446655440000")Response 201
{
"status": "created",
"id": "7f3e9a12-b4c1-41f2-a890-556677889900"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
403 | Agent belongs to a different tenant |
404 | Agent not found |
List Agent Calls
Returns a paginated list of calls made with a specific agent. Use it to monitor per-agent performance and debug call flows.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | uuid | Agent ID |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max records to return (max 200) |
offset | integer | 0 | Records to skip |
status | string | All statuses | Filter by call status: queued, ringing, in_progress, completed, or failed |
Example Request
curl "https://api.rymi.live/v1/agents/550e8400-e29b-41d4-a716-446655440000/calls?limit=20&status=completed" \
-H "Authorization: Bearer YOUR_API_KEY"const { calls } = await rymi.agents.listCalls("550e8400-e29b-41d4-a716-446655440000", {
limit: 20,
status: "completed",
});result = rymi.agents.list_calls(
"550e8400-e29b-41d4-a716-446655440000",
limit=20,
status="completed",
)Response 200
{
"calls": [
{
"id": "call_abc123",
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"started_at": "2026-03-01T10:00:00Z",
"ended_at": "2026-03-01T10:05:00Z",
"bill_duration": 300,
"total_cost": 0.30
}
],
"total": 1,
"offset": 0,
"limit": 20,
"agent_id": "550e8400-e29b-41d4-a716-446655440000"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
403 | Publishable keys cannot access call history, or agent does not belong to you |
404 | Agent not found |
Delete Agent
WARNING
Deleting an agent cascade-deletes all associated number mappings. Active calls using this agent are not affected.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | uuid | Agent ID |
Example Request
curl -X DELETE https://api.rymi.live/v1/agents/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY"const result = await rymi.agents.delete("550e8400-e29b-41d4-a716-446655440000");result = rymi.agents.delete("550e8400-e29b-41d4-a716-446655440000")Response 200
{
"status": "deleted",
"id": "550e8400-e29b-41d4-a716-446655440000"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
404 | Agent not found for this tenant |
Generate Agent Draft
Describe the agent you want in plain English. Rymi returns a draft persona/playbook bundle plus a compiled prompt preview. You can also send the current draft and opt into clarifying questions before generation.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
prompt | string | Yes | — | Natural-language description of the agent you want |
mode | string | No | create | create for a new agent or edit to refine an existing config |
allow_clarifying_questions | boolean | No | false | When true, Rymi may return questions instead of generating a weak draft |
options.voice | string | No | — | Preferred voice ID or name |
options.llm_provider | string | No | — | Preferred LLM provider hint |
options.llm_model | string | No | — | Preferred model hint |
current_config | object | No | — | Current agent config snapshot for edit mode |
Example: Create Mode
curl -X POST https://api.rymi.live/v1/agents/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A friendly female sales agent who speaks Hindi with a Delhi accent and can sell insurance plans",
"options": {
"llm_provider": "gemini",
"voice": "Aoede"
},
"mode": "create",
"allow_clarifying_questions": false
}'Response 200: Generated
{
"generated": true,
"draft": {
"name": "Delhi Insurance Sales Agent",
"voice": "Aoede",
"llm_provider": "gemini",
"persona": {
"role": "Insurance sales specialist",
"tone": "friendly",
"audience": "Hindi-speaking consumers in North India"
},
"playbook": {
"opener": "Namaste! Main aapki insurance needs mein madad kar sakti hoon.",
"cta": "Book a follow-up with our advisor"
}
},
"compiled_prompt_preview": "You are a friendly female sales agent..."
}Response 200: Clarifying Questions
If allow_clarifying_questions is true and the brief is too thin:
{
"generated": false,
"clarifying_questions": [
"What primary action should the agent drive toward?",
"How should we know the call was successful?"
],
"quality_gates": {
"blockers": ["Primary CTA is missing."],
"warnings": ["Audience context is thin."]
}
}Example: Edit Mode
curl -X POST https://api.rymi.live/v1/agents/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Make the tone more formal and add an escalation rule for angry customers",
"mode": "edit",
"current_config": {
"name": "Support Agent",
"persona": { "role": "Customer support", "tone": "friendly" },
"playbook": { "opener": "Hi! How can I help?" }
}
}'Errors
| Status | Meaning |
|---|---|
400 | Missing prompt or invalid mode |
401 | Missing or invalid API key |
500 | Generation failed |
503 | Generation provider is not configured |
Configuration Reference
The canonical agent payload shape. Every field is optional on PUT /v1/agents/:id (partial updates). On POST /v1/agents only name is required.
Top-level Fields
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Display name for the agent |
voice | string | "Aoede" | Voice ID (use GET /v1/agents/llm-options for available voices) |
language | string | "en-US" | BCP-47 language code |
agent_kind | string | "custom" | custom or managed. See Agent Kind |
managed_sku_id | string | null | null | SKU ID for managed agents (GET /v1/managed-skus); null for custom |
llm_provider | string | "gemini" | Conversation LLM: gemini, openai, anthropic, sarvam |
llm_model | string | "gemini-2.5-flash" | Model ID for the conversation LLM |
stt_provider | string | — | Speech-to-text provider override |
stt_model | string | — | STT model override |
tts_provider | string | — | Text-to-speech provider override |
tts_model | string | — | TTS model override |
supported_languages | string[] | [language] | All BCP-47 locales this agent may run |
llm_fallback_provider / llm_fallback_model | string | null | — | Secondary LLM provider/model; null clears |
stt_fallback_provider / stt_fallback_model | string | null | — | Secondary STT provider/model; null clears |
tts_fallback_provider / tts_fallback_model | string | null | — | Secondary TTS provider/model; null clears |
custom_llm_url / custom_voice_url / custom_transcriber_url | string | null | — | Self-hosted endpoints (https:///wss://), Enterprise; null clears |
custom_voice_mode | string | rymi | Wire format for custom_voice_url: rymi or openai-compat |
provider_config is server-derived (recomputed from the resolved stack + supported languages on every write) and is not accepted as an input field.
persona Object
Who the agent is, how it sounds, and what it knows.
| Field | Type | Description |
|---|---|---|
role | string | Job title (e.g. "Sales Specialist") |
audienceDescription | string | Who the agent talks to |
toneOverride | string | Speaking style (e.g. "warm and concise") |
companyName | string | Company name injected into the system prompt |
companyWebsite | string | Company website URL |
companyDescription | string | What the company does |
knowledgeBase | string[] | URLs or text passages the agent references |
successCriteria | string[] | What a successful call looks like |
voiceConfig.bargeInEnabled | boolean | Whether the caller can interrupt mid-sentence |
callerPersonas | object[] | Caller type variants: { type, approach } |
playbook Object
Conversation flow, objections, scripts, and call-to-action.
| Field | Type | Description |
|---|---|---|
opener | string | First thing the agent says |
qualificationFlow | object[] | Questions and what to listen for: { question, listensFor } |
requiredSlots | object[] | Data to collect: { name, description, required } |
objectionHandlers | object[] | How to handle pushback: { trigger, response } |
scripts | object[] | Canned responses for specific situations: { title, when, content } |
closingCTA | string | Primary call-to-action at end of call |
fallbackCTA | string | Fallback if primary CTA fails |
escalationRule | string | When/how to escalate to a human |
advanced Object
Runtime, speech, and safety configuration.
| Field | Type | Default | Description |
|---|---|---|---|
maxCallDuration | number | 600 | Max call length in seconds. Range 30 to 7200, enforced on POST /v1/agents/apply-changes but not on POST/PATCH /v1/agents |
maxTurnLength | number | 60 | Max agent speaking time per turn (seconds) |
silencePromptDelay | number | 8 | Seconds of silence before nudging the caller |
postSilenceHangup | number | 15 | Seconds of silence before hanging up |
replyDelay | number | 0 | Milliseconds to pause before responding |
startSpeakingPhrasing | string | "agent_greets" | agent_greets or wait_for_user |
startSpeakingThreshold | number | — | VAD sensitivity for when agent starts speaking |
stopSpeakingThreshold | number | — | VAD sensitivity for when caller stops speaking |
resumeAfterInterruption | boolean | true | Resume interrupted sentence after caller stops |
smartEndpointing | boolean | true | AI-powered end-of-turn detection |
waitAfterSentence | number | — | ms to wait after a sentence ends |
waitAfterNoPunctuation | number | — | ms to wait when no sentence-ending punctuation |
waitAfterNumbers | number | — | ms to wait after numbers (they often continue) |
stt_confidence_threshold | number | — | Minimum confidence to accept a transcription |
stt_numeral_formatting | boolean | true | Format numbers as numerals in transcript |
stt_profanity_filter | boolean | false | Filter profanity from transcript |
stt_keywords | string | — | Comma-separated keywords to boost STT accuracy |
offLimitsTopics | string | — | Topics the agent must never discuss |
prohibitedClaims | string | — | Claims the agent must never make |
features Object
| Field | Type | Default | Description |
|---|---|---|---|
recording_enabled | boolean | false | Record both sides of each call |
transcription_enabled | boolean | true | Transcribe and store each call |
require_consent | boolean | true | Announce recording at call start |
post_call Object
| Field | Type | Default | Description |
|---|---|---|---|
summary.enabled | boolean | true | Generate a call summary |
summary.prompt | string | — | Custom summary instructions |
structured_extraction.json_schema | object | — | JSON Schema for data extraction |
structured_extraction.prompt | string | — | Custom extraction instructions (auto-generated if omitted) |
evaluation.rubric | string | — | Numbered scoring criteria |
model.provider | string | — | gemini or openai for post-call LLM |
model.model | string | — | Model ID for post-call LLM |
Validate Publish
POST /v1/agents/validate-publishCheck whether an agent is ready to go live. Returns a validation report without persisting any changes.
Body
| Field | Type | Description |
|---|---|---|
agent_id | uuid | Optional. Merge validation with a persisted agent's config |
name | string | Agent name to validate |
voice | string | Voice ID to validate |
persona | object | Persona config |
playbook | object | Playbook config |
Example
curl -X POST https://api.rymi.live/v1/agents/validate-publish \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "550e8400-e29b-41d4-a716-446655440000"}'Apply Changes
POST /v1/agents/apply-changesValidates and resolves a flat key/value change-set against the AgentConfig field registry. Enforces field types, edit-mode blocklist, and implies rules. Does not persist. Follow up with PUT /v1/agents/:id.
Body
| Field | Type | Description |
|---|---|---|
currentConfig | object | The agent's current flat config |
changes | array | [{key, value}] field changes to apply |
mode | string | "create" or "edit" |
lenient | boolean | Skip unknown-field hard-fail (not recommended) |
Example
curl -X POST https://api.rymi.live/v1/agents/apply-changes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currentConfig": {"name": "Support", "voice": "Aoede"},
"changes": [{"key": "voice", "value": "Charon"}],
"mode": "edit"
}'Response
{
"valid": true,
"config": { "name": "Support", "voice": "Charon" },
"applied": [{ "key": "voice", "value": "Charon" }]
}Preview Model Stack
POST /v1/agents/stack-previewResolves the model stack (STT/LLM/TTS) for a set of supported languages, along with any blockers and warnings, without saving. Call this before create or update to confirm a multi-language setup resolves to a valid stack.
Body
| Field | Type | Required | Description |
|---|---|---|---|
supported_languages | string[] | Yes | Non-empty list of BCP-47 locales to resolve a stack for |
language | string | null | No | Primary locale (defaults to the first supported language) |
current_provider_config | object | null | No | Existing provider config to diff against |
Example
curl -X POST https://api.rymi.live/v1/agents/stack-preview \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"supported_languages": ["hi-IN", "en-US"]
}'Response 200
{
"language": "hi-IN",
"supported_languages": ["hi-IN", "en-US"],
"provider_config": { "mode": "pipeline", "stt": { }, "llm": { }, "tts": { } },
"blockers": [],
"warnings": []
}provider_config is the resolved flat stack. If a language can't be served, it appears in blockers. Non-fatal notes (e.g. a fallback substitution) appear in warnings.
Enrich Company
POST /v1/agents/enrich-companyGenerates a company description from a website URL, grounded in Google Search results. Drop the result into an agent's persona.
Body
| Field | Type | Description |
|---|---|---|
companyName | string | Company name |
websiteUrl | string | Company website URL |
Example
curl -X POST https://api.rymi.live/v1/agents/enrich-company \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"companyName": "Acme Corp", "websiteUrl": "https://acme.example.com"}'Response
This endpoint always returns 200. Use the enriched boolean to discriminate success from failure rather than the HTTP status. On success:
{
"enriched": true,
"companyDescription": "Acme Corp is a leading provider of...",
"knowledgeBase": []
}When the lookup cannot be completed, enriched is false and an error string explains why (the call still returns 200):
{
"enriched": false,
"error": "Could not look up company details. You can describe your business manually."
}Additional Endpoints
These endpoints back the Studio agent builder and SDK/MCP flows. All are prefixed with /v1 and authenticated like the rest of the API.
Catalog & capabilities
| Method | Path | Description |
|---|---|---|
GET | /v1/managed-skus | List managed SKUs with their published price_per_min and locked stacks |
GET | /v1/agents/voices | Voice catalog for agent configuration |
GET | /v1/agents/:id/tool-capabilities | The tool capabilities resolved for a specific agent |
Lifecycle
| Method | Path | Description |
|---|---|---|
POST | /v1/agents/:id/publish | Validate the persisted config and freeze it into the published snapshot the runtime serves. Reports blockers instead of silently no-op'ing |
POST | /v1/agents/:id/opt-out-to-custom | Convert a managed agent to a custom agent, unlocking the stack for manual configuration |
POST | /v1/agents/:id/apply-managed-sku | Swap an agent onto a managed SKU stack in place. Body { managed_sku_id, language } |
AI-assisted drafting
| Method | Path | Description |
|---|---|---|
POST | /v1/agents/draft | Create an agent from the full create body (name required; structured config or system_prompt), skipping publish gates. Not prompt-driven — for prompt-driven creation use /v1/agents/generate |
POST | /v1/agents/draft-field | Generate or refine a single agent field |
POST | /v1/agents/compile-prompt | Compile a preview of the agent's system prompt from its structured config |
POST | /v1/agents/chat/answer | Answer a builder-assistant question about agent configuration |

