---
title: "List scopes available for a new personal access token"
method: GET
path: "/personal-access-tokens/scopes"
tags: ["Personal Access Tokens"]
---

# List scopes available for a new personal access token

`GET /personal-access-tokens/scopes`

## Request

- Base URL: `https://app.pipeshub.com/api/v1`
- URL: `https://app.pipeshub.com/api/v1/personal-access-tokens/scopes`
- Auth: HTTP bearer

Returns the org's configured `MCP_SCOPES` as a flat array of scope
definitions, for populating the create-token scope picker. Unlike
`GET /oauth-clients/scopes`, this is **not** grouped by category and
**not** role-aware — every org member sees the same set, since PAT
scope selection isn't gated by admin status. The handler reads no query
parameters and ignores any that are sent.

## Response `200`

Scopes available to grant

- PatScopesListResponse: Response body for `GET /personal-access-tokens/scopes` (`listScopes`). Unlike `GET /oauth-clients/scopes`, this is a **flat array**, not grouped by category, and reflects the org's configured `MCP_SCOPES` rather than the full role-aware OAuth-app scope catalog.
  - `scopes` OAuthScopeInfo[], required
    - `name` string, required: Scope identifier
    - `description` string, required: Human-readable scope description
    - `category` string, required: Scope category for grouping (matches the key under `scopes` on list responses)
    - `requiresUserConsent` boolean, required: Whether end-user consent is required when this scope is requested

## Other responses

- `400`: Refused before authentication because a query value, or any string in a JSON or form-encoded body, looks like markup to the app-wide XSS filter: an HTML tag, a script tag, `<iframe`, `<object`, `<embed` or `<svg` tag, a word starting with `on` followed by `=` (meant for inline event handlers such as `onerror=`, it also catches plain text such as `one=1`), a `javascript:` or `data:text/html` URL, an encoded script tag (`&lt;script`, `%3cscript`), or any string longer than 100,000 characters (`HTTP_BAD_REQUEST`, "HTML tags, scripts, and XSS content are not allowed in ...", naming the field or query parameter; a string over 100,000 characters is refused as too long instead). A JSON body that does not parse is refused the same way, also before authentication (`HTTP_BAD_REQUEST`, "The request body is not valid JSON.").
- `401`: Unauthorized
- `403`: The bearer token is an OAuth access token, a personal access token (`phpat_`) or a service token (`phsvc_`) rather than an interactive user session
- `429`: Rate limit exceeded
- `500`: Internal server error. A JSON body larger than 10 MB, or a form-encoded body larger than 100 KB or with more than 1000 fields, is answered `413` by the app-wide body parsers instead, also before authentication.

## Changes

- **2026-10-28** `dbb5e203b445`: 4 info
  - added the non-success response with the status `400`
  - added the non-success response with the status `403`
  - added the non-success response with the status `500`
  - added the optional property `error/requestId` to the response with the `401` status
- **2026-08-12** `5798f431973a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/changes/personal-access-tokens/scopes/get.md)

---

[API](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api.md) - [All operations](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/llms.txt) - [OpenAPI document](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/revisions/dbb5e203b445?raw)
