# Create Installation User Token

Part of [Apps and installations](https://cursor.com/docs/api/origin/reference/apps-and-installations.md) in the Origin API reference.

POST

`/v1/origin/app/installations/{installationId}/user_access_tokens`

Requires no scope (app JWT).

Creates an installation user token that acts on behalf of one member of the installation's namespace.

The installation must belong to the authenticated app and have accepted `namespace:user_tokens:write`. Name the user with exactly one of `userId` or `userEmail`. An unknown, ambiguous, or ineligible user receives `PermissionDenied` (HTTP 403) without revealing which condition failed.

The token's access is limited to permissions held by both the installation and the user. When both `scopes` and `repositoryIds` are set, each scope must be allowed on every listed repository for both principals or the request receives `PermissionDenied` (HTTP 403). See [Acting on behalf of users](https://cursor.com/docs/api/origin/acting-as-users.md) for the complete flow.

## Path Parameters

`installationId` string Required

The unique identifier of the installation to scope the token to. Bound from the URL path; the installation must belong to the authenticated app.

## Request Body

`userId` string

The user's `user_…` ID, as returned in actor payloads. Set exactly one of `userId` or `userEmail`.

`userEmail` string

The user's account email. It must match exactly one eligible namespace member.

`scopes` array

Scope strings that cap the token. Values must be unique and included in the installation's accepted scopes. Requesting `namespace:user_tokens:write` returns `InvalidArgument` (HTTP 400); it authorizes minting and cannot be delegated to the token. Empty or omitted adds no scope cap.

`repositoryIds` array

Repository IDs that cap the token. Values must be unique, accessible to the installation, and contain at most 50 entries. Empty or omitted adds no repository cap.

## Response Fields

`token` string

Short-lived installation user token. Treat it as a secret and do not log it.

`expiresAt` string

RFC 3339 expiration time; the token expires after at most 15 minutes and never outlives the app JWT used to mint it.

```bash
curl --request POST \
  --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID/user_access_tokens' \
  --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "userId": "user_01k2ja2000e0080000000000c3",
  "scopes": [
    "repository:pull_requests:reviews:write"
  ],
  "repositoryIds": [
    "repo_01k2ja2000e0080000000000q4"
  ]
}'
```

**Response shape:**

```json
{
  "token": "YOUR_INSTALLATION_USER_TOKEN",
  "expiresAt": "2026-08-01T10:30:00Z"
}
```


---

## Sitemap

[Origin API docs index](https://cursor.com/docs/api/origin/llms.txt)
