Skip to main content

Virtual keys live under projects, so GET /api/v1/projects/{project_id}/virtual-keys answers for one project at a time. A screen that has to name a key anywhere in the organization — the picker in the MCP tool group dialog, for one — would otherwise list the projects and then issue one request per project. In an organization with hundreds of projects that is hundreds of requests to open one dialog.

GET /api/v1/orgs/{org_id}/virtual-keys is that list in one request.

Request#

There are no query parameters. The organization id is the only input.

Response#

An array of virtual keys, oldest first. Each is the object GET /api/v1/projects/{project_id}/virtual-keys returns, without any digest of a secret: there is no key_hash, and none of the previous_* fields of a rotation. Each carries its project_id; join it to GET /api/v1/orgs/{org_id}/projects to name the project and its team.

The secret is never part of a listing; it is shown once, when the key is minted.

Authorization#

The virtual_key capability’s read action, the one the per-project list takes, decided for each key at its own project. The list holds exactly the keys the per-project list would show the caller, project by project, so asking for the whole organization widens nothing:

  • an organization reader gets every key of the organization;
  • a team reader gets the keys of that team’s projects;
  • a project reader gets that project’s keys;
  • an account with no role anywhere inside the organization is refused with 403, and an unauthenticated one with 401. A caller with a role that reaches no key gets an empty array.

A superadmin or the deployment admin token reads every key.