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

# Services

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.

{% hint style="info" %}
**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.
{% endhint %}

## 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).

## Endpoints

### Create a Service

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### List Services

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Get a Service

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Update a Service

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}" method="put" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Delete a Service

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}" method="delete" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Upsert a Version Set

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}/version-sets/{name}" method="put" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Process a Voice-Note Turn

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}/voice-turn" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Process a Text Turn

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/services/{service\_id}/text-turn" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Version Sets

{% hint style="warning" %}
**Model ID validation.** When creating or updating a service, every `llm_name` in `version_sets.llm_model_preferences` must belong to a supported provider family. Unroutable model identifiers are rejected with a `422` response listing the offending entries. This validation applies only at write time - existing configurations are not affected on read.
{% endhint %}

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.

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.

```mermaid
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#D4E2E7", "primaryTextColor": "#100F0F", "primaryBorderColor": "#083241", "lineColor": "#575452", "textColor": "#100F0F", "clusterBkg": "#F1EAE7", "clusterBorder": "#D7D2D0"}}}%%
flowchart TB
    A[personal-dev] -->|validate| B[test]
    B -->|run simulations| C[preview]
    C -->|UAT + promote| D[release]
```

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.

{% hint style="warning" %}
When creating a service with a non-empty `version_sets` map, or replacing that map during an update, include `release`. The single-version upsert can create or replace `release` or a custom set. It validates pinned agent and context graph versions. Names must match `^[A-Za-z0-9_-]+$` (max 40 characters).
{% endhint %}

## 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.

```json
{
  "actions": [
    { "description": "Look up available appointment slots", "filler_hint": "Let me check what's available..." },
    { "description": "Confirm the appointment with the user", "filler_hint": null }
  ],
  "exit_conditions": [
    { "description": "Appointment confirmed", "next_state": "wrap_up", "filler_hint": "Great, I've got that booked." }
  ]
}
```

{% hint style="info" %}
**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.
{% endhint %}

## 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`        | Amigo's own voice pipeline (STT, reasoning, TTS). The default. |
| `gpt_realtime` | GPT realtime speech-to-speech model family                     |
| `gpt_live`     | GPT-Live full-duplex 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](/developer-guide/platform-api/workspaces/voice-configuration.md) for field-level inheritance and defaults.

### Fields

**Latency**

| Field                 | Type                           | Default         | Description                                                                                                                 |
| --------------------- | ------------------------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `tts_model`           | `"sonic-turbo"` or `"sonic-3"` | `"sonic-turbo"` | TTS model selection. `sonic-turbo` targets 40ms time-to-first-audio; `sonic-3` targets 90ms with higher speech quality.     |
| `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"` | `backchannel` produces short acknowledgments like "Mm" and "Yeah". `phrase` produces longer fillers like "Let me check on that". `silent` disables fillers entirely. |
| `filler_vocabulary`    | `list[str]`                                | -               | Custom filler words. Overrides the default vocabulary for the selected filler style.                                                                                 |
| `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` | -       | Hard cap on response length in sentences. This is mechanically enforced (the pipeline truncates), not just prompted. |
| `max_response_words`     | `int` | -       | Hard cap on response length in words. Same mechanical enforcement.                                                   |

**Barge-in**

| Field                   | Type    | Default | Description                                                                                                                                                                            |
| ----------------------- | ------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `barge_in_min_speech_s` | `float` | `0.25`  | 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. |

**Tools**

| Field                  | Type   | Default | Description                                                                                                        |
| ---------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `forward_call_enabled` | `bool` | `false` | Whether the `forward_call` tool is available. Opt-in because call forwarding has cost and compliance implications. |

### Presets

Agent Forge provides five named presets:

| Preset              | TTS Model     | Buffer | Filler Style  | Backchannel Delay | Response Cap |
| ------------------- | ------------- | ------ | ------------- | ----------------- | ------------ |
| `ultra_low_latency` | `sonic-turbo` | 200ms  | `backchannel` | 400ms             | 1 sentence   |
| `balanced`          | defaults      | 500ms  | defaults      | defaults          | -            |
| `quality`           | `sonic-3`     | 500ms  | `phrase`      | defaults          | -            |
| `gpt_live`          | n/a           | n/a    | n/a           | n/a               | n/a          |
| `gpt_realtime`      | n/a           | n/a    | n/a           | n/a               | n/a          |

### Example

Include `voice_config` when creating or updating a service:

```json
{
  "name": "Intake Line",
  "agent_id": "abc123",
  "context_graph_id": "def456",
  "voice_config": {
    "tts_model": "sonic-turbo",
    "max_buffer_delay_ms": 200,
    "filler_style": "backchannel",
    "backchannel_delay_ms": 400,
    "max_response_sentences": 1,
    "barge_in_min_speech_s": 0.25,
    "min_tts_speed": 0.92,
    "forward_call_enabled": false
  }
}
```

### CLI

Apply a preset:

```bash
forge platform service voice-config <service_id> --preset ultra_low_latency
```

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):

```bash
forge platform service voice-config <service_id> --body '{"filler_style": "silent", "max_response_sentences": 1}'
```

Read current config:

```bash
forge platform service voice-config <service_id> --get
```

### API

Use [Update a Service](#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](#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](/developer-guide/platform-api/workspaces/voice-configuration.md#turn-level-emotion-selection) for the available emotions and how the empathy system can override the selection, and [Voice Agent](/developer-guide/platform-api/conversations/voice-agent.md) for the emotional adaptation behavior.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/platform-api/workspaces/services.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
