> ## Documentation Index
> Fetch the complete documentation index at: https://hobbyist-e43fa225.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage hosted agents

> View, monitor, and manage hosted agents in Foundry Agent Service by using the REST API, Python SDK, or Azure Developer CLI.

export const ZonePivot = ({group, options = [], defaultValue, label = "Choose an experience"}) => {
  const values = options.map(option => option.id);
  const optionKey = options.map(option => `${option.id}:${option.title}`).join("|");
  const [activePivot, setActivePivot] = useState(defaultValue || values[0]);
  const slugify = value => value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
  const resolvePivot = () => {
    if (typeof window === "undefined") return defaultValue || values[0];
    const params = new URLSearchParams(window.location.search);
    const requested = params.get("pivots");
    if (requested) {
      const requestedIds = requested.split(",").map(value => value.trim()).filter(Boolean);
      const match = requestedIds.find(id => values.includes(id));
      if (match) return match;
    }
    const hash = window.location.hash.replace(/^#/, "");
    if (hash) {
      const match = options.find(option => option.id === hash || slugify(option.title) === hash);
      if (match) return match.id;
    }
    try {
      const stored = window.localStorage.getItem(`foundry-zone-pivot:${group}`);
      if (values.includes(stored)) return stored;
    } catch {
      return defaultValue || values[0];
    }
    return defaultValue || values[0];
  };
  const publishPivotChange = value => {
    if (typeof window === "undefined") return;
    window.dispatchEvent(new CustomEvent("foundry-zone-pivot-change", {
      detail: {
        group,
        value
      }
    }));
  };
  const syncTableOfContents = () => {
    if (typeof window === "undefined") return;
    window.requestAnimationFrame(() => {
      const toc = document.getElementById("table-of-contents-content");
      if (!toc) return;
      const links = Array.from(toc.querySelectorAll('a[href^="#"]'));
      for (const link of links) {
        const item = link.closest("li");
        const rawId = link.getAttribute("href")?.slice(1);
        if (!item || !rawId) continue;
        let id = rawId;
        try {
          id = decodeURIComponent(rawId);
        } catch {}
        item.style.display = document.getElementById(id) ? "" : "none";
      }
    });
  };
  useEffect(() => {
    const resolvedPivot = resolvePivot();
    setActivePivot(resolvedPivot);
    publishPivotChange(resolvedPivot);
    window.setTimeout(syncTableOfContents, 0);
  }, [group, defaultValue, values.join("|"), optionKey]);
  const selectPivot = value => {
    setActivePivot(value);
    if (typeof window !== "undefined") {
      try {
        window.localStorage.setItem(`foundry-zone-pivot:${group}`, value);
      } catch {}
      const url = new URL(window.location.href);
      const current = url.searchParams.get("pivots");
      const preserved = current ? current.split(",").map(id => id.trim()).filter(id => id && !values.includes(id)) : [];
      url.searchParams.set("pivots", [...preserved, value].join(","));
      window.history.replaceState(null, "", `${url.pathname}${url.search}${url.hash}`);
    }
    publishPivotChange(value);
    window.setTimeout(syncTableOfContents, 0);
  };
  if (options.length < 2) return null;
  return <div className="not-prose my-6 border-b border-slate-200 pb-3 dark:border-slate-800">
      <div className="mb-2 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">
        {label}
      </div>
      <div className="flex flex-wrap gap-2" role="tablist" aria-label={label}>
        {options.map(option => {
    const selected = option.id === activePivot;
    return <button key={option.id} type="button" role="tab" aria-selected={selected} onClick={() => selectPivot(option.id)} className={`rounded-md border px-3 py-1.5 text-sm font-medium transition ${selected ? "border-slate-900 bg-slate-900 text-white shadow-sm dark:border-slate-100 dark:bg-slate-100 dark:text-slate-950" : "border-slate-200 bg-white text-slate-700 hover:border-slate-400 hover:text-slate-950 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-200 dark:hover:border-slate-500"}`}>
              {option.title}
            </button>;
  })}
      </div>
    </div>;
};

export const ZoneContent = ({group, value, options = [], values = [], defaultValue, children}) => {
  const optionKey = options.map(option => `${option.id}:${option.title}`).join("|");
  const [activePivot, setActivePivot] = useState(defaultValue || values[0]);
  const slugify = value => value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
  const resolvePivot = () => {
    if (typeof window === "undefined") return defaultValue || values[0];
    const params = new URLSearchParams(window.location.search);
    const requested = params.get("pivots");
    if (requested) {
      const requestedIds = requested.split(",").map(value => value.trim()).filter(Boolean);
      const match = requestedIds.find(id => values.includes(id));
      if (match) return match;
    }
    const hash = window.location.hash.replace(/^#/, "");
    if (hash) {
      const match = options.find(option => option.id === hash || slugify(option.title) === hash);
      if (match) return match.id;
    }
    try {
      const stored = window.localStorage.getItem(`foundry-zone-pivot:${group}`);
      if (values.includes(stored)) return stored;
    } catch {
      return defaultValue || values[0];
    }
    return defaultValue || values[0];
  };
  useEffect(() => {
    setActivePivot(resolvePivot());
  }, [group, defaultValue, values.join("|"), optionKey]);
  useEffect(() => {
    const onPivotChange = event => {
      if (event.detail?.group === group && values.includes(event.detail.value)) {
        setActivePivot(event.detail.value);
      }
    };
    window.addEventListener("foundry-zone-pivot-change", onPivotChange);
    return () => window.removeEventListener("foundry-zone-pivot-change", onPivotChange);
  }, [group, values.join("|")]);
  if (activePivot !== value) return null;
  return <>{children}</>;
};

This article shows you how to manage Hosted agents in Foundry Agent Service. After you [deploy a Hosted agent](/agents/deploy-hosted-agent), you can view its status, create new versions, select the version served by the agent endpoint, monitor logs, and delete agents when they're no longer needed.

The platform manages the container lifecycle automatically. Compute is provisioned when a request arrives and deprovisioned after the idle timeout (15 minutes). This automatic compute scaling is separate from the agent's endpoint state. You don't start or stop the compute manually, but you can [disable an agent's endpoint](#disable-or-enable-an-agent) to take it offline and enable it again later.

## Prerequisites

* A [deployed Hosted agent](/agents/deploy-hosted-agent).

<ZonePivot group="azd__python__rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} defaultValue="rest" />

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  * [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) version 2.80 or later, authenticated with `az login`.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  * Python SDK: `azure-ai-projects>=2.3.0` and `azure-identity`.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  * [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) version 1.23.0 or later.
  * The Foundry agents extension:

    ```bash theme={null}
    azd ext install azure.ai.agents
    ```
</ZoneContent>

## Set up variables

The REST API examples in this article use `az rest` to call the Foundry Agent Service endpoints directly. Set the following variables before running the commands:

```bash theme={null}
ACCOUNT_NAME="<your-foundry-account-name>"
PROJECT_NAME="<your-project-name>"
AGENT_NAME="<your-agent-name>"
BASE_URL="https://${ACCOUNT_NAME}.services.ai.azure.com/api/projects/${PROJECT_NAME}"
API_VERSION="v1"
RESOURCE="https://ai.azure.com"
```

<Info>
  The `--resource` parameter is required for all `az rest` calls to Foundry Agent Service data-plane endpoints. Without it, `az rest` can't derive the correct Azure AD audience from the URL and authentication fails.
</Info>

## View agents and versions

Use the following commands to list agents and inspect version details.

### List all agents in a project

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method GET \
      --url "${BASE_URL}/agents?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  from azure.identity import DefaultAzureCredential
  from azure.ai.projects import AIProjectClient

  project = AIProjectClient(
      endpoint=PROJECT_ENDPOINT,
      credential=DefaultAzureCredential(),
  )

  for agent in project.agents.list():
      print(agent.name)
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  azd ai agent show
  ```

  <Note>
    `azd ai agent show` reads the agent name and version from the `azd` service entry in your project configuration.
  </Note>
</ZoneContent>

### Get agent details

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```

  The response includes the agent's latest version, status, and definition.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  agent = project.agents.get(agent_name="my-agent")
  print(f"Name: {agent.name}")
  print(f"Status: {agent.versions['latest']['status']}")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  azd ai agent show
  ```
</ZoneContent>

### Get a specific version

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions/1?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  agent_version = project.agents.get_version(
      agent_name="my-agent", agent_version="1"
  )
  print(f"Version: {agent_version.version}")
  print(f"Status: {agent_version['status']}")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Version information is included in the output of `azd ai agent show`.
</ZoneContent>

### List all versions of an agent

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```

  By default, the list excludes [draft versions (preview)](#create-a-draft-version-preview). To include them, add the `include_drafts=true` query parameter:

  ```bash theme={null}
  az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}&include_drafts=true" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  for version in project.agents.list_versions(agent_name="my-agent"):
      print(f"Version: {version.version}, Status: {version['status']}")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Version information is included in the output of `azd ai agent show`.
</ZoneContent>

### Create a new version

Create a new agent version when you need to update the container image, change resource allocation, or modify environment variables.

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method POST \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}" \
      --resource "${RESOURCE}" \
      --body '{
          "definition": {
              "kind": "hosted",
              "container_configuration": {
                  "image": "myregistry.azurecr.io/my-agent:v2"
              },
              "cpu": "1",
              "memory": "2Gi",
              "protocol_versions": [
                  {"protocol": "responses", "version": "1.0.0"}
              ]
          }
      }'
  ```

  Replace `responses` with `invocations` if your agent uses the Invocations protocol, or include both to expose both protocols. For details on protocol selection, see [Deploy a Hosted agent](/agents/deploy-hosted-agent#container-requirements).
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  from azure.ai.projects.models import ContainerConfiguration, HostedAgentDefinition, ProtocolVersionRecord

  agent = project.agents.create_version(
      agent_name="my-agent",
      definition=HostedAgentDefinition(
          cpu="1",
          memory="2Gi",
          container_configuration=ContainerConfiguration(
              image="myregistry.azurecr.io/my-agent:v2"
          ),
          protocol_versions=[
              ProtocolVersionRecord(protocol="responses", version="1.0.0"),
          ],
      ),
  )
  print(f"Created version: {agent.version}")
  ```

  Replace `responses` with `invocations` if your agent uses the Invocations protocol, or pass both to expose both protocols.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  New versions are created automatically when you run `azd deploy` with updated code or configuration.
</ZoneContent>

### Create a draft version (preview)

<Note>
  Draft versions are in preview. Preview features are provided without a service-level agreement and aren't recommended for production workloads. Behavior can change. Draft creation must be enabled for your subscription; until it's enabled, a request with `draft` set to `true` creates a normal release version instead.
</Note>

A *draft version* is an experimental version that you can create and test without affecting how your agent serves production traffic. Drafts let you iterate on a new image, resource allocation, or configuration before you promote the change to a regular release version.

Draft versions differ from regular release versions in the following ways:

* **Separate version identifier**: A draft is assigned a `draft-{timestamp}` version string (for example, `draft-1719600000000`) instead of an auto-incremented integer, so it never advances your release version numbering.
* **Excluded from default listings**: Drafts don't appear when you [list versions](#list-all-versions-of-an-agent) unless you pass `include_drafts=true`.
* **Excluded from implicit routing**: A draft is never resolved as the agent's latest version, so it doesn't receive traffic automatically.
* **Can't be a traffic-routing target**: You can't pin a traffic-routing rule to a draft version. Requests to route traffic to a draft are rejected.

To create a draft version, set `draft` to `true` in the request body:

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method POST \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}" \
      --resource "${RESOURCE}" \
      --body '{
          "draft": true,
          "definition": {
              "kind": "hosted",
              "container_configuration": {
                  "image": "myregistry.azurecr.io/my-agent:experimental"
              },
              "cpu": "1",
              "memory": "2Gi",
              "protocol_versions": [
                  {"protocol": "responses", "version": "1.0.0"}
              ]
          }
      }'
  ```

  The response `version` field contains the assigned `draft-{timestamp}` identifier. Use that identifier to [get](#get-a-specific-version) or [delete](#delete-a-specific-version) the draft, or to test it directly. When you're satisfied with the change, promote it by creating a new version with the same image and configuration but with `draft` omitted (or set to `false`). The new version receives a regular auto-incremented version number and becomes eligible for traffic routing.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Draft versions are currently available through the REST API only. Switch to the **REST** tab for an example, and call the same `${BASE_URL}/agents/${AGENT_NAME}/versions` endpoint with `"draft": true` in the request body.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Draft versions are currently available through the REST API only. Switch to the **REST** tab for an example.
</ZoneContent>

### Version status values

After you create or update an agent version, poll the version endpoint until the status reaches `active`:

| Status     | Description                                                               |
| ---------- | ------------------------------------------------------------------------- |
| `creating` | Infrastructure is being provisioned (typically 2-5 minutes).              |
| `active`   | Agent is ready to serve requests.                                         |
| `failed`   | Provisioning failed. Check the `error` field in the response for details. |
| `deleting` | Version is being cleaned up.                                              |
| `deleted`  | Version has been fully removed.                                           |

Poll the version status after creation:

```python theme={null}
import time

def wait_for_version_active(project, agent_name, agent_version, max_attempts=60):
    for attempt in range(max_attempts):
        time.sleep(10)
        version = project.agents.get_version(
            agent_name=agent_name, agent_version=agent_version
        )
        status = version["status"]
        print(f"Version status: {status} (attempt {attempt + 1})")
        if status == "active":
            return
        if status == "failed":
            raise RuntimeError(f"Version provisioning failed: {dict(version)}")
    raise RuntimeError("Timed out waiting for version to become active")
```

## Disable or enable an agent

Disable an agent to take its endpoint offline without deleting the agent or any of its versions. While disabled, the agent rejects requests, but its configuration and versions remain intact. Enable the agent again whenever you're ready to resume serving requests. Disabling is reversible, which makes it the preferred way to take an agent out of service temporarily.

### Disable an agent

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method POST \
      --url "${BASE_URL}/agents/${AGENT_NAME}:disable?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not supported as a standalone command. Use the REST API.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not supported as a standalone command. Use the REST API.
</ZoneContent>

### Enable an agent

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method POST \
      --url "${BASE_URL}/agents/${AGENT_NAME}:enable?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not supported as a standalone command. Use the REST API.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not supported as a standalone command. Use the REST API.
</ZoneContent>

## Delete an agent

You can delete a specific version or an entire agent with all its versions.

### Delete a specific version

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method DELETE \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions/1?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  project.agents.delete_version(agent_name="my-agent", agent_version="1")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not currently supported as a standalone command. Use the REST API or SDK.
</ZoneContent>

### Delete an agent and all versions

<Warning>
  This action permanently deletes the agent and all its versions. Active sessions are terminated. This operation can't be undone.
</Warning>

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```bash theme={null}
  az rest --method DELETE \
      --url "${BASE_URL}/agents/${AGENT_NAME}?api-version=${API_VERSION}" \
      --resource "${RESOURCE}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  project.agents.delete(agent_name="my-agent")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Not currently supported as a standalone command. Use the REST API or SDK.
</ZoneContent>

## View logs and monitor

Access container logs for debugging provisioning and runtime issues.

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Stream logs from a specific agent session:

  ```bash theme={null}
  AGENT_VERSION="<version>"
  SESSION_ID="<session-id>"

  az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}/versions/${AGENT_VERSION}/sessions/${SESSION_ID}:logstream?api-version=${API_VERSION}" \
      --resource "${RESOURCE}" \
      --headers "Accept=text/event-stream"
  ```

  The logstream endpoint returns Server-Sent Events (SSE) with `event: log` frames. Each frame contains a JSON payload with `timestamp`, `stream` (`stdout`, `stderr`, or `status`), and `message` fields.

  Timeouts:

  * Maximum connection duration: 30 minutes
  * Idle timeout: 2 minutes
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Viewing container logs isn't currently supported through the Python SDK. Use the REST API or Azure Developer CLI.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Monitor a running agent with real-time status and log information:

  ```bash theme={null}
  azd ai agent monitor
  ```

  This command reads the agent name and version from the `azd` service entry in your project configuration.
</ZoneContent>

### Example log output

```text theme={null}
2026-04-09T08:43:48.72656  Connecting to the container 'agent-container'...
2026-04-09T08:43:48.75451  Successfully connected to container: 'agent-container'
2026-04-09T08:43:59.0671054Z stdout F INFO: 127.0.0.1:42588 - "GET /readiness HTTP/1.1" 200 OK
```

## Configure agent endpoint routing

An agent endpoint routes 100% of its traffic to one agent version. Use the version selector to choose the version that the endpoint serves.

<Info>
  Traffic splitting between agent versions isn't supported. Configure one `FixedRatio` rule with `traffic_percentage` set to `100`, even though `version_selection_rules` is an array.
</Info>

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Endpoint routing is configured by patching the agent object. Use `PATCH /agents/{agent_name}` with `Content-Type: application/merge-patch+json`:

  ```bash theme={null}
  az rest --method PATCH \
      --url "${BASE_URL}/agents/${AGENT_NAME}?api-version=${API_VERSION}" \
      --resource "${RESOURCE}" \
      --headers "Content-Type=application/merge-patch+json" \
      --body '{
          "agent_endpoint": {
              "version_selector": {
                  "version_selection_rules": [
                      {"agent_version": "1", "traffic_percentage": 100, "type": "FixedRatio"}
                  ]
              },
              "protocol_configuration": {
                  "responses": {}
              }
          }
      }'
  ```

  Set `protocol_configuration` to `{"invocations": {}}` or `{"responses": {}, "invocations": {}}` to match the protocols your agent exposes.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  from azure.ai.projects.models import (
      AgentEndpointConfig,
      FixedRatioVersionSelectionRule,
      ProtocolConfiguration,
      ResponsesProtocolConfiguration,
      VersionSelector,
  )

  endpoint_config = AgentEndpointConfig(
      version_selector=VersionSelector(
          version_selection_rules=[
              FixedRatioVersionSelectionRule(
                  agent_version="1", traffic_percentage=100
              ),
          ]
      ),
      protocol_configuration=ProtocolConfiguration(
          responses=ResponsesProtocolConfiguration()
      ),
  )

  project.agents.update_details(
      agent_name="my-agent",
      agent_endpoint=endpoint_config,
  )
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  During `azd deploy`, the tool automatically configures endpoint routing. To select a specific version, use the REST API or SDK.
</ZoneContent>

## Retrieve the agent identity for role assignments

Each Hosted agent has an *instance identity* — a Microsoft Entra ID service principal that the agent uses at runtime to authenticate to downstream resources. To grant the agent access to services such as Azure Storage or Azure Cosmos DB, you need the identity's principal ID so you can create RBAC role assignments.

For more information on how agent identities work, see [Agent identity concepts](/agents/agent-identity).

### Extract the agent identity principal ID

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Use the `--query` parameter to extract the `instance_identity.principal_id` directly from the agent details:

  ```bash theme={null}
  AGENT_IDENTITY=$(az rest --method GET \
      --url "${BASE_URL}/agents/${AGENT_NAME}?api-version=${API_VERSION}" \
      --resource "${RESOURCE}" \
      --query "instance_identity.principal_id" \
      --output tsv)

  echo "Agent identity principal ID: ${AGENT_IDENTITY}"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  ```python theme={null}
  agent = project.agents.get(agent_name="my-agent")
  agent_identity = agent.instance_identity["principal_id"]
  print(f"Agent identity principal ID: {agent_identity}")
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Use the REST API or Python SDK to retrieve the agent identity principal ID.
</ZoneContent>

### Assign roles to the agent identity

After you have the principal ID, assign RBAC roles to the agent identity at the appropriate resource scope. Use `--assignee-object-id` with `--assignee-principal-type ServicePrincipal` to avoid Microsoft Graph lookup issues with agent identity service principals.

The agent identity works with any Azure resource that supports RBAC. The following examples show two common scenarios: granting access to the Foundry project and granting access to a storage account.

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Assign a role on the Foundry project (for example, to allow the agent to use project resources):

  ```bash theme={null}
  az role assignment create \
      --assignee-object-id "$AGENT_IDENTITY" \
      --assignee-principal-type ServicePrincipal \
      --role "Azure AI Developer" \
      --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account-name>/projects/<project-name>"
  ```

  Assign a role on a storage account (for example, to allow the agent to read and write blobs):

  ```bash theme={null}
  az role assignment create \
      --assignee-object-id "$AGENT_IDENTITY" \
      --assignee-principal-type ServicePrincipal \
      --role "Storage Blob Data Contributor" \
      --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Role assignments are an Azure Resource Manager operation. Use the Azure CLI commands shown in the REST tab with the `agent_identity` value from the previous step, or use the [Azure Authorization Management](https://learn.microsoft.com/python/api/azure-mgmt-authorization) SDK to create role assignments programmatically.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Use the Azure CLI directly to create role assignments. Retrieve the agent identity principal ID by using the REST API or Python SDK, then run `az role assignment create` as shown in the REST tab.
</ZoneContent>

### Verify role assignments

<ZoneContent group="azd__python__rest" value="rest" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  List the roles assigned to the agent identity on the Foundry project:

  ```bash theme={null}
  az role assignment list \
      --assignee "$AGENT_IDENTITY" \
      --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account-name>/projects/<project-name>" \
      --output table
  ```

  List the roles assigned to the agent identity on a storage account:

  ```bash theme={null}
  az role assignment list \
      --assignee "$AGENT_IDENTITY" \
      --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>" \
      --output table
  ```
</ZoneContent>

<ZoneContent group="azd__python__rest" value="python" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Use the Azure CLI commands shown in the REST tab to verify role assignments.
</ZoneContent>

<ZoneContent group="azd__python__rest" value="azd" options={[{"id": "rest", "title": "REST"}, {"id": "python", "title": "Python"}, {"id": "azd", "title": "Azure Developer CLI"}]} values={["rest", "python", "azd"]} defaultValue="rest">
  Use the Azure CLI directly to verify role assignments as shown in the REST tab.
</ZoneContent>

## Next steps

<Card title="Agent applications" icon="arrow-right" href="agent-applications.md" />

## Related content

* [What are Hosted agents?](/agents/hosted-agents)
* [Deploy a Hosted agent](/agents/deploy-hosted-agent)
* [Agent identity concepts](/agents/agent-identity)
* [Evaluate your AI agents](/observability/trace-agent-concept)
