diff --git a/aigw/api-reference/admin-api/error.mdx b/aigw/api-reference/admin-api/error.mdx
index a1509e82..3489f46f 100644
--- a/aigw/api-reference/admin-api/error.mdx
+++ b/aigw/api-reference/admin-api/error.mdx
@@ -51,7 +51,7 @@ Admin API failures carry a code in the `AB` series alongside the HTTP status. Th
The path is right and the resource is not there. Two causes dominate:
- **A slug was passed where an ID was expected**, or the reverse. Configs, integrations and providers take slugs; guardrails, MCP servers, policies and API keys take IDs.
- - **The resource belongs to a workspace you did not name.** Pass `workspace_id` as a query parameter on `GET`, and in the body on `POST` and `PUT`.
+ - **The resource belongs to a workspace you did not name.** Pass `workspace_id`, the workspace's UUID, as a query parameter on every method, including `POST` and `PUT`.
diff --git a/aigw/api-reference/admin-api/introduction.mdx b/aigw/api-reference/admin-api/introduction.mdx
index 915240e2..6f4b38c8 100644
--- a/aigw/api-reference/admin-api/introduction.mdx
+++ b/aigw/api-reference/admin-api/introduction.mdx
@@ -46,14 +46,14 @@ Admin API requests are authorised with a **Strata Cloud Manager access token**,
```
- Send the token as a bearer token. Every endpoint takes the same header.
+ Send the token as a bearer token. Every endpoint takes the same header. Configs belong to a workspace, so name one with `workspace_id`, the workspace's **UUID**.
```sh
- curl https://api.apps.paloaltonetworks.com/ai_gw/v2/configs \
+ curl "https://api.apps.paloaltonetworks.com/ai_gw/v2/configs?workspace_id=" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
- The response lists the configs belonging to the organisation the token is scoped to. You do not send a tenant identifier on the request, because the token carries it.
+ The response lists the configs in that workspace. You don't send a tenant identifier, because the token carries it. You do send the workspace, because the token is scoped to the whole organisation. [Find a workspace's ID](#find-a-workspaces-id) shows how to get the UUID.
Tokens last **15 minutes**, reported as `expires_in: 900` on the token response. Cache one for that window and refresh it shortly before it lapses.
@@ -69,6 +69,7 @@ Which base URL an endpoint uses follows the resource, not the sidebar group it s
| `https://api.apps.paloaltonetworks.com/ai_gw/v2` | Configs, workspace guardrails, providers, API keys, usage and rate limit policies, MCP servers, analytics, feedback |
| `https://api.apps.paloaltonetworks.com/ai_gw/admin/v2` | Integrations, MCP integrations, secret references, deployments, organisation guardrails |
| `https://aigw.portkey.ai/v1` | `POST /logs` and `GET /logs/{logId}`. Self-hosted deployments substitute their own host |
+| `https://api.sase.paloaltonetworks.com/airs/workspace/v1` | [Workspaces](/aigw/api-reference/workspaces/list-workspaces): list, create, view and update the workspaces in a tenant |
The organisation guardrail endpoints carry their prefix in the path instead of the base URL, as `/admin/v2/guardrails` against `https://api.apps.paloaltonetworks.com/ai_gw`. That resolves to the same place as the admin base above.
@@ -92,18 +93,50 @@ graph LR
| Level | Addressed by | Holds |
|:--|:--|:--|
| **Organisation** | The TSG ID inside your token. One TSG is one organisation. | Integrations, MCP integrations, secret references, deployments, organisation guardrails |
-| **Workspace** | A `workspace_id`, passed explicitly | Configs, providers, workspace guardrails, analytics |
+| **Workspace** | A `workspace_id` (the workspace UUID), passed explicitly | Configs, providers, workspace guardrails, analytics |
The split matches the base URLs: organisation-level resources are served from the `admin/v2` base. API keys and limit policies span both levels, and [`POST /api-keys/{sub-type}`](/aigw/api-reference/api-keys/post-api-keys-by-sub-type) takes the level from the calling token rather than from the path — `sub-type` chooses `user` or `service`, nothing more.
-To reach a workspace-level resource, pass `workspace_id` as a **query parameter** on `GET` and list requests, and in the **request body** on `POST` and `PUT`. A workspace UUID or a slug both work.
+To reach a workspace-level resource, pass `workspace_id` as a **query parameter**, on every method, including `POST` and `PUT`. It's required on these calls, and it must be the workspace's **UUID**. A workspace slug doesn't work here.
```sh
-curl "https://api.apps.paloaltonetworks.com/ai_gw/v2/configs?workspace_id=WORKSPACE_SLUG" \
+curl "https://api.apps.paloaltonetworks.com/ai_gw/v2/configs?workspace_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
-Omit it and the call resolves against the organisation default.
+The Admin API takes an access token, and an access token is scoped to the whole organisation, so it can't tell the gateway which workspace you mean. A workspace API key already belongs to one workspace, but the Admin API doesn't accept those keys.
+
+### Find a workspace's ID
+
+The workspace UUID isn't shown next to the slug in Strata Cloud Manager. Get it either of these ways:
+
+- **From the API.** [`GET /workspaces`](/aigw/api-reference/workspaces/list-workspaces) on the Workspace Service lists the workspaces in your tenant, with the same access token. Filter by name with `exact_name`, or with `name` for a case-insensitive substring match. Each workspace's `id` is the value to pass as `workspace_id`.
+
+ ```sh
+ curl "https://api.sase.paloaltonetworks.com/airs/workspace/v1/workspaces?exact_name=ML%20Platform%20Team" \
+ -H "Authorization: Bearer $ACCESS_TOKEN"
+ ```
+
+ ```json
+ {
+ "workspaces": [
+ {
+ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
+ "name": "ML Platform Team",
+ "scope_name": "ml_platform_team_x7k2",
+ "is_default": false,
+ "status": "active"
+ }
+ ],
+ "total_count": 1,
+ "limit": 20,
+ "offset": 0
+ }
+ ```
+
+ The response is shortened here. Workspace names aren't unique within a tenant, so check `total_count` before you take the first result.
+
+- **From Strata Cloud Manager.** Open the workspace and copy the UUID from the page URL.
### Slugs and IDs
diff --git a/aigw/help-center/you-do-not-have-enough-permissions.mdx b/aigw/help-center/you-do-not-have-enough-permissions.mdx
index be1e2fa2..78512bc2 100644
--- a/aigw/help-center/you-do-not-have-enough-permissions.mdx
+++ b/aigw/help-center/you-do-not-have-enough-permissions.mdx
@@ -84,19 +84,19 @@ Before fixing the error, understand the two key types and how scopes work.
-Admin API requests reach workspace-level resources (providers, configs, prompts, integrations) by passing `workspace_id` as a query parameter (for `GET`/list requests) or in the request body (for `POST`/`PUT` requests). Use a workspace UUID or slug. Workspace API keys are locked to their own workspace and can't access other workspaces.
+Admin API requests reach workspace-level resources (providers, configs, prompts, integrations) by passing `workspace_id` as a query parameter on every method, including `POST` and `PUT`. It must be the workspace's UUID, not its slug. See [Find a workspace's ID](/aigw/api-reference/admin-api/introduction#find-a-workspaces-id). Workspace API keys are locked to their own workspace and can't access other workspaces.
-```sh Listing configs (GET, query parameter)
-curl "https://api.apps.paloaltonetworks.com/ai_gw/v2/configs?workspace_id=ws-abc123" \
+```sh Listing configs (GET)
+curl "https://api.apps.paloaltonetworks.com/ai_gw/v2/configs?workspace_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
-```sh Creating a provider (POST, request body)
-curl -X POST "https://api.apps.paloaltonetworks.com/ai_gw/v2/providers" \
+```sh Creating a provider (POST)
+curl -X POST "https://api.apps.paloaltonetworks.com/ai_gw/v2/providers?workspace_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
- -d '{"workspace_id": "ws-abc123", "name": "My Provider"}'
+ -d '{"name": "My Provider"}'
```
diff --git a/aigw/product/administration/enforce-default-config.mdx b/aigw/product/administration/enforce-default-config.mdx
index 9e576854..892be01f 100644
--- a/aigw/product/administration/enforce-default-config.mdx
+++ b/aigw/product/administration/enforce-default-config.mdx
@@ -63,12 +63,11 @@ You can also programmatically attach config when creating or updating API keys u
```bash
-curl -X POST "https://api.apps.paloaltonetworks.com/ai_gw/v2/api-keys/service" \
+curl -X POST "https://api.apps.paloaltonetworks.com/ai_gw/v2/api-keys/service?workspace_id=" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"name": "engineering-team",
- "workspace_id": "YOUR_WORKSPACE_ID",
"defaults": {
"config_id": "pc-your-config-id",
"metadata": {
diff --git a/aigw/product/enterprise-offering/org-management.mdx b/aigw/product/enterprise-offering/org-management.mdx
index 1c3459d2..9ceb051c 100644
--- a/aigw/product/enterprise-offering/org-management.mdx
+++ b/aigw/product/enterprise-offering/org-management.mdx
@@ -20,7 +20,7 @@ This structure enables you to:
-
+
diff --git a/aigw/product/enterprise-offering/org-management/workspaces.mdx b/aigw/product/enterprise-offering/org-management/workspaces.mdx
index 7b7bbe51..4c789325 100644
--- a/aigw/product/enterprise-offering/org-management/workspaces.mdx
+++ b/aigw/product/enterprise-offering/org-management/workspaces.mdx
@@ -18,7 +18,7 @@ Key features of Workspaces:
* Both these types of keys are scoped to the workspace by default and can only execute actions within that workspace.
* **Completion API Scoping:** Completion APIs are always scoped by workspace and can only be accessed using workspace API keys.
* **Admin Control:** While only org admins can create workspaces, managers can add API keys and team members with roles to existing workspaces.
-* **Flexible Updates:** When making updates to entities via admin keys (at the org level), you can specify the `workspace_id` to target specific workspaces.
+* **Flexible Updates:** When you change entities with an organisation-level access token, pass `workspace_id` to say which workspace you're changing. It's the workspace's UUID, not its slug. See [Workspace IDs](#workspace-ids).
Workspaces provide a powerful way to organize your projects, teams, and resources within your larger organisation, ensuring proper access control and data separation.
@@ -41,6 +41,24 @@ graph TD
This structure allows for efficient management of resources and access within each workspace, providing a clear separation between different projects or teams within your organisation.
+### Workspace IDs
+
+Every workspace has two identifiers:
+
+| Identifier | Example | Where it's used |
+|:--|:--|:--|
+| **Slug** | The short name you gave the workspace | Shown in Strata Cloud Manager |
+| **ID** (UUID) | `a1b2c3d4-e5f6-7890-abcd-ef1234567890` | The `workspace_id` parameter on the [Admin API](/aigw/api-reference/admin-api/introduction#how-resources-are-scoped) |
+
+Admin API calls that act on a workspace, such as configs, providers, guardrails and analytics, require `workspace_id`, and it must be the UUID. A slug isn't accepted there.
+
+To find a workspace's UUID:
+
+- Call [`GET /workspaces`](/aigw/api-reference/workspaces/list-workspaces) on the Workspace Service (`https://api.sase.paloaltonetworks.com/airs/workspace/v1`) with your access token, filtered by `exact_name`. The `id` field of each result is the UUID.
+- Or open the workspace in Strata Cloud Manager and copy the UUID from the page URL.
+
+The Workspace Service also [creates](/aigw/api-reference/workspaces/create-workspace), [gets](/aigw/api-reference/workspaces/get-workspace) and [updates](/aigw/api-reference/workspaces/update-workspace) workspaces. A workspace is bound to a Strata Cloud Manager scope: create the scope first, then pass its name as `scope_name` when you create the workspace.
+
### Deleting a Workspace
diff --git a/docs.json b/docs.json
index 7fad4255..c5ba98ce 100644
--- a/docs.json
+++ b/docs.json
@@ -2361,6 +2361,17 @@
"POST /images/variations"
]
},
+ {
+ "group": "Messages",
+ "openapi": {
+ "source": "https://raw.githubusercontent.com/PaloAltoNetworks/openapi/refs/heads/main/openapi.yaml",
+ "directory": "aigw/api-reference"
+ },
+ "pages": [
+ "POST /messages",
+ "POST /messages/count_tokens"
+ ]
+ },
{
"group": "Model Pricing",
"openapi": {
@@ -2697,6 +2708,20 @@
"POST /api-keys/{id}/rotate"
]
},
+ {
+ "group": "Access Policies",
+ "openapi": {
+ "source": "https://raw.githubusercontent.com/PaloAltoNetworks/openapi/refs/heads/main/openapi.yaml",
+ "directory": "aigw/api-reference"
+ },
+ "pages": [
+ "POST /policies/access",
+ "GET /policies/access",
+ "GET /policies/access/{accessPolicyId}",
+ "PUT /policies/access/{accessPolicyId}",
+ "DELETE /policies/access/{accessPolicyId}"
+ ]
+ },
{
"group": "Deployments",
"openapi": {
@@ -2712,6 +2737,20 @@
"GET /deployments/{deploymentId}/ping"
]
},
+ {
+ "group": "Egress Allowlist",
+ "openapi": {
+ "source": "https://raw.githubusercontent.com/PaloAltoNetworks/openapi/refs/heads/main/openapi.yaml",
+ "directory": "aigw/api-reference"
+ },
+ "pages": [
+ "GET /egress-allowlist",
+ "POST /egress-allowlist",
+ "GET /egress-allowlist/{egressAllowlistId}",
+ "PUT /egress-allowlist/{egressAllowlistId}",
+ "DELETE /egress-allowlist/{egressAllowlistId}"
+ ]
+ },
{
"group": "Org Guardrails",
"openapi": {
@@ -2758,6 +2797,19 @@
"GET /policies/usage-limits/{policyUsageLimitsId}/entities",
"PUT /policies/usage-limits/{policyUsageLimitsId}/entities/{entityId}/reset"
]
+ },
+ {
+ "group": "Workspaces",
+ "openapi": {
+ "source": "https://raw.githubusercontent.com/PaloAltoNetworks/openapi/refs/heads/main/openapi.yaml",
+ "directory": "aigw/api-reference"
+ },
+ "pages": [
+ "GET /workspaces",
+ "POST /workspaces",
+ "GET /workspaces/{id}",
+ "PUT /workspaces/{id}"
+ ]
}
]
},
@@ -2800,7 +2852,10 @@
"GET /analytics/groups/users",
"GET /analytics/groups/ai-models",
"GET /analytics/groups/provider",
- "GET /analytics/groups/metadata/{metadataKey}"
+ "GET /analytics/groups/metadata/{metadataKey}",
+ "GET /analytics/groups/a2a",
+ "GET /analytics/groups/mcp",
+ "GET /analytics/groups/workspaces"
]
},
{