> For the complete documentation index, see [llms.txt](https://docs.concurrence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.concurrence.com/api-reference/readme/platform/services.md).

# Services

## List services

> List services in a workspace with pagination. Filter by \`agent\_id\` or \`context\_graph\_id\` to list the services on an agent or context graph. Requires \`Service.view\` permission.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"SearchString":{"type":"string","maxLength":200,"minLength":1},"ServiceListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ServiceResponse"},"type":"array","title":"Items"},"has_more":{"type":"boolean","title":"Has More"},"continuation_token":{"title":"Continuation Token"}},"type":"object","required":["items","has_more"],"title":"ServiceListResponse"},"ServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"context_graph_id":{"type":"string","format":"uuid","title":"Context Graph Id"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"context_graph_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context Graph Name"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"is_active":{"type":"boolean","title":"Is Active"},"version_sets":{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Output"},"type":"object","title":"Version Sets"},"tags":{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","title":"Tags"},"tool_capacity":{"type":"integer","title":"Tool Capacity"},"channel_type":{"type":"string","enum":["voice","text"],"title":"Channel Type","default":"voice"},"environment":{"type":"string","enum":["sandbox","production"],"title":"Environment","default":"production"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Output"},{"type":"null"}]},"accepted_context":{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","title":"Accepted Context"},"is_system":{"type":"boolean","title":"Is System","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","workspace_id","name","description","agent_id","context_graph_id","keyterms","is_active","version_sets","tags","tool_capacity","created_at","updated_at"],"title":"ServiceResponse"},"VersionSet-Output":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"LLMConfig":{"properties":{"llm_name":{"type":"string","title":"Llm Name"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"experience_controls":{"anyOf":[{"$ref":"#/components/schemas/LLMExperienceControls"},{"type":"null"}]}},"type":"object","required":["llm_name"],"title":"LLMConfig"},"LLMExperienceControls":{"properties":{"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}],"title":"Reasoning Effort"},"temperature":{"anyOf":[{"type":"number","maximum":2,"minimum":0},{"type":"null"}],"title":"Temperature"},"top_p":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Top P"}},"additionalProperties":false,"type":"object","title":"LLMExperienceControls","description":"Typed model-tuning controls for a version set's LLM preference.\n\n``params`` remains available as a provider-specific escape hatch. These three\nfields are the ones deployments actually use; the surface was trimmed from\nnineteen in V370 after a production census found the other sixteen had never\nbeen set to a non-null value by anyone. Token budgets are intentionally\nexcluded so version sets do not reintroduce accidental response truncation."},"ServiceTag":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["key"],"title":"ServiceTag"},"ServiceVoiceConfig-Output":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."},"RealtimeSessionConfig":{"properties":{"model":{"anyOf":[{"type":"string","enum":["gpt-realtime-2.1","gpt-realtime-2.1-mini"]},{"type":"null"}],"title":"Model"},"voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"$ref":"#/components/schemas/RealtimeCustomVoice"},{"type":"null"}],"title":"Voice"},"speed":{"anyOf":[{"type":"number","maximum":1.5,"minimum":0.25},{"type":"null"}],"title":"Speed"},"noise_reduction":{"anyOf":[{"type":"string","enum":["near_field","far_field","off"]},{"type":"null"}],"title":"Noise Reduction","description":"Input noise reduction. Omit or set null to use the Platform default; set 'off' to disable it."},"transcription":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTranscriptionConfig"},{"type":"null"}]},"turn_detection":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/RealtimeServerVadConfig"},{"$ref":"#/components/schemas/RealtimeSemanticVadConfig"}],"discriminator":{"propertyName":"type","mapping":{"semantic_vad":"#/components/schemas/RealtimeSemanticVadConfig","server_vad":"#/components/schemas/RealtimeServerVadConfig"}}},{"type":"null"}],"title":"Turn Detection"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort"},"max_output_tokens":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"string","const":"inf"},{"type":"null"}],"title":"Max Output Tokens"},"truncation":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTruncationConfig"},{"type":"null"}]},"required_tool_on_first_caller_turn":{"anyOf":[{"type":"string","maxLength":256,"minLength":1,"pattern":"^[A-Za-z_][A-Za-z0-9_.:-]*$"},{"type":"null"}],"title":"Required Tool On First Caller Turn","description":"Force one named function on the first caller-generated response, excluding the inbound greeting, then restore automatic tool choice. Runtime accepts this only for source_override='test' sessions and tools that the executor verifies are read-only or side-effect-free."}},"additionalProperties":false,"type":"object","title":"RealtimeSessionConfig","description":"Typed OpenAI Realtime session controls for a service."},"RealtimeCustomVoice":{"properties":{"id":{"type":"string","maxLength":256,"minLength":1,"pattern":"^voice_[A-Za-z0-9_-]+$","title":"Id"}},"additionalProperties":false,"type":"object","required":["id"],"title":"RealtimeCustomVoice","description":"Approved OpenAI custom voice reference."},"RealtimeTranscriptionConfig":{"properties":{"model":{"type":"string","const":"gpt-transcribe","title":"Model","default":"gpt-transcribe"},"language":{"anyOf":[{"type":"string","maxLength":35,"minLength":2,"pattern":"^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$"},{"type":"null"}],"title":"Language"},"prompt":{"anyOf":[{"type":"string","maxLength":1024,"minLength":1},{"type":"null"}],"title":"Prompt"}},"additionalProperties":false,"type":"object","title":"RealtimeTranscriptionConfig","description":"Asynchronous caller-audio transcription used for transcripts and observability."},"RealtimeServerVadConfig":{"properties":{"type":{"type":"string","const":"server_vad","title":"Type","default":"server_vad"},"threshold":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Threshold"},"prefix_padding_ms":{"anyOf":[{"type":"integer","maximum":5000,"minimum":0},{"type":"null"}],"title":"Prefix Padding Ms"},"silence_duration_ms":{"anyOf":[{"type":"integer","maximum":10000,"minimum":0},{"type":"null"}],"title":"Silence Duration Ms"},"idle_timeout_ms":{"anyOf":[{"type":"integer","maximum":30000,"minimum":5000},{"type":"null"}],"title":"Idle Timeout Ms"}},"additionalProperties":false,"type":"object","title":"RealtimeServerVadConfig","description":"Volume-based turn detection controls."},"RealtimeSemanticVadConfig":{"properties":{"type":{"type":"string","const":"semantic_vad","title":"Type","default":"semantic_vad"},"eagerness":{"type":"string","enum":["auto","low","medium","high"],"title":"Eagerness","default":"auto"}},"additionalProperties":false,"type":"object","title":"RealtimeSemanticVadConfig","description":"Semantic turn detection controls."},"RealtimeTruncationConfig":{"properties":{"type":{"type":"string","enum":["auto","disabled","retention_ratio"],"title":"Type","default":"auto"},"retention_ratio":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Retention Ratio"},"post_instructions_tokens":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Post Instructions Tokens"}},"additionalProperties":false,"type":"object","title":"RealtimeTruncationConfig","description":"Conversation context truncation strategy."},"ServiceForwardingConfig":{"properties":{"forward_to":{"anyOf":[{"$ref":"#/components/schemas/PhoneE164"},{"type":"null"}]},"warm_transfer":{"type":"boolean","title":"Warm Transfer"},"approved_destinations":{"additionalProperties":{"$ref":"#/components/schemas/NameString"},"propertyNames":{"$ref":"#/components/schemas/PhoneE164"},"type":"object","maxProperties":50,"title":"Approved Destinations"}},"type":"object","required":["forward_to","warm_transfer"],"title":"ServiceForwardingConfig","description":"Per-service call-forwarding destination + transfer mechanism.\n\nThis block gates the ``forward_call`` tool: None means the agent cannot\ntransfer at all. When present, ``forward_to`` picks the destination mode,\nand the tool schema follows it — a static service gets an argument-less\ntool, a dynamic one gets a required ``phone_number`` that must be one of\n``approved_destinations`` (none approved means no tool). Nothing cascades:\na service is one mode or the other."},"PhoneE164":{"type":"string","maxLength":16,"minLength":2},"NameString":{"type":"string","maxLength":256,"minLength":1},"ContextKeySpec":{"properties":{"key":{"$ref":"#/components/schemas/SlugString"},"type":{"type":"string","enum":["string","number"],"title":"Type"},"description":{"$ref":"#/components/schemas/DescriptionString"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["key","type","description","required"],"title":"ContextKeySpec","description":"One key a conversation may supply as start-time context for a service.\n\nThe value is validated against ``type`` at conversation start; a tool can then\nbind the key to one of its parameters (injected, hidden from the model)."},"SlugString":{"type":"string","maxLength":63,"minLength":2,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"},"DescriptionString":{"type":"string","maxLength":2000},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v1/{workspace_id}/services":{"get":{"tags":["Services"],"summary":"List services","description":"List services in a workspace with pagination. Filter by `agent_id` or `context_graph_id` to list the services on an agent or context graph. Requires `Service.view` permission.","operationId":"list-services","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"default":[],"title":"Sort By"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"exclusiveMinimum":0,"default":50,"title":"Limit"}},{"name":"continuation_token","in":"query","required":false,"schema":{"title":"Continuation Token"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SearchString"},{"type":"null"}],"title":"Search"}},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Only services on this agent. Each version set pins a version of its service's agent.","title":"Agent Id"},"description":"Only services on this agent. Each version set pins a version of its service's agent."},{"name":"context_graph_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Only services on this context graph. Each version set pins a version of its service's context graph.","title":"Context Graph Id"},"description":"Only services on this context graph. Each version set pins a version of its service's context graph."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceListResponse"}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create a service

> Create a new service linking an agent and a context graph. Validates that agent\_id and context\_graph\_id exist in the workspace and that every version set name and pinned version is valid. Requires \`Service.create\` permission.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"CreateServiceRequest":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"description":{"$ref":"#/components/schemas/DescriptionString","default":""},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"context_graph_id":{"type":"string","format":"uuid","title":"Context Graph Id"},"keyterms":{"items":{"type":"string","maxLength":128,"minLength":1},"type":"array","maxItems":500,"title":"Keyterms"},"is_active":{"type":"boolean","title":"Is Active","default":true},"version_sets":{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Input"},"type":"object","title":"Version Sets","default":{}},"tags":{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","maxItems":50,"title":"Tags"},"tool_capacity":{"type":"integer","maximum":10,"minimum":1,"title":"Tool Capacity","default":3},"channel_type":{"type":"string","enum":["voice","text"],"title":"Channel Type","default":"voice"},"environment":{"type":"string","enum":["sandbox","production"],"title":"Environment","default":"production"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Input"},{"type":"null"}]},"accepted_context":{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","maxItems":100,"title":"Accepted Context"}},"type":"object","required":["name","agent_id","context_graph_id"],"title":"CreateServiceRequest"},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"VersionSet-Input":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"LLMConfig":{"properties":{"llm_name":{"type":"string","title":"Llm Name"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"experience_controls":{"anyOf":[{"$ref":"#/components/schemas/LLMExperienceControls"},{"type":"null"}]}},"type":"object","required":["llm_name"],"title":"LLMConfig"},"LLMExperienceControls":{"properties":{"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}],"title":"Reasoning Effort"},"temperature":{"anyOf":[{"type":"number","maximum":2,"minimum":0},{"type":"null"}],"title":"Temperature"},"top_p":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Top P"}},"additionalProperties":false,"type":"object","title":"LLMExperienceControls","description":"Typed model-tuning controls for a version set's LLM preference.\n\n``params`` remains available as a provider-specific escape hatch. These three\nfields are the ones deployments actually use; the surface was trimmed from\nnineteen in V370 after a production census found the other sixteen had never\nbeen set to a non-null value by anyone. Token budgets are intentionally\nexcluded so version sets do not reintroduce accidental response truncation."},"ServiceTag":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["key"],"title":"ServiceTag"},"ServiceVoiceConfig-Input":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."},"RealtimeSessionConfig":{"properties":{"model":{"anyOf":[{"type":"string","enum":["gpt-realtime-2.1","gpt-realtime-2.1-mini"]},{"type":"null"}],"title":"Model"},"voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"$ref":"#/components/schemas/RealtimeCustomVoice"},{"type":"null"}],"title":"Voice"},"speed":{"anyOf":[{"type":"number","maximum":1.5,"minimum":0.25},{"type":"null"}],"title":"Speed"},"noise_reduction":{"anyOf":[{"type":"string","enum":["near_field","far_field","off"]},{"type":"null"}],"title":"Noise Reduction","description":"Input noise reduction. Omit or set null to use the Platform default; set 'off' to disable it."},"transcription":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTranscriptionConfig"},{"type":"null"}]},"turn_detection":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/RealtimeServerVadConfig"},{"$ref":"#/components/schemas/RealtimeSemanticVadConfig"}],"discriminator":{"propertyName":"type","mapping":{"semantic_vad":"#/components/schemas/RealtimeSemanticVadConfig","server_vad":"#/components/schemas/RealtimeServerVadConfig"}}},{"type":"null"}],"title":"Turn Detection"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort"},"max_output_tokens":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"string","const":"inf"},{"type":"null"}],"title":"Max Output Tokens"},"truncation":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTruncationConfig"},{"type":"null"}]},"required_tool_on_first_caller_turn":{"anyOf":[{"type":"string","maxLength":256,"minLength":1,"pattern":"^[A-Za-z_][A-Za-z0-9_.:-]*$"},{"type":"null"}],"title":"Required Tool On First Caller Turn","description":"Force one named function on the first caller-generated response, excluding the inbound greeting, then restore automatic tool choice. Runtime accepts this only for source_override='test' sessions and tools that the executor verifies are read-only or side-effect-free."}},"additionalProperties":false,"type":"object","title":"RealtimeSessionConfig","description":"Typed OpenAI Realtime session controls for a service."},"RealtimeCustomVoice":{"properties":{"id":{"type":"string","maxLength":256,"minLength":1,"pattern":"^voice_[A-Za-z0-9_-]+$","title":"Id"}},"additionalProperties":false,"type":"object","required":["id"],"title":"RealtimeCustomVoice","description":"Approved OpenAI custom voice reference."},"RealtimeTranscriptionConfig":{"properties":{"model":{"type":"string","const":"gpt-transcribe","title":"Model","default":"gpt-transcribe"},"language":{"anyOf":[{"type":"string","maxLength":35,"minLength":2,"pattern":"^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$"},{"type":"null"}],"title":"Language"},"prompt":{"anyOf":[{"type":"string","maxLength":1024,"minLength":1},{"type":"null"}],"title":"Prompt"}},"additionalProperties":false,"type":"object","title":"RealtimeTranscriptionConfig","description":"Asynchronous caller-audio transcription used for transcripts and observability."},"RealtimeServerVadConfig":{"properties":{"type":{"type":"string","const":"server_vad","title":"Type","default":"server_vad"},"threshold":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Threshold"},"prefix_padding_ms":{"anyOf":[{"type":"integer","maximum":5000,"minimum":0},{"type":"null"}],"title":"Prefix Padding Ms"},"silence_duration_ms":{"anyOf":[{"type":"integer","maximum":10000,"minimum":0},{"type":"null"}],"title":"Silence Duration Ms"},"idle_timeout_ms":{"anyOf":[{"type":"integer","maximum":30000,"minimum":5000},{"type":"null"}],"title":"Idle Timeout Ms"}},"additionalProperties":false,"type":"object","title":"RealtimeServerVadConfig","description":"Volume-based turn detection controls."},"RealtimeSemanticVadConfig":{"properties":{"type":{"type":"string","const":"semantic_vad","title":"Type","default":"semantic_vad"},"eagerness":{"type":"string","enum":["auto","low","medium","high"],"title":"Eagerness","default":"auto"}},"additionalProperties":false,"type":"object","title":"RealtimeSemanticVadConfig","description":"Semantic turn detection controls."},"RealtimeTruncationConfig":{"properties":{"type":{"type":"string","enum":["auto","disabled","retention_ratio"],"title":"Type","default":"auto"},"retention_ratio":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Retention Ratio"},"post_instructions_tokens":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Post Instructions Tokens"}},"additionalProperties":false,"type":"object","title":"RealtimeTruncationConfig","description":"Conversation context truncation strategy."},"ServiceForwardingConfig":{"properties":{"forward_to":{"anyOf":[{"$ref":"#/components/schemas/PhoneE164"},{"type":"null"}]},"warm_transfer":{"type":"boolean","title":"Warm Transfer"},"approved_destinations":{"additionalProperties":{"$ref":"#/components/schemas/NameString"},"propertyNames":{"$ref":"#/components/schemas/PhoneE164"},"type":"object","maxProperties":50,"title":"Approved Destinations"}},"type":"object","required":["forward_to","warm_transfer"],"title":"ServiceForwardingConfig","description":"Per-service call-forwarding destination + transfer mechanism.\n\nThis block gates the ``forward_call`` tool: None means the agent cannot\ntransfer at all. When present, ``forward_to`` picks the destination mode,\nand the tool schema follows it — a static service gets an argument-less\ntool, a dynamic one gets a required ``phone_number`` that must be one of\n``approved_destinations`` (none approved means no tool). Nothing cascades:\na service is one mode or the other."},"PhoneE164":{"type":"string","maxLength":16,"minLength":2},"ContextKeySpec":{"properties":{"key":{"$ref":"#/components/schemas/SlugString"},"type":{"type":"string","enum":["string","number"],"title":"Type"},"description":{"$ref":"#/components/schemas/DescriptionString"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["key","type","description","required"],"title":"ContextKeySpec","description":"One key a conversation may supply as start-time context for a service.\n\nThe value is validated against ``type`` at conversation start; a tool can then\nbind the key to one of its parameters (injected, hidden from the model)."},"SlugString":{"type":"string","maxLength":63,"minLength":2,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"},"ServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"context_graph_id":{"type":"string","format":"uuid","title":"Context Graph Id"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"context_graph_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context Graph Name"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"is_active":{"type":"boolean","title":"Is Active"},"version_sets":{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Output"},"type":"object","title":"Version Sets"},"tags":{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","title":"Tags"},"tool_capacity":{"type":"integer","title":"Tool Capacity"},"channel_type":{"type":"string","enum":["voice","text"],"title":"Channel Type","default":"voice"},"environment":{"type":"string","enum":["sandbox","production"],"title":"Environment","default":"production"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Output"},{"type":"null"}]},"accepted_context":{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","title":"Accepted Context"},"is_system":{"type":"boolean","title":"Is System","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","workspace_id","name","description","agent_id","context_graph_id","keyterms","is_active","version_sets","tags","tool_capacity","created_at","updated_at"],"title":"ServiceResponse"},"VersionSet-Output":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"ServiceVoiceConfig-Output":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."}}},"paths":{"/v1/{workspace_id}/services":{"post":{"tags":["Services"],"summary":"Create a service","description":"Create a new service linking an agent and a context graph. Validates that agent_id and context_graph_id exist in the workspace and that every version set name and pinned version is valid. Requires `Service.create` permission.","operationId":"create-service","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"409":{"description":"Name already taken."},"422":{"description":"Invalid request body."}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get a service

> Retrieve a service by ID. Requires \`Service.view\` permission.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"ServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"context_graph_id":{"type":"string","format":"uuid","title":"Context Graph Id"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"context_graph_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context Graph Name"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"is_active":{"type":"boolean","title":"Is Active"},"version_sets":{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Output"},"type":"object","title":"Version Sets"},"tags":{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","title":"Tags"},"tool_capacity":{"type":"integer","title":"Tool Capacity"},"channel_type":{"type":"string","enum":["voice","text"],"title":"Channel Type","default":"voice"},"environment":{"type":"string","enum":["sandbox","production"],"title":"Environment","default":"production"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Output"},{"type":"null"}]},"accepted_context":{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","title":"Accepted Context"},"is_system":{"type":"boolean","title":"Is System","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","workspace_id","name","description","agent_id","context_graph_id","keyterms","is_active","version_sets","tags","tool_capacity","created_at","updated_at"],"title":"ServiceResponse"},"VersionSet-Output":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"LLMConfig":{"properties":{"llm_name":{"type":"string","title":"Llm Name"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"experience_controls":{"anyOf":[{"$ref":"#/components/schemas/LLMExperienceControls"},{"type":"null"}]}},"type":"object","required":["llm_name"],"title":"LLMConfig"},"LLMExperienceControls":{"properties":{"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}],"title":"Reasoning Effort"},"temperature":{"anyOf":[{"type":"number","maximum":2,"minimum":0},{"type":"null"}],"title":"Temperature"},"top_p":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Top P"}},"additionalProperties":false,"type":"object","title":"LLMExperienceControls","description":"Typed model-tuning controls for a version set's LLM preference.\n\n``params`` remains available as a provider-specific escape hatch. These three\nfields are the ones deployments actually use; the surface was trimmed from\nnineteen in V370 after a production census found the other sixteen had never\nbeen set to a non-null value by anyone. Token budgets are intentionally\nexcluded so version sets do not reintroduce accidental response truncation."},"ServiceTag":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["key"],"title":"ServiceTag"},"ServiceVoiceConfig-Output":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."},"RealtimeSessionConfig":{"properties":{"model":{"anyOf":[{"type":"string","enum":["gpt-realtime-2.1","gpt-realtime-2.1-mini"]},{"type":"null"}],"title":"Model"},"voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"$ref":"#/components/schemas/RealtimeCustomVoice"},{"type":"null"}],"title":"Voice"},"speed":{"anyOf":[{"type":"number","maximum":1.5,"minimum":0.25},{"type":"null"}],"title":"Speed"},"noise_reduction":{"anyOf":[{"type":"string","enum":["near_field","far_field","off"]},{"type":"null"}],"title":"Noise Reduction","description":"Input noise reduction. Omit or set null to use the Platform default; set 'off' to disable it."},"transcription":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTranscriptionConfig"},{"type":"null"}]},"turn_detection":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/RealtimeServerVadConfig"},{"$ref":"#/components/schemas/RealtimeSemanticVadConfig"}],"discriminator":{"propertyName":"type","mapping":{"semantic_vad":"#/components/schemas/RealtimeSemanticVadConfig","server_vad":"#/components/schemas/RealtimeServerVadConfig"}}},{"type":"null"}],"title":"Turn Detection"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort"},"max_output_tokens":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"string","const":"inf"},{"type":"null"}],"title":"Max Output Tokens"},"truncation":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTruncationConfig"},{"type":"null"}]},"required_tool_on_first_caller_turn":{"anyOf":[{"type":"string","maxLength":256,"minLength":1,"pattern":"^[A-Za-z_][A-Za-z0-9_.:-]*$"},{"type":"null"}],"title":"Required Tool On First Caller Turn","description":"Force one named function on the first caller-generated response, excluding the inbound greeting, then restore automatic tool choice. Runtime accepts this only for source_override='test' sessions and tools that the executor verifies are read-only or side-effect-free."}},"additionalProperties":false,"type":"object","title":"RealtimeSessionConfig","description":"Typed OpenAI Realtime session controls for a service."},"RealtimeCustomVoice":{"properties":{"id":{"type":"string","maxLength":256,"minLength":1,"pattern":"^voice_[A-Za-z0-9_-]+$","title":"Id"}},"additionalProperties":false,"type":"object","required":["id"],"title":"RealtimeCustomVoice","description":"Approved OpenAI custom voice reference."},"RealtimeTranscriptionConfig":{"properties":{"model":{"type":"string","const":"gpt-transcribe","title":"Model","default":"gpt-transcribe"},"language":{"anyOf":[{"type":"string","maxLength":35,"minLength":2,"pattern":"^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$"},{"type":"null"}],"title":"Language"},"prompt":{"anyOf":[{"type":"string","maxLength":1024,"minLength":1},{"type":"null"}],"title":"Prompt"}},"additionalProperties":false,"type":"object","title":"RealtimeTranscriptionConfig","description":"Asynchronous caller-audio transcription used for transcripts and observability."},"RealtimeServerVadConfig":{"properties":{"type":{"type":"string","const":"server_vad","title":"Type","default":"server_vad"},"threshold":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Threshold"},"prefix_padding_ms":{"anyOf":[{"type":"integer","maximum":5000,"minimum":0},{"type":"null"}],"title":"Prefix Padding Ms"},"silence_duration_ms":{"anyOf":[{"type":"integer","maximum":10000,"minimum":0},{"type":"null"}],"title":"Silence Duration Ms"},"idle_timeout_ms":{"anyOf":[{"type":"integer","maximum":30000,"minimum":5000},{"type":"null"}],"title":"Idle Timeout Ms"}},"additionalProperties":false,"type":"object","title":"RealtimeServerVadConfig","description":"Volume-based turn detection controls."},"RealtimeSemanticVadConfig":{"properties":{"type":{"type":"string","const":"semantic_vad","title":"Type","default":"semantic_vad"},"eagerness":{"type":"string","enum":["auto","low","medium","high"],"title":"Eagerness","default":"auto"}},"additionalProperties":false,"type":"object","title":"RealtimeSemanticVadConfig","description":"Semantic turn detection controls."},"RealtimeTruncationConfig":{"properties":{"type":{"type":"string","enum":["auto","disabled","retention_ratio"],"title":"Type","default":"auto"},"retention_ratio":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Retention Ratio"},"post_instructions_tokens":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Post Instructions Tokens"}},"additionalProperties":false,"type":"object","title":"RealtimeTruncationConfig","description":"Conversation context truncation strategy."},"ServiceForwardingConfig":{"properties":{"forward_to":{"anyOf":[{"$ref":"#/components/schemas/PhoneE164"},{"type":"null"}]},"warm_transfer":{"type":"boolean","title":"Warm Transfer"},"approved_destinations":{"additionalProperties":{"$ref":"#/components/schemas/NameString"},"propertyNames":{"$ref":"#/components/schemas/PhoneE164"},"type":"object","maxProperties":50,"title":"Approved Destinations"}},"type":"object","required":["forward_to","warm_transfer"],"title":"ServiceForwardingConfig","description":"Per-service call-forwarding destination + transfer mechanism.\n\nThis block gates the ``forward_call`` tool: None means the agent cannot\ntransfer at all. When present, ``forward_to`` picks the destination mode,\nand the tool schema follows it — a static service gets an argument-less\ntool, a dynamic one gets a required ``phone_number`` that must be one of\n``approved_destinations`` (none approved means no tool). Nothing cascades:\na service is one mode or the other."},"PhoneE164":{"type":"string","maxLength":16,"minLength":2},"NameString":{"type":"string","maxLength":256,"minLength":1},"ContextKeySpec":{"properties":{"key":{"$ref":"#/components/schemas/SlugString"},"type":{"type":"string","enum":["string","number"],"title":"Type"},"description":{"$ref":"#/components/schemas/DescriptionString"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["key","type","description","required"],"title":"ContextKeySpec","description":"One key a conversation may supply as start-time context for a service.\n\nThe value is validated against ``type`` at conversation start; a tool can then\nbind the key to one of its parameters (injected, hidden from the model)."},"SlugString":{"type":"string","maxLength":63,"minLength":2,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"},"DescriptionString":{"type":"string","maxLength":2000},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v1/{workspace_id}/services/{service_id}":{"get":{"tags":["Services"],"summary":"Get a service","description":"Retrieve a service by ID. Requires `Service.view` permission.","operationId":"get-service","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update a service

> Update a service's configuration. Requires \`Service.update\` permission.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"UpdateServiceRequest":{"properties":{"name":{"anyOf":[{"$ref":"#/components/schemas/NameString"},{"type":"null"}]},"description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]},"agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"},"context_graph_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Context Graph Id"},"keyterms":{"anyOf":[{"items":{"type":"string","maxLength":128,"minLength":1},"type":"array","maxItems":500},{"type":"null"}],"title":"Keyterms"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"version_sets":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Input"},"type":"object"},{"type":"null"}],"title":"Version Sets"},"tags":{"anyOf":[{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","maxItems":50},{"type":"null"}],"title":"Tags"},"tool_capacity":{"anyOf":[{"type":"integer","maximum":10,"minimum":1},{"type":"null"}],"title":"Tool Capacity"},"channel_type":{"anyOf":[{"type":"string","enum":["voice","text"]},{"type":"null"}],"title":"Channel Type"},"environment":{"anyOf":[{"type":"string","enum":["sandbox","production"]},{"type":"null"}],"title":"Environment"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Input"},{"type":"null"}]},"accepted_context":{"anyOf":[{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","maxItems":100},{"type":"null"}],"title":"Accepted Context"}},"type":"object","title":"UpdateServiceRequest"},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"VersionSet-Input":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"LLMConfig":{"properties":{"llm_name":{"type":"string","title":"Llm Name"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"experience_controls":{"anyOf":[{"$ref":"#/components/schemas/LLMExperienceControls"},{"type":"null"}]}},"type":"object","required":["llm_name"],"title":"LLMConfig"},"LLMExperienceControls":{"properties":{"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}],"title":"Reasoning Effort"},"temperature":{"anyOf":[{"type":"number","maximum":2,"minimum":0},{"type":"null"}],"title":"Temperature"},"top_p":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Top P"}},"additionalProperties":false,"type":"object","title":"LLMExperienceControls","description":"Typed model-tuning controls for a version set's LLM preference.\n\n``params`` remains available as a provider-specific escape hatch. These three\nfields are the ones deployments actually use; the surface was trimmed from\nnineteen in V370 after a production census found the other sixteen had never\nbeen set to a non-null value by anyone. Token budgets are intentionally\nexcluded so version sets do not reintroduce accidental response truncation."},"ServiceTag":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["key"],"title":"ServiceTag"},"ServiceVoiceConfig-Input":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."},"RealtimeSessionConfig":{"properties":{"model":{"anyOf":[{"type":"string","enum":["gpt-realtime-2.1","gpt-realtime-2.1-mini"]},{"type":"null"}],"title":"Model"},"voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"$ref":"#/components/schemas/RealtimeCustomVoice"},{"type":"null"}],"title":"Voice"},"speed":{"anyOf":[{"type":"number","maximum":1.5,"minimum":0.25},{"type":"null"}],"title":"Speed"},"noise_reduction":{"anyOf":[{"type":"string","enum":["near_field","far_field","off"]},{"type":"null"}],"title":"Noise Reduction","description":"Input noise reduction. Omit or set null to use the Platform default; set 'off' to disable it."},"transcription":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTranscriptionConfig"},{"type":"null"}]},"turn_detection":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/RealtimeServerVadConfig"},{"$ref":"#/components/schemas/RealtimeSemanticVadConfig"}],"discriminator":{"propertyName":"type","mapping":{"semantic_vad":"#/components/schemas/RealtimeSemanticVadConfig","server_vad":"#/components/schemas/RealtimeServerVadConfig"}}},{"type":"null"}],"title":"Turn Detection"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort"},"max_output_tokens":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"string","const":"inf"},{"type":"null"}],"title":"Max Output Tokens"},"truncation":{"anyOf":[{"$ref":"#/components/schemas/RealtimeTruncationConfig"},{"type":"null"}]},"required_tool_on_first_caller_turn":{"anyOf":[{"type":"string","maxLength":256,"minLength":1,"pattern":"^[A-Za-z_][A-Za-z0-9_.:-]*$"},{"type":"null"}],"title":"Required Tool On First Caller Turn","description":"Force one named function on the first caller-generated response, excluding the inbound greeting, then restore automatic tool choice. Runtime accepts this only for source_override='test' sessions and tools that the executor verifies are read-only or side-effect-free."}},"additionalProperties":false,"type":"object","title":"RealtimeSessionConfig","description":"Typed OpenAI Realtime session controls for a service."},"RealtimeCustomVoice":{"properties":{"id":{"type":"string","maxLength":256,"minLength":1,"pattern":"^voice_[A-Za-z0-9_-]+$","title":"Id"}},"additionalProperties":false,"type":"object","required":["id"],"title":"RealtimeCustomVoice","description":"Approved OpenAI custom voice reference."},"RealtimeTranscriptionConfig":{"properties":{"model":{"type":"string","const":"gpt-transcribe","title":"Model","default":"gpt-transcribe"},"language":{"anyOf":[{"type":"string","maxLength":35,"minLength":2,"pattern":"^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$"},{"type":"null"}],"title":"Language"},"prompt":{"anyOf":[{"type":"string","maxLength":1024,"minLength":1},{"type":"null"}],"title":"Prompt"}},"additionalProperties":false,"type":"object","title":"RealtimeTranscriptionConfig","description":"Asynchronous caller-audio transcription used for transcripts and observability."},"RealtimeServerVadConfig":{"properties":{"type":{"type":"string","const":"server_vad","title":"Type","default":"server_vad"},"threshold":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Threshold"},"prefix_padding_ms":{"anyOf":[{"type":"integer","maximum":5000,"minimum":0},{"type":"null"}],"title":"Prefix Padding Ms"},"silence_duration_ms":{"anyOf":[{"type":"integer","maximum":10000,"minimum":0},{"type":"null"}],"title":"Silence Duration Ms"},"idle_timeout_ms":{"anyOf":[{"type":"integer","maximum":30000,"minimum":5000},{"type":"null"}],"title":"Idle Timeout Ms"}},"additionalProperties":false,"type":"object","title":"RealtimeServerVadConfig","description":"Volume-based turn detection controls."},"RealtimeSemanticVadConfig":{"properties":{"type":{"type":"string","const":"semantic_vad","title":"Type","default":"semantic_vad"},"eagerness":{"type":"string","enum":["auto","low","medium","high"],"title":"Eagerness","default":"auto"}},"additionalProperties":false,"type":"object","title":"RealtimeSemanticVadConfig","description":"Semantic turn detection controls."},"RealtimeTruncationConfig":{"properties":{"type":{"type":"string","enum":["auto","disabled","retention_ratio"],"title":"Type","default":"auto"},"retention_ratio":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Retention Ratio"},"post_instructions_tokens":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Post Instructions Tokens"}},"additionalProperties":false,"type":"object","title":"RealtimeTruncationConfig","description":"Conversation context truncation strategy."},"ServiceForwardingConfig":{"properties":{"forward_to":{"anyOf":[{"$ref":"#/components/schemas/PhoneE164"},{"type":"null"}]},"warm_transfer":{"type":"boolean","title":"Warm Transfer"},"approved_destinations":{"additionalProperties":{"$ref":"#/components/schemas/NameString"},"propertyNames":{"$ref":"#/components/schemas/PhoneE164"},"type":"object","maxProperties":50,"title":"Approved Destinations"}},"type":"object","required":["forward_to","warm_transfer"],"title":"ServiceForwardingConfig","description":"Per-service call-forwarding destination + transfer mechanism.\n\nThis block gates the ``forward_call`` tool: None means the agent cannot\ntransfer at all. When present, ``forward_to`` picks the destination mode,\nand the tool schema follows it — a static service gets an argument-less\ntool, a dynamic one gets a required ``phone_number`` that must be one of\n``approved_destinations`` (none approved means no tool). Nothing cascades:\na service is one mode or the other."},"PhoneE164":{"type":"string","maxLength":16,"minLength":2},"ContextKeySpec":{"properties":{"key":{"$ref":"#/components/schemas/SlugString"},"type":{"type":"string","enum":["string","number"],"title":"Type"},"description":{"$ref":"#/components/schemas/DescriptionString"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["key","type","description","required"],"title":"ContextKeySpec","description":"One key a conversation may supply as start-time context for a service.\n\nThe value is validated against ``type`` at conversation start; a tool can then\nbind the key to one of its parameters (injected, hidden from the model)."},"SlugString":{"type":"string","maxLength":63,"minLength":2,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"},"ServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"context_graph_id":{"type":"string","format":"uuid","title":"Context Graph Id"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"context_graph_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context Graph Name"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"is_active":{"type":"boolean","title":"Is Active"},"version_sets":{"additionalProperties":{"$ref":"#/components/schemas/VersionSet-Output"},"type":"object","title":"Version Sets"},"tags":{"items":{"$ref":"#/components/schemas/ServiceTag"},"type":"array","title":"Tags"},"tool_capacity":{"type":"integer","title":"Tool Capacity"},"channel_type":{"type":"string","enum":["voice","text"],"title":"Channel Type","default":"voice"},"environment":{"type":"string","enum":["sandbox","production"],"title":"Environment","default":"production"},"voice_config":{"anyOf":[{"$ref":"#/components/schemas/ServiceVoiceConfig-Output"},{"type":"null"}]},"accepted_context":{"items":{"$ref":"#/components/schemas/ContextKeySpec"},"type":"array","title":"Accepted Context"},"is_system":{"type":"boolean","title":"Is System","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","workspace_id","name","description","agent_id","context_graph_id","keyterms","is_active","version_sets","tags","tool_capacity","created_at","updated_at"],"title":"ServiceResponse"},"VersionSet-Output":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"ServiceVoiceConfig-Output":{"properties":{"max_buffer_delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Buffer Delay Ms"},"eager_eot_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Eager Eot Threshold"},"eot_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eot Timeout Ms"},"filler_style":{"type":"string","enum":["backchannel","phrase","silent"],"title":"Filler Style","default":"backchannel"},"filler_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Filler Vocabulary"},"backchannel_delay_ms":{"type":"integer","title":"Backchannel Delay Ms","default":400},"max_response_sentences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Sentences"},"max_response_words":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Response Words"},"barge_in_min_speech_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Min Speech S"},"barge_in_cooldown_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Barge In Cooldown S"},"min_tts_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Tts Speed"},"post_eot_pause_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Eot Pause Ms"},"transition_deadline_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transition Deadline Ms"},"progress_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress Interval Ms"},"empathy_hold_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Empathy Hold Ms"},"filler_cooldown_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filler Cooldown Ms"},"progress_vocabulary":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Progress Vocabulary"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object","maxProperties":10},{"type":"null"}],"title":"Language Providers"},"session_provider":{"anyOf":[{"type":"string","enum":["amigo","gpt_realtime"]},{"type":"null"}],"title":"Session Provider"},"realtime_voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Realtime Voice","description":"Deprecated built-in OpenAI Realtime voice shortcut. Use realtime.voice instead; the two fields are mutually exclusive.","deprecated":true},"realtime":{"anyOf":[{"$ref":"#/components/schemas/RealtimeSessionConfig"},{"type":"null"}]},"forwarding":{"anyOf":[{"$ref":"#/components/schemas/ServiceForwardingConfig"},{"type":"null"}]}},"type":"object","title":"ServiceVoiceConfig","description":"Per-service voice pipeline tuning. Overrides workspace/env defaults.\n\nEach field is optional — None means inherit from the layer above\n(workspace VoiceSettings → env vars → hardcoded defaults)."}}},"paths":{"/v1/{workspace_id}/services/{service_id}":{"put":{"tags":["Services"],"summary":"Update a service","description":"Update a service's configuration. Requires `Service.update` permission.","operationId":"update-service","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateServiceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"409":{"description":"Name already taken."},"422":{"description":"Invalid request body."}}}}}}
```

## Delete a service

> Delete a service. Requires \`Service.delete\` permission.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v1/{workspace_id}/services/{service_id}":{"delete":{"tags":["Services"],"summary":"Delete a service","description":"Delete a service. Requires `Service.delete` permission.","operationId":"delete-service","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Upsert a service version set

> Replace or create a named version set on a service. The name and pinned agent and context graph versions are validated.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"UpsertVersionSetRequest":{"properties":{"version_set":{"$ref":"#/components/schemas/VersionSet-Input"}},"type":"object","required":["version_set"],"title":"UpsertVersionSetRequest"},"VersionSet-Input":{"properties":{"agent_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agent Version Number"},"context_graph_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Graph Version Number"},"llm_model_preferences":{"additionalProperties":{"$ref":"#/components/schemas/LLMConfig"},"type":"object","title":"Llm Model Preferences"}},"type":"object","title":"VersionSet","description":"Pins agent, state machine, and LLM model versions for a service."},"LLMConfig":{"properties":{"llm_name":{"type":"string","title":"Llm Name"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"experience_controls":{"anyOf":[{"$ref":"#/components/schemas/LLMExperienceControls"},{"type":"null"}]}},"type":"object","required":["llm_name"],"title":"LLMConfig"},"LLMExperienceControls":{"properties":{"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}],"title":"Reasoning Effort"},"temperature":{"anyOf":[{"type":"number","maximum":2,"minimum":0},{"type":"null"}],"title":"Temperature"},"top_p":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Top P"}},"additionalProperties":false,"type":"object","title":"LLMExperienceControls","description":"Typed model-tuning controls for a version set's LLM preference.\n\n``params`` remains available as a provider-specific escape hatch. These three\nfields are the ones deployments actually use; the surface was trimmed from\nnineteen in V370 after a production census found the other sixteen had never\nbeen set to a non-null value by anyone. Token budgets are intentionally\nexcluded so version sets do not reintroduce accidental response truncation."}}},"paths":{"/v1/{workspace_id}/services/{service_id}/version-sets/{name}":{"put":{"tags":["Services"],"summary":"Upsert a service version set","description":"Replace or create a named version set on a service. The name and pinned agent and context graph versions are validated.","operationId":"upsert-service-version-set","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","maxLength":40,"description":"Version set name (e.g. 'release')","title":"Name"},"description":"Version set name (e.g. 'release')"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertVersionSetRequest"}}}},"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid API key."},"403":{"description":"Insufficient permissions."},"404":{"description":"Not found."},"409":{"description":"Name already taken."},"422":{"description":"Invalid request body."}}}}}}
```

## Voice Turn

> Run one WhatsApp-style voice-note turn against the service's agent.\
> \
> Accepts OGG Opus audio (or any format Deepgram's prerecorded endpoint\
> accepts). Server keys the conversation on \`\`(workspace, service,\
> phone\_number)\`\` and returns the agent's spoken reply as OGG Opus — or WAV\
> PCM16 when the \`\`Accept\`\` header prefers \`\`audio/wav\`\`.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://platform.api-us.concurrence.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"Body_voice-turn":{"properties":{"audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio"},"phone_number":{"type":"string","maxLength":16,"pattern":"^\\+[1-9]\\d{1,14}$","title":"Phone Number"}},"type":"object","required":["audio","phone_number"],"title":"Body_voice-turn"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v1/{workspace_id}/services/{service_id}/voice-turn":{"post":{"tags":["Services"],"summary":"Voice Turn","description":"Run one WhatsApp-style voice-note turn against the service's agent.\n\nAccepts OGG Opus audio (or any format Deepgram's prerecorded endpoint\naccepts). Server keys the conversation on ``(workspace, service,\nphone_number)`` and returns the agent's spoken reply as OGG Opus — or WAV\nPCM16 when the ``Accept`` header prefers ``audio/wav``.","operationId":"voice-turn","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"accept","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accept"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_voice-turn"}}}},"responses":{"200":{"description":"Agent spoken reply — OGG Opus by default, WAV PCM16 (16 kHz mono) when the request's Accept header prefers audio/wav","content":{"application/json":{"schema":{}},"audio/ogg":{},"audio/wav":{}}},"204":{"description":"Agent elected silence"},"409":{"description":"Concurrent voice turn in progress for this speaker"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.concurrence.com/api-reference/readme/platform/services.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
