> 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/classic-api/core-api/services.md).

# Services

Discover, create, and manage the services that users converse with. A service pairs an agent with a context graph under a single service ID, and version sets control which versions of each are deployed to each environment.

## Understanding Amigo Services

Your integration may include multiple service types, each designed for specific interaction scenarios:

* **Meet & Greet**: optimized for new user onboarding
* **Adaptive Support**: designed for returning user support

Each service has a unique service ID that you reference when creating conversations. Services are configured with Context Graphs (the API may call these "state machines") that define how agents navigate problem spaces. Learn more about Context Graphs in the [Conceptual Documentation](https://docs.amigo.ai/agent/context-graphs).

{% hint style="info" %}
For enterprise voice and EHR workflows, see [Platform API: Services](/developer-guide/platform-api/workspaces/services.md).
{% endhint %}

Services can be connected in a workflow (for example, Meet & Greet leading to Adaptive Support), but you still start each conversation with the correct service ID so the user lands in the right experience.

### Service Routing Flow

```mermaid
%%{init: {"flowchart": {"useMaxWidth": true, "nodeSpacing": 30, "rankSpacing": 40}, "theme": "base", "themeVariables": {"primaryColor": "#D4E2E7", "primaryTextColor": "#100F0F", "primaryBorderColor": "#083241", "lineColor": "#575452", "textColor": "#100F0F", "clusterBkg": "#F1EAE7", "clusterBorder": "#D7D2D0"}}}%%
flowchart TB
    Start([User Arrives]) --> Check{Has account?}
    Check -->|No| MeetGreet[Meet & Greet Service]
    Check -->|Yes| Returning{Returning user?}

    MeetGreet -->|completes onboarding| Onboard[User Onboarded]
    Onboard --> Adaptive[Adaptive Support Service]

    Returning -->|Yes| Adaptive
    Returning -->|No| MeetGreet

    Adaptive --> Interaction[User Interaction]
    Interaction --> Return{User returns later?}
    Return -->|Yes| Adaptive

    style MeetGreet fill:#DDE3DB,stroke:#2c3827,color:#100F0F,stroke-width:2px
    style Adaptive fill:#F0DDD9,stroke:#AA412A,color:#100F0F,stroke-width:2px
    style Start fill:#D4E2E7,stroke:#083241,color:#100F0F,stroke-width:2px
    style Onboard fill:#E8E2EB,stroke:#C5BACE,color:#100F0F,stroke-width:2px
```

## Retrieving Available Services

To discover all available services for your organization:

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request GET \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/?limit=10&is_active=true' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>' \
     --header 'Accept: application/json'
```

{% endtab %}

{% tab title="Python SDK" %}

```python
from amigo_sdk import AmigoClient
from amigo_sdk.models import GetServicesParametersQuery

with AmigoClient() as client:
    services = client.services.get_services(
        GetServicesParametersQuery(limit=10, is_active=True)
    )

    for service in services.services:
        print(f"Service: {service.name} (ID: {service.id})")
```

*Note: Async version also available with `async with AsyncAmigoClient()`*
{% endtab %}

{% tab title="TypeScript SDK" %}

```typescript
import { AmigoClient } from "@amigo-ai/sdk";

const client = new AmigoClient({ ...config });
const services = await client.services.getServices({
  limit: 10,
  is_active: true,
});

services.services?.forEach((service) => {
  console.log(`Service: ${service.name} (ID: ${service.id})`);
});
```

{% endtab %}
{% endtabs %}

The response contains the matching services alongside pagination fields (`has_more`, `continuation_token`) and, on the first page, `filter_values` listing the dynamic filter values available.

```json
{
  "services": [
    {
      "id": "6618791275130b73714e8d1c",
      "name": "Meet & Greet",
      "description": "A service that handles a scenario",
      "is_active": true,
      "service_hierarchical_state_machine_id": "6618791375530b73714e8d1a",
      "agent_id": "6618791275530b73714e9d18",
      "version_sets": {
        "release": {
          "agent_version_number": 2,
          "service_hierarchical_state_machine_version_number": 3,
          "llm_model_preferences": {}
        }
      },
      "tags": [{"key": "team", "value": "support"}],
      "keyterms": ["amigo"],
      "creator": {"org_id": "<YOUR-ORG-ID>", "user_id": "6618791275130b73714e0001"},
      "updated_by": {"org_id": "<YOUR-ORG-ID>", "user_id": "6618791275130b73714e0001"}
    }
  ],
  "has_more": false,
  "continuation_token": null,
  "filter_values": {
    "tags": ["team:support"]
  }
}
```

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Create a Service

Create a new service that pairs an agent with a context graph. The new service automatically gets an `edge` version set that tracks the latest agent and context graph versions with no LLM model preference, plus a `release` version set that equals the request's `release_version_set` if specified, or `edge` otherwise. Creating an active service fails if an active service with the same name already exists.

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request POST \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>' \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --data '{
  "service_hierarchical_state_machine_id": "8b5c6599bfb8ffc45646b289",
  "agent_id": "0d0b781189c14189526c2603",
  "name": "New Service",
  "description": "A description",
  "is_active": true,
  "keyterms": ["amigo"],
  "tags": {"team": "support"}
}'
```

{% endtab %}

{% tab title="Python SDK" %}

```python
from amigo_sdk import AmigoClient
from amigo_sdk.generated.model import ServiceCreateServiceRequest

with AmigoClient() as client:
    result = client.services.create_service(
        ServiceCreateServiceRequest(
            service_hierarchical_state_machine_id="8b5c6599bfb8ffc45646b289",
            agent_id="0d0b781189c14189526c2603",
            name="New Service",
            description="A description",
            is_active=True,
            keyterms=["amigo"],
            tags={"team": "support"},
        )
    )
    print(f"Created service: {result.id}")
```

*Note: Async version also available with `async with AsyncAmigoClient()`*
{% endtab %}

{% tab title="TypeScript SDK" %}

```typescript
import { AmigoClient, serviceId } from "@amigo-ai/sdk";

const client = new AmigoClient({ ...config });
const result = await client.services.createService({
  body: {
    service_hierarchical_state_machine_id: "8b5c6599bfb8ffc45646b289",
    agent_id: "0d0b781189c14189526c2603",
    name: "New Service",
    description: "A description",
    is_active: true,
    keyterms: ["amigo"],
    tags: { team: "support" },
  },
});
console.log(`Created service: ${result.id}`);
```

{% endtab %}
{% endtabs %}

The response will contain the ID of the created service:

```json
{
  "id": "6618791275130b73714e8d1c"
}
```

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Update a Service

Update a service's fields: `name`, `description`, `is_active`, `agent_id`, `service_hierarchical_state_machine_id`, `tags`, and `keyterms`. Only the fields you provide (non-null) are updated.

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request POST \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/<SERVICE-ID>/' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>' \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --data '{"is_active": false}'
```

{% endtab %}

{% tab title="Python SDK" %}

```python
from amigo_sdk import AmigoClient
from amigo_sdk.generated.model import ServiceUpdateServiceRequest

with AmigoClient() as client:
    client.services.update_service(
        service_id="6618791275130b73714e8d1c",
        body=ServiceUpdateServiceRequest(is_active=False),
    )
```

*Note: Async version also available with `async with AsyncAmigoClient()`*
{% endtab %}

{% tab title="TypeScript SDK" %}

```typescript
import { AmigoClient, serviceId } from "@amigo-ai/sdk";

const client = new AmigoClient({ ...config });
await client.services.updateService({
  serviceId: serviceId("6618791275130b73714e8d1c"),
  body: { is_active: false },
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Deactivating a service (`is_active: false`) returns an error if the service is used in a simulation unit test. Activating a service fails if another active service already has the same name.
{% endhint %}

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

## Service Mapping Best Practices

{% hint style="success" %}
**Effective Service Routing**

For effective service routing in your application:

1. **Service ID Persistence**: store service IDs in your system with descriptive labels.
2. **User Journey Mapping**: map user states to the right services. For example, first-time users go to a Meet & Greet service (service ID: `67a23a08b02fe1e74341a6f8`), and returning users go to a Reactive Support service (service ID: `675769a1d71dbf8cf042271f`).
3. **Dynamic Routing**: implement logic in your application to direct users to the appropriate service based on their status or needs.
   {% endhint %}

## Service Versioning with Version Sets

Services use **version sets** to manage deployments across different environments. Each service can have multiple version sets (for example, `"release"`, `"staging"`, `"dev"`), so you can test and promote changes without modifying the service ID.

### What are Version Sets?

A version set is a named configuration that pins version numbers for the agent and context graph the service already references (`agent_id` and `service_hierarchical_state_machine_id` live on the service itself):

* **Agent version** (`agent_version_number`; `null` selects the latest agent version)
* **Context Graph version** (`service_hierarchical_state_machine_version_number`; `null` selects the latest version)
* **LLM Model Preferences** (`llm_model_preferences`, model configuration for this deployment)

This enables safe, controlled deployment:

```
Service: "Customer Support"
├─ Version Set: "release" → Agent v2.1, Context Graph v3.0, premium-tier model
├─ Version Set: "staging" → Agent v2.2, Context Graph v3.1, standard-tier model
└─ Version Set: "dev" → Agent v3.0, Context Graph v4.0, economy-tier model
```

### Using Version Sets

When creating conversations, specify the version set:

* **`service_version_set_name`**: the version set to use (typically `"release"` for production)
* **`service_id`**: the unique identifier for the service

**Example:**

```json
{
  "service_id": "6618791275130b73714e8d1c",
  "service_version_set_name": "release"
}
```

This approach gives you:

* **Stable production** through the `"release"` version set
* **Safe testing** through `"staging"` or `"dev"` version sets
* **Zero-downtime deployments** by updating version sets without changing service\_id
* **Easy rollback** by reverting version set configurations

For more on managing version sets and promotion workflows, see [Version Sets Best Practices](/developer-guide/operations/devops/version-sets-best-practices.md).

## Dynamic Behaviors

Services can be extended with **Dynamic Behaviors**: reusable, versioned, trigger-based rules that inject instructions or modify tool availability when specific conversation patterns are detected. Behavior sets attach at the service level through the behavior set's own applied-services list and active flag, managed through the dynamic behavior set endpoints - they are not part of a service's version sets, so they cannot be staged per version set. See the endpoint reference for creating, versioning, and monitoring behavior sets:

{% content-ref url="/pages/bXk6Ps8872nrs4Ca5J6o" %}
[Broken mention](broken://pages/bXk6Ps8872nrs4Ca5J6o)
{% endcontent-ref %}

## Reading Version Sets

There is no standalone read endpoint for a single version set. Version sets are returned on the service object - list services and read the `version_sets` map on the service you care about:

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request GET \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/?id=<SERVICE-ID>' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>' \
     --header 'Accept: application/json'
```

{% endtab %}

{% tab title="Python" %}

```python
import os
import requests

ORG_ID = os.environ["AMIGO_ORG_ID"]
TOKEN = os.environ["AMIGO_TOKEN"]

response = requests.get(
    f"https://api.amigo.ai/v1/{ORG_ID}/service/",
    params={"id": service_id},
    headers={"Authorization": f"Bearer {TOKEN}"},
    timeout=15,
)
response.raise_for_status()
service = response.json()["services"][0]
print(service["version_sets"].get("release"))
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const response = await fetch(
  `https://api.amigo.ai/v1/${orgId}/service/?id=${serviceId}`,
  { headers: { Authorization: `Bearer ${token}` } }
);
const { services } = await response.json();
console.log(services[0].version_sets["release"]);
```

{% endtab %}
{% endtabs %}

## Upsert a Version Set

Create or update a version set for a service. This is an idempotent operation: if the version set already exists it is updated; otherwise it is created.

The request body wraps a single `version_set` object with three required keys: `agent_version_number`, `service_hierarchical_state_machine_version_number` (either can be `null` to select the latest version), and `llm_model_preferences`.

{% hint style="warning" %}
The `edge` version set cannot be updated.
{% endhint %}

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request PUT \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/<SERVICE-ID>/version_sets/staging/' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>' \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --data '{
  "version_set": {
    "agent_version_number": 2,
    "service_hierarchical_state_machine_version_number": 3,
    "llm_model_preferences": {}
  }
}'
```

{% endtab %}

{% tab title="Python SDK" %}

```python
from amigo_sdk import AmigoClient
from amigo_sdk.generated.model import ServiceUpsertServiceVersionSetRequest

with AmigoClient() as client:
    client.services.upsert_version_set(
        service_id="6618791275130b73714e8d1c",
        version_set_name="staging",
        body=ServiceUpsertServiceVersionSetRequest(
            version_set={
                "agent_version_number": 2,
                "service_hierarchical_state_machine_version_number": 3,
                "llm_model_preferences": {},
            },
        ),
    )
```

*Note: Async version also available with `async with AsyncAmigoClient()`*
{% endtab %}

{% tab title="TypeScript SDK" %}

```typescript
import { AmigoClient, serviceId } from "@amigo-ai/sdk";

const client = new AmigoClient({ ...config });
await client.services.upsertVersionSet({
  serviceId: serviceId("6618791275130b73714e8d1c"),
  versionSetName: "staging",
  body: {
    version_set: {
      agent_version_number: 2,
      service_hierarchical_state_machine_version_number: 3,
      llm_model_preferences: {},
    },
  },
});
```

{% endtab %}
{% endtabs %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/{service\_id}/version\_sets/{version\_set\_name}/" method="put" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Delete a Version Set

Remove a version set from a service. This operation cannot be undone. The request returns an error if the version set is used in any simulation unit tests.

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request DELETE \
     --url 'https://api.amigo.ai/v1/<YOUR-ORG-ID>/service/<SERVICE-ID>/version_sets/staging/' \
     --header 'Authorization: Bearer <AUTH-TOKEN-OF-USER>'
```

{% endtab %}

{% tab title="Python SDK" %}

```python
from amigo_sdk import AmigoClient

with AmigoClient() as client:
    client.services.delete_version_set(
        service_id="6618791275130b73714e8d1c",
        version_set_name="staging",
    )
```

*Note: Async version also available with `async with AsyncAmigoClient()`*
{% endtab %}

{% tab title="TypeScript SDK" %}

```typescript
import { AmigoClient, serviceId } from "@amigo-ai/sdk";

const client = new AmigoClient({ ...config });
await client.services.deleteVersionSet({
  serviceId: serviceId("6618791275130b73714e8d1c"),
  versionSetName: "staging",
});
```

{% endtab %}
{% endtabs %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/{service\_id}/version\_sets/{version\_set\_name}/" method="delete" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}


---

# 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/classic-api/core-api/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.
