For the complete documentation index, see llms.txt. This page is also available as Markdown.

Services

Bind agents and context graphs into deployable services, manage version sets, and configure voice behavior for conversations across supported channels.

A service binds an agent, a context graph, and version sets into a deployable unit. Services are the entry point for conversations: when a user calls a phone number or starts a chat, the platform resolves the service to determine which agent persona, conversation flow, and model configuration to use.

Classic API vs Platform API: These APIs expose separate service resources. Platform services are workspace-scoped and their IDs are used with Platform conversation and call routes. Classic service IDs are organization-scoped and used with Classic conversation routes.

Key Concepts

  • Agent and context graph binding: every service links to one agent and one context graph.

  • Version sets: named configurations that pin specific agent and context graph versions and LLM model preferences.

  • Tags: key-value metadata stored with the service.

  • Channel type: the separate channel_type field declares whether the service is for voice or text conversations.

  • Tool capacity: maximum concurrent tool executions per conversation (1-10, default 3).

  • Accepted conversation context: the accepted_context schema declares which string and number values callers may supply when starting a conversation.

Endpoints

Create a Service

Create a service

post

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.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Body
namestring · min: 1 · max: 256Required
descriptionstring · max: 2000OptionalDefault: ""
agent_idstring · uuidRequired
context_graph_idstring · uuidRequired
keytermsstring[] · max: 500Optional
is_activebooleanOptionalDefault: true
tool_capacityinteger · min: 1 · max: 10OptionalDefault: 3
channel_typestring · enumOptionalDefault: voicePossible values:
environmentstring · enumOptionalDefault: productionPossible values:
Responses
201

Successful Response

application/json
idstring · uuidRequired
workspace_idstring · uuidRequired
namestringRequired
descriptionstringRequired
agent_idstring · uuidRequired
context_graph_idstring · uuidRequired
agent_namestring · nullableOptional
context_graph_namestring · nullableOptional
keytermsstring[]Required
is_activebooleanRequired
tool_capacityintegerRequired
channel_typestring · enumOptionalDefault: voicePossible values:
environmentstring · enumOptionalDefault: productionPossible values:
is_systembooleanOptionalDefault: false
created_atstring · date-timeRequired
updated_atstring · date-timeRequired
post/v1/{workspace_id}/services
POST /v1/{workspace_id}/services HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 1910

{
  "name": "text",
  "description": "",
  "agent_id": "123e4567-e89b-12d3-a456-426614174000",
  "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
  "keyterms": [
    "text"
  ],
  "is_active": true,
  "version_sets": {
    "ANY_ADDITIONAL_PROPERTY": {
      "agent_version_number": 1,
      "context_graph_version_number": 1,
      "llm_model_preferences": {
        "ANY_ADDITIONAL_PROPERTY": {
          "llm_name": "text",
          "params": {
            "ANY_ADDITIONAL_PROPERTY": "anything"
          },
          "experience_controls": {
            "reasoning_effort": "none",
            "temperature": 1,
            "top_p": 1
          }
        }
      }
    }
  },
  "tags": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "tool_capacity": 3,
  "channel_type": "voice",
  "environment": "production",
  "voice_config": {
    "max_buffer_delay_ms": 1,
    "eager_eot_threshold": 1,
    "eot_timeout_ms": 1,
    "filler_style": "backchannel",
    "filler_vocabulary": [
      "text"
    ],
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "max_response_words": 1,
    "barge_in_min_speech_s": 1,
    "barge_in_cooldown_s": 1,
    "min_tts_speed": 1,
    "post_eot_pause_ms": 1,
    "transition_deadline_ms": 1,
    "progress_interval_ms": 1,
    "empathy_hold_ms": 1,
    "filler_cooldown_ms": 1,
    "progress_vocabulary": [
      "text"
    ],
    "tts_provider": "cartesia",
    "tts_config": {
      "ANY_ADDITIONAL_PROPERTY": "anything"
    },
    "language_providers": {
      "ANY_ADDITIONAL_PROPERTY": {
        "provider": "cartesia",
        "config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        }
      }
    },
    "session_provider": "amigo",
    "realtime": {
      "model": "gpt-realtime-2.1",
      "voice": "alloy",
      "speed": 1,
      "noise_reduction": "near_field",
      "transcription": {
        "model": "gpt-transcribe",
        "language": "text",
        "prompt": "text"
      },
      "turn_detection": {
        "type": "server_vad",
        "threshold": 1,
        "prefix_padding_ms": 1,
        "silence_duration_ms": 1,
        "idle_timeout_ms": 1
      },
      "reasoning_effort": "low",
      "max_output_tokens": 1,
      "truncation": {
        "type": "auto",
        "retention_ratio": 1,
        "post_instructions_tokens": 1
      },
      "required_tool_on_first_caller_turn": "text"
    },
    "forwarding": {
      "forward_to": "text",
      "warm_transfer": true,
      "approved_destinations": {
        "ANY_ADDITIONAL_PROPERTY": "text"
      }
    }
  },
  "accepted_context": [
    {
      "key": "text",
      "type": "string",
      "description": "text",
      "required": true
    }
  ]
}
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "text",
  "description": "text",
  "agent_id": "123e4567-e89b-12d3-a456-426614174000",
  "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
  "agent_name": "text",
  "context_graph_name": "text",
  "keyterms": [
    "text"
  ],
  "is_active": true,
  "version_sets": {
    "ANY_ADDITIONAL_PROPERTY": {
      "agent_version_number": 1,
      "context_graph_version_number": 1,
      "llm_model_preferences": {
        "ANY_ADDITIONAL_PROPERTY": {
          "llm_name": "text",
          "params": {
            "ANY_ADDITIONAL_PROPERTY": "anything"
          },
          "experience_controls": {
            "reasoning_effort": "none",
            "temperature": 1,
            "top_p": 1
          }
        }
      }
    }
  },
  "tags": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "tool_capacity": 1,
  "channel_type": "voice",
  "environment": "production",
  "voice_config": {
    "max_buffer_delay_ms": 1,
    "eager_eot_threshold": 1,
    "eot_timeout_ms": 1,
    "filler_style": "backchannel",
    "filler_vocabulary": [
      "text"
    ],
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "max_response_words": 1,
    "barge_in_min_speech_s": 1,
    "barge_in_cooldown_s": 1,
    "min_tts_speed": 1,
    "post_eot_pause_ms": 1,
    "transition_deadline_ms": 1,
    "progress_interval_ms": 1,
    "empathy_hold_ms": 1,
    "filler_cooldown_ms": 1,
    "progress_vocabulary": [
      "text"
    ],
    "tts_provider": "cartesia",
    "tts_config": {
      "ANY_ADDITIONAL_PROPERTY": "anything"
    },
    "language_providers": {
      "ANY_ADDITIONAL_PROPERTY": {
        "provider": "cartesia",
        "config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        }
      }
    },
    "session_provider": "amigo",
    "realtime": {
      "model": "gpt-realtime-2.1",
      "voice": "alloy",
      "speed": 1,
      "noise_reduction": "near_field",
      "transcription": {
        "model": "gpt-transcribe",
        "language": "text",
        "prompt": "text"
      },
      "turn_detection": {
        "type": "server_vad",
        "threshold": 1,
        "prefix_padding_ms": 1,
        "silence_duration_ms": 1,
        "idle_timeout_ms": 1
      },
      "reasoning_effort": "low",
      "max_output_tokens": 1,
      "truncation": {
        "type": "auto",
        "retention_ratio": 1,
        "post_instructions_tokens": 1
      },
      "required_tool_on_first_caller_turn": "text"
    },
    "forwarding": {
      "forward_to": "text",
      "warm_transfer": true,
      "approved_destinations": {
        "ANY_ADDITIONAL_PROPERTY": "text"
      }
    }
  },
  "accepted_context": [
    {
      "key": "text",
      "type": "string",
      "description": "text",
      "required": true
    }
  ],
  "is_system": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

List Services

Filter by agent_id or context_graph_id to find the services that run a given agent or Context Graph. Filters apply before pagination.

List services

get

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.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Query parameters
sort_bystring[]OptionalDefault: []
limitinteger · max: 200OptionalDefault: 50
continuation_tokenanyOptional
searchstring · min: 1 · max: 200 · nullableOptional
is_activeboolean · nullableOptional
agent_idstring · uuid · nullableOptional

Only services on this agent. Each version set pins a version of its service's agent.

context_graph_idstring · uuid · nullableOptional

Only services on this context graph. Each version set pins a version of its service's context graph.

Responses
200

Successful Response

application/json
has_morebooleanRequired
continuation_tokenanyOptional
get/v1/{workspace_id}/services
GET /v1/{workspace_id}/services HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "items": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "text",
      "description": "text",
      "agent_id": "123e4567-e89b-12d3-a456-426614174000",
      "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
      "agent_name": "text",
      "context_graph_name": "text",
      "keyterms": [
        "text"
      ],
      "is_active": true,
      "version_sets": {
        "ANY_ADDITIONAL_PROPERTY": {
          "agent_version_number": 1,
          "context_graph_version_number": 1,
          "llm_model_preferences": {
            "ANY_ADDITIONAL_PROPERTY": {
              "llm_name": "text",
              "params": {
                "ANY_ADDITIONAL_PROPERTY": "anything"
              },
              "experience_controls": {
                "reasoning_effort": "none",
                "temperature": 1,
                "top_p": 1
              }
            }
          }
        }
      },
      "tags": [
        {
          "key": "text",
          "value": "text"
        }
      ],
      "tool_capacity": 1,
      "channel_type": "voice",
      "environment": "production",
      "voice_config": {
        "max_buffer_delay_ms": 1,
        "eager_eot_threshold": 1,
        "eot_timeout_ms": 1,
        "filler_style": "backchannel",
        "filler_vocabulary": [
          "text"
        ],
        "backchannel_delay_ms": 400,
        "max_response_sentences": 1,
        "max_response_words": 1,
        "barge_in_min_speech_s": 1,
        "barge_in_cooldown_s": 1,
        "min_tts_speed": 1,
        "post_eot_pause_ms": 1,
        "transition_deadline_ms": 1,
        "progress_interval_ms": 1,
        "empathy_hold_ms": 1,
        "filler_cooldown_ms": 1,
        "progress_vocabulary": [
          "text"
        ],
        "tts_provider": "cartesia",
        "tts_config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        },
        "language_providers": {
          "ANY_ADDITIONAL_PROPERTY": {
            "provider": "cartesia",
            "config": {
              "ANY_ADDITIONAL_PROPERTY": "anything"
            }
          }
        },
        "session_provider": "amigo",
        "realtime": {
          "model": "gpt-realtime-2.1",
          "voice": "alloy",
          "speed": 1,
          "noise_reduction": "near_field",
          "transcription": {
            "model": "gpt-transcribe",
            "language": "text",
            "prompt": "text"
          },
          "turn_detection": {
            "type": "server_vad",
            "threshold": 1,
            "prefix_padding_ms": 1,
            "silence_duration_ms": 1,
            "idle_timeout_ms": 1
          },
          "reasoning_effort": "low",
          "max_output_tokens": 1,
          "truncation": {
            "type": "auto",
            "retention_ratio": 1,
            "post_instructions_tokens": 1
          },
          "required_tool_on_first_caller_turn": "text"
        },
        "forwarding": {
          "forward_to": "text",
          "warm_transfer": true,
          "approved_destinations": {
            "ANY_ADDITIONAL_PROPERTY": "text"
          }
        }
      },
      "accepted_context": [
        {
          "key": "text",
          "type": "string",
          "description": "text",
          "required": true
        }
      ],
      "is_system": false,
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "has_more": true,
  "continuation_token": null
}

Get a Service

Get a service

get

Retrieve a service by ID. Requires Service.view permission.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
service_idstring · uuidRequired
Responses
200

Successful Response

application/json
idstring · uuidRequired
workspace_idstring · uuidRequired
namestringRequired
descriptionstringRequired
agent_idstring · uuidRequired
context_graph_idstring · uuidRequired
agent_namestring · nullableOptional
context_graph_namestring · nullableOptional
keytermsstring[]Required
is_activebooleanRequired
tool_capacityintegerRequired
channel_typestring · enumOptionalDefault: voicePossible values:
environmentstring · enumOptionalDefault: productionPossible values:
is_systembooleanOptionalDefault: false
created_atstring · date-timeRequired
updated_atstring · date-timeRequired
get/v1/{workspace_id}/services/{service_id}
GET /v1/{workspace_id}/services/{service_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "text",
  "description": "text",
  "agent_id": "123e4567-e89b-12d3-a456-426614174000",
  "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
  "agent_name": "text",
  "context_graph_name": "text",
  "keyterms": [
    "text"
  ],
  "is_active": true,
  "version_sets": {
    "ANY_ADDITIONAL_PROPERTY": {
      "agent_version_number": 1,
      "context_graph_version_number": 1,
      "llm_model_preferences": {
        "ANY_ADDITIONAL_PROPERTY": {
          "llm_name": "text",
          "params": {
            "ANY_ADDITIONAL_PROPERTY": "anything"
          },
          "experience_controls": {
            "reasoning_effort": "none",
            "temperature": 1,
            "top_p": 1
          }
        }
      }
    }
  },
  "tags": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "tool_capacity": 1,
  "channel_type": "voice",
  "environment": "production",
  "voice_config": {
    "max_buffer_delay_ms": 1,
    "eager_eot_threshold": 1,
    "eot_timeout_ms": 1,
    "filler_style": "backchannel",
    "filler_vocabulary": [
      "text"
    ],
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "max_response_words": 1,
    "barge_in_min_speech_s": 1,
    "barge_in_cooldown_s": 1,
    "min_tts_speed": 1,
    "post_eot_pause_ms": 1,
    "transition_deadline_ms": 1,
    "progress_interval_ms": 1,
    "empathy_hold_ms": 1,
    "filler_cooldown_ms": 1,
    "progress_vocabulary": [
      "text"
    ],
    "tts_provider": "cartesia",
    "tts_config": {
      "ANY_ADDITIONAL_PROPERTY": "anything"
    },
    "language_providers": {
      "ANY_ADDITIONAL_PROPERTY": {
        "provider": "cartesia",
        "config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        }
      }
    },
    "session_provider": "amigo",
    "realtime": {
      "model": "gpt-realtime-2.1",
      "voice": "alloy",
      "speed": 1,
      "noise_reduction": "near_field",
      "transcription": {
        "model": "gpt-transcribe",
        "language": "text",
        "prompt": "text"
      },
      "turn_detection": {
        "type": "server_vad",
        "threshold": 1,
        "prefix_padding_ms": 1,
        "silence_duration_ms": 1,
        "idle_timeout_ms": 1
      },
      "reasoning_effort": "low",
      "max_output_tokens": 1,
      "truncation": {
        "type": "auto",
        "retention_ratio": 1,
        "post_instructions_tokens": 1
      },
      "required_tool_on_first_caller_turn": "text"
    },
    "forwarding": {
      "forward_to": "text",
      "warm_transfer": true,
      "approved_destinations": {
        "ANY_ADDITIONAL_PROPERTY": "text"
      }
    }
  },
  "accepted_context": [
    {
      "key": "text",
      "type": "string",
      "description": "text",
      "required": true
    }
  ],
  "is_system": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Update a Service

Omitted top-level fields and fields sent as null leave their stored values unchanged. Explicit non-null values, including an empty description, is_active: false, or empty keyterms and tags lists, are applied when valid for the field.

A supplied voice_config object replaces the stored voice configuration. Nested nulls accepted by its schema are preserved, including forwarding.forward_to: null for dynamic forwarding. Sending voice_config: null leaves the existing configuration unchanged. Read the current configuration first and resend the complete object when changing it.

Update a service

put

Update a service's configuration. Requires Service.update permission.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
service_idstring · uuidRequired
Body
namestring · min: 1 · max: 256 · nullableOptional
descriptionstring · max: 2000 · nullableOptional
agent_idstring · uuid · nullableOptional
context_graph_idstring · uuid · nullableOptional
keytermsstring[] · max: 500 · nullableOptional
is_activeboolean · nullableOptional
tool_capacityinteger · min: 1 · max: 10 · nullableOptional
channel_typestring · enum · nullableOptionalPossible values:
environmentstring · enum · nullableOptionalPossible values:
Responses
200

Successful Response

application/json
idstring · uuidRequired
workspace_idstring · uuidRequired
namestringRequired
descriptionstringRequired
agent_idstring · uuidRequired
context_graph_idstring · uuidRequired
agent_namestring · nullableOptional
context_graph_namestring · nullableOptional
keytermsstring[]Required
is_activebooleanRequired
tool_capacityintegerRequired
channel_typestring · enumOptionalDefault: voicePossible values:
environmentstring · enumOptionalDefault: productionPossible values:
is_systembooleanOptionalDefault: false
created_atstring · date-timeRequired
updated_atstring · date-timeRequired
put/v1/{workspace_id}/services/{service_id}
PUT /v1/{workspace_id}/services/{service_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 1911

{
  "name": "text",
  "description": "text",
  "agent_id": "123e4567-e89b-12d3-a456-426614174000",
  "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
  "keyterms": [
    "text"
  ],
  "is_active": true,
  "version_sets": {
    "ANY_ADDITIONAL_PROPERTY": {
      "agent_version_number": 1,
      "context_graph_version_number": 1,
      "llm_model_preferences": {
        "ANY_ADDITIONAL_PROPERTY": {
          "llm_name": "text",
          "params": {
            "ANY_ADDITIONAL_PROPERTY": "anything"
          },
          "experience_controls": {
            "reasoning_effort": "none",
            "temperature": 1,
            "top_p": 1
          }
        }
      }
    }
  },
  "tags": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "tool_capacity": 1,
  "channel_type": "voice",
  "environment": "sandbox",
  "voice_config": {
    "max_buffer_delay_ms": 1,
    "eager_eot_threshold": 1,
    "eot_timeout_ms": 1,
    "filler_style": "backchannel",
    "filler_vocabulary": [
      "text"
    ],
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "max_response_words": 1,
    "barge_in_min_speech_s": 1,
    "barge_in_cooldown_s": 1,
    "min_tts_speed": 1,
    "post_eot_pause_ms": 1,
    "transition_deadline_ms": 1,
    "progress_interval_ms": 1,
    "empathy_hold_ms": 1,
    "filler_cooldown_ms": 1,
    "progress_vocabulary": [
      "text"
    ],
    "tts_provider": "cartesia",
    "tts_config": {
      "ANY_ADDITIONAL_PROPERTY": "anything"
    },
    "language_providers": {
      "ANY_ADDITIONAL_PROPERTY": {
        "provider": "cartesia",
        "config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        }
      }
    },
    "session_provider": "amigo",
    "realtime": {
      "model": "gpt-realtime-2.1",
      "voice": "alloy",
      "speed": 1,
      "noise_reduction": "near_field",
      "transcription": {
        "model": "gpt-transcribe",
        "language": "text",
        "prompt": "text"
      },
      "turn_detection": {
        "type": "server_vad",
        "threshold": 1,
        "prefix_padding_ms": 1,
        "silence_duration_ms": 1,
        "idle_timeout_ms": 1
      },
      "reasoning_effort": "low",
      "max_output_tokens": 1,
      "truncation": {
        "type": "auto",
        "retention_ratio": 1,
        "post_instructions_tokens": 1
      },
      "required_tool_on_first_caller_turn": "text"
    },
    "forwarding": {
      "forward_to": "text",
      "warm_transfer": true,
      "approved_destinations": {
        "ANY_ADDITIONAL_PROPERTY": "text"
      }
    }
  },
  "accepted_context": [
    {
      "key": "text",
      "type": "string",
      "description": "text",
      "required": true
    }
  ]
}
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "text",
  "description": "text",
  "agent_id": "123e4567-e89b-12d3-a456-426614174000",
  "context_graph_id": "123e4567-e89b-12d3-a456-426614174000",
  "agent_name": "text",
  "context_graph_name": "text",
  "keyterms": [
    "text"
  ],
  "is_active": true,
  "version_sets": {
    "ANY_ADDITIONAL_PROPERTY": {
      "agent_version_number": 1,
      "context_graph_version_number": 1,
      "llm_model_preferences": {
        "ANY_ADDITIONAL_PROPERTY": {
          "llm_name": "text",
          "params": {
            "ANY_ADDITIONAL_PROPERTY": "anything"
          },
          "experience_controls": {
            "reasoning_effort": "none",
            "temperature": 1,
            "top_p": 1
          }
        }
      }
    }
  },
  "tags": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "tool_capacity": 1,
  "channel_type": "voice",
  "environment": "production",
  "voice_config": {
    "max_buffer_delay_ms": 1,
    "eager_eot_threshold": 1,
    "eot_timeout_ms": 1,
    "filler_style": "backchannel",
    "filler_vocabulary": [
      "text"
    ],
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "max_response_words": 1,
    "barge_in_min_speech_s": 1,
    "barge_in_cooldown_s": 1,
    "min_tts_speed": 1,
    "post_eot_pause_ms": 1,
    "transition_deadline_ms": 1,
    "progress_interval_ms": 1,
    "empathy_hold_ms": 1,
    "filler_cooldown_ms": 1,
    "progress_vocabulary": [
      "text"
    ],
    "tts_provider": "cartesia",
    "tts_config": {
      "ANY_ADDITIONAL_PROPERTY": "anything"
    },
    "language_providers": {
      "ANY_ADDITIONAL_PROPERTY": {
        "provider": "cartesia",
        "config": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        }
      }
    },
    "session_provider": "amigo",
    "realtime": {
      "model": "gpt-realtime-2.1",
      "voice": "alloy",
      "speed": 1,
      "noise_reduction": "near_field",
      "transcription": {
        "model": "gpt-transcribe",
        "language": "text",
        "prompt": "text"
      },
      "turn_detection": {
        "type": "server_vad",
        "threshold": 1,
        "prefix_padding_ms": 1,
        "silence_duration_ms": 1,
        "idle_timeout_ms": 1
      },
      "reasoning_effort": "low",
      "max_output_tokens": 1,
      "truncation": {
        "type": "auto",
        "retention_ratio": 1,
        "post_instructions_tokens": 1
      },
      "required_tool_on_first_caller_turn": "text"
    },
    "forwarding": {
      "forward_to": "text",
      "warm_transfer": true,
      "approved_destinations": {
        "ANY_ADDITIONAL_PROPERTY": "text"
      }
    }
  },
  "accepted_context": [
    {
      "key": "text",
      "type": "string",
      "description": "text",
      "required": true
    }
  ],
  "is_system": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Delete a Service

Delete a service

delete

Delete a service. Requires Service.delete permission.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
service_idstring · uuidRequired
Responses
204

Successful Response

No content

delete/v1/{workspace_id}/services/{service_id}
DELETE /v1/{workspace_id}/services/{service_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*

No content

Upsert a Version Set

Upsert a service version set

put

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

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
service_idstring · uuidRequired
namestring · max: 40Required

Version set name (e.g. 'release')

Body
Responses
204

Successful Response

No content

put/v1/{workspace_id}/services/{service_id}/version-sets/{name}
PUT /v1/{workspace_id}/services/{service_id}/version-sets/{name} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 271

{
  "version_set": {
    "agent_version_number": 1,
    "context_graph_version_number": 1,
    "llm_model_preferences": {
      "ANY_ADDITIONAL_PROPERTY": {
        "llm_name": "text",
        "params": {
          "ANY_ADDITIONAL_PROPERTY": "anything"
        },
        "experience_controls": {
          "reasoning_effort": "none",
          "temperature": 1,
          "top_p": 1
        }
      }
    }
  }
}

No content

Process a Voice-Note Turn

Voice Turn

post

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.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
service_idstring · uuidRequired
Header parameters
acceptstring · nullableOptional
Body
audiostringRequired
phone_numberstring · max: 16RequiredPattern: ^\+[1-9]\d{1,14}$
Responses
200

Agent spoken reply — OGG Opus by default, WAV PCM16 (16 kHz mono) when the request's Accept header prefers audio/wav

anyOptional
post/v1/{workspace_id}/services/{service_id}/voice-turn
POST /v1/{workspace_id}/services/{service_id}/voice-turn HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: multipart/form-data
Accept: */*
Content-Length: 38

{
  "audio": "text",
  "phone_number": "text"
}

No content

Text Conversations

The former service text-turn endpoint has been removed. Use Conversations for application-hosted text and the managed channel integrations for SMS and WhatsApp.

Accepted Conversation Context

Declare accepted_context on the service's create or update request. Each entry specifies a unique key, a type of string or number, a description, and a required flag. Conversation creation validates its parsed context map against this schema; unknown keys, missing required keys, and values that fail this validation return 422. The guide below also covers a boolean-coercion edge case in request parsing.

Update the service with PUT /v1/{workspace_id}/services/{service_id}. A supplied accepted_context list replaces the entire previous list. Omission or null preserves it; [] accepts no caller-supplied context keys. Coordinate newly required keys with callers before changing a shared service.

The service declares the schema; the active Context Graph's state-to-tool specification declares context_bindings. Follow Pass Context to Tool Parameters for a complete setup, supported tool paths, and mapped parameter names and automatic channel-id prerequisites.

The same declaration governs values a trusted backend sets on a live voice call. Declare such a key with required: false; on voice, a tool bound to it refuses to run until it is set. See Set Context on a Live Voice Call.

Version Sets

Creating a service, updating it, and upserting a version set all check the version sets they write. A version set name must match [A-Za-z0-9_-]{1,40}, or the request returns 422. Each pinned agent and Context Graph version must exist for the service's agent and graph, or the request returns 404. Changing a service's agent_id or context_graph_id checks its stored pins against the new target.

Version sets support an optional llm_model_preferences map that overrides the default models used for context graph navigation and conversational engagement. Each key identifies a model role: use nav for navigation and engage for response generation. Each value specifies the preferred model and optional parameters for that role. When omitted, sessions use the platform defaults.

This lets you pin specific agent versions to specific models for controlled rollouts, A/B testing, or compliance requirements that mandate a fixed model version.

Model preference resolution order

  1. Version set override - If the active version set has an llm_model_preferences entry for the relevant role, that model is used.

  2. Platform default - If no override is configured, the platform default model is used.

The resolved model is applied consistently across voice sessions, text sessions, and simulation runs.

Tool Turns and Reasoning Effort

On gpt-5.4, gpt-5.5, gpt-5.6, and gpt-6 engage models, a turn that offers the model tools is sent at reasoning_effort none, the only effort those models accept with tools. A turn without tools uses the configured effort.

Because a higher effort would not be honored on tool turns, creating or updating a service, or upserting a version set, returns 422 when an engage preference for one of these models sets reasoning_effort above none in params or experience_controls. The message names the version set, the preference, and the model. Leave the effort unset or set it to none. A version set saved before this check still loads, but its next save fails until the effort is fixed.

Version sets enable safe iteration, like Git branches for your service configuration:

  • release: the required default version set used when clients do not specify one. Service creation adds an unpinned release set when version_sets is omitted or empty.

  • Custom sets: create named sets (for example, personal-dev, test, or preview) for your promotion workflow. Leaving a version number unset resolves the latest available version at runtime.

The recommended promotion path: personal-dev → test → preview → release

Manage Platform version sets through service updates or the single-version upsert endpoint. Agent Forge also provides forge platform version-set commands for listing, inspecting, upserting, comparing, promoting, and rolling back sets. Mutating commands are dry-run by default and require --apply to execute.

Structured Actions

Context Graph action states use a structured Action model. Each action and exit condition can carry a filler_hint, a semantic direction that guides the voice pipeline's filler generation alongside emotional context and latency state.

Filler hints are not literal audio fillers. They are semantic directions; the voice pipeline uses them alongside real-time emotional and latency context to produce natural-sounding filler speech.

Voice Configuration

Session Provider

The voice_config.session_provider field controls which voice session runtime drives calls for a service. Supported values:

Value
Description

amigo

Concurrence's own voice pipeline (STT, reasoning, TTS). The default.

gpt_realtime

GPT realtime speech-to-speech model family

When the service field is unset, it inherits the agent-level provider and then the environment default, which is normally amigo. The session provider can also be set on the service detail page in the Console.

The platform resolves the session provider with the following precedence: service > agent > environment default.

voice_config is an optional field on the service model that controls how the voice pipeline behaves for that service. It covers latency tuning, filler behavior, response length, barge-in sensitivity, and tool access. If omitted, the service has no service-level overrides. See Voice Configuration for field-level inheritance and defaults.

Fields

Latency

Field
Type
Default
Description

max_buffer_delay_ms

int (200 to 1000)

500

How long the pipeline buffers text before sending to TTS. Lower values feel snappier but may produce choppier speech.

eager_eot_threshold

float (0.0 to 1.0)

-

End-of-turn sensitivity. Higher values make the system more aggressive about detecting when the caller has stopped talking.

eot_timeout_ms

int

-

Hard timeout for end-of-turn detection in milliseconds.

Fillers

Field
Type
Default
Description

filler_style

"backchannel", "phrase", or "silent"

"backchannel"

Only silent changes runtime behavior: it mutes the agent's autonomous backchannels. backchannel and phrase are currently advisory, and Context Graph progress phrases still play under silent. See Voice Configuration.

filler_vocabulary

list[str]

-

Custom words for the short acknowledgment played when navigation is skipped. Tool-wait phrases come from progress_vocabulary or Context Graph progress phrases.

backchannel_delay_ms

int

400

Delay before emitting a backchannel filler when navigation is skipped. Controls how quickly the agent acknowledges the caller.

Response

Field
Type
Default
Description

max_response_sentences

int

-

Streamed-response sentence cap. Counting is approximate across streamed fragments.

max_response_words

int

-

Streamed-response word cap, enforced while consuming generated text.

Barge-in

Field
Type
Default
Description

barge_in_min_speech_s

float

0.5

Minimum speech duration before the caller can interrupt the agent. Lower values make barge-in more sensitive. Setting this too low causes false interrupts from breath sounds or "um".

barge_in_cooldown_s

float

1.5

Cooldown period after a barge-in before another one can trigger. Prevents rapid-fire interruptions.

Speed

Field
Type
Default
Description

min_tts_speed

float (0.5 to 1.0)

-

Minimum TTS speed multiplier. When the emotion engine reduces speech rate in response to caller distress, it cannot go below this value. The empathy formula produces speeds in the 0.85-0.97 range; set this somewhere in that band if the agent sounds unnaturally slow after emotional turns. Omit to use the default unclamped behavior.

Call Forwarding

Configure forwarding in voice_config.forwarding. Omitting that block or setting it to null leaves the forwarding tool unavailable. When present, choose warm or cold transfer explicitly and configure either a fixed destination or dynamic destination mode. There is no workspace-number fallback.

Dynamic mode (forward_to: null) dials only the numbers listed in approved_destinations, a map of E.164 number to label with up to 50 entries. A dynamic block with no approved destinations offers no forward_call tool, and approved_destinations with a fixed forward_to returns 422. See Call Forwarding for an example.

The removed forward_call_enabled flag is not the current enablement control. The embedded service schema is authoritative for the forwarding object. Active turn policy can further restrict forwarding. See Call Forwarding for the hold and answer-handling sequence.

Presets

Agent Forge provides four named presets:

Preset
Buffer
Filler Style
Backchannel Delay
Response Cap

ultra_low_latency

200ms

backchannel

400ms

1 sentence

balanced

500ms

defaults

defaults

-

quality

500ms

phrase

defaults

-

gpt_realtime

n/a

n/a

n/a

n/a

Presets no longer select a Cartesia model. The service tts_model field they set was removed on October 9, 2026, so a sent value is ignored. Pin a model in tts_config.model; see Default TTS Model.

Example

Include voice_config when creating or updating a service:

CLI

Apply a preset:

Set config fields (the body replaces the stored voice config as a whole - read the current config first and include every field you want to keep):

Read current config:

API

Use Update a Service with the voice_config field in the request body. The field replaces the stored voice config as a whole. Omitted fields resolve through their field-specific defaults or inheritance rules. Read the current config first (--get or Get a Service) and resend the full object with your changes.

Turn-Level Emotion

On each turn, the voice pipeline selects an emotional tone alongside the state transition and applies it to the entire utterance - filler and main response share the same tone, so the whole turn has consistent prosody with no mid-sentence shifts. See Voice Configuration for the available emotions and how the empathy system can override the selection, and Voice Agent for the emotional adaptation behavior.

Last updated

Was this helpful?