GROK BOT / list-model-access-configuration-via-org-api

Grok Bot

List model access configuration with the Organization API

Scan linked teams for unrestricted vs custom model-access policy with GET https://api.cursor.com/organizations/teams/model-access/configuration, and read one team with GET https://api.cursor.com/organizations/teams/{teamId}/model-access/configuration. Official reference: Organization API → Model access. These routes are in preview and may change before general availability.

Authenticate with an Organization API key (Basic auth, key as username, empty password). Reads need models:read (or admin:*). Keys scoped only to members:*, usage:*, or generic read:* cannot call these routes. Rate limit: 20 requests per minute. Enterprise organizations; target teams must have model access control available.

Numeric teamId values come from routes such as List organization members.

List linked teams

curl -X GET "https://api.cursor.com/organizations/teams/model-access/configuration?page=1&pageSize=50" \
  -u YOUR_ORGANIZATION_API_KEY:

Optional query: teamIds as a comma-separated list (for example 7,8,9).

Example response:

{
  "teams": [
    {
      "teamId": 7,
      "teamName": "Platform",
      "state": "custom",
      "newProviderDefault": "disabled",
      "newModelDefault": "enabled"
    },
    {
      "teamId": 8,
      "teamName": "Mobile",
      "state": "custom",
      "newProviderDefault": "disabled",
      "newModelDefault": "enabled"
    },
    {
      "teamId": 9,
      "teamName": "Data",
      "state": "unrestricted",
      "newProviderDefault": null,
      "newModelDefault": null
    },
    {
      "teamId": 10,
      "teamName": "Research",
      "errorMessage": "Model access control is not available for this team"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 50,
    "totalCount": 4,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPreviousPage": false
  }
}
Field Meaning
teamId / teamName Linked team id and display name
state unrestricted, custom, or legacy when configuration loaded
newProviderDefault / newModelDefault Defaults when state is custom; otherwise null
errorMessage Present on HTTP 200 list rows when that team cannot load configuration (for example model access control unavailable)

Use the list to catch configuration drift. For on/off drift across providers and models, GET each team’s providers after a custom policy exists (same official Model access section).

Get one team

curl -X GET https://api.cursor.com/organizations/teams/7/model-access/configuration \
  -u YOUR_ORGANIZATION_API_KEY:

Unknown or unlinked teamId returns 404. Teams without model access control available return 403 on this single-team GET.

Pitfalls

  • List rows can be HTTP 200 with errorMessage instead of state / defaults when model access control is unavailable for that team.
  • Provider and model reads return 409 while a team’s state is still unrestricted or legacy — seed a custom policy first (Set model access configuration).
  • There is no org-level copy endpoint or policy fingerprint; compare list rows and per-team provider GETs yourself.
  • Preview paths can shift before GA — pin the official docs when you automate.