From e565d42e08e4fcc4c5442817d8b92042779acaab Mon Sep 17 00:00:00 2001 From: Vrushank Vyas Date: Tue, 3 Nov 2026 23:02:29 +0530 Subject: [PATCH 1/2] docs(aigw): workspace_id is a required UUID; how to find it The Admin API docs said a workspace slug works for workspace_id and that leaving it out falls back to the default workspace. Neither is true: an organisation-scoped access token needs workspace_id, and it must be the workspace's UUID, which the console doesn't show next to the slug. - admin-api/introduction: the first-request curl now sends workspace_id; scoping section corrected (required, UUID, query parameter on every method); new "Find a workspace's ID" section using the Workspace Service; Workspace Service added to the base URL table - workspaces: new "Workspace IDs" section, slug vs UUID, and the Workspace Service for creating and updating workspaces - error, help-center permissions, enforce-default-config: same correction where they repeated the old claims - org-management: the Workspaces card pointed at Portkey's endpoint - docs.json: API nav synced from PaloAltoNetworks/openapi, adding the Workspaces group and the Messages, Access Policies and Egress Allowlist groups Co-Authored-By: Claude Opus 5.5 --- aigw/api-reference/admin-api/error.mdx | 2 +- aigw/api-reference/admin-api/introduction.mdx | 47 ++++++++++++--- .../you-do-not-have-enough-permissions.mdx | 2 +- .../administration/enforce-default-config.mdx | 3 +- .../enterprise-offering/org-management.mdx | 2 +- .../org-management/workspaces.mdx | 20 ++++++- docs.json | 57 ++++++++++++++++++- 7 files changed, 119 insertions(+), 14 deletions(-) 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..6edf93fa 100644 --- a/aigw/help-center/you-do-not-have-enough-permissions.mdx +++ b/aigw/help-center/you-do-not-have-enough-permissions.mdx @@ -84,7 +84,7 @@ 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) 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" ] }, { From b81c90af7100f418d557cfc6d66a55dd3bd99183 Mon Sep 17 00:00:00 2001 From: Vrushank Vyas Date: Tue, 3 Nov 2026 23:17:05 +0530 Subject: [PATCH 2/2] docs(aigw): permissions examples send a UUID workspace_id in the query string Addresses review: the two curl examples under the corrected note still used a ws-abc123 slug, and the provider POST still put workspace_id in the body. Co-Authored-By: Claude Opus 5.5 --- .../help-center/you-do-not-have-enough-permissions.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 6edf93fa..78512bc2 100644 --- a/aigw/help-center/you-do-not-have-enough-permissions.mdx +++ b/aigw/help-center/you-do-not-have-enough-permissions.mdx @@ -87,16 +87,16 @@ 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 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"}' ```