Scopes
The complete list of Connect permissions and what each one grants.
A scope is a single named permission on a token. Request only what your app actually uses — users see the list on the consent screen.
The list#
| Scope | Grants |
|---|---|
profile.read | GET /connect/userinfo — user id and username |
profile.email | GET /connect/userinfo — the user's email address |
models.run | AI actions through the compatible API or /run, including video jobs, billed to the user under the applicable app or PortModel pricing |
account.manage | Customer account and developer actions through /run, including API keys, credits, billing, usage, connected apps and complaint submission/reads; never administration or moderation |
errors.report | Send bounded crash and API failure reports for this app; see Error reporting |
complaints.write | Submit complaints and append supporting evidence for this user and app; see Complaints |
complaints.read | Read this user and app's complaints, status, and shared resolution |
kv.read | Read per-user key/value data (scoped to your app) |
kv.write | Write per-user key/value data |
files.read | Read the user's folder for your app |
files.write | Write and delete files in that folder |
Scopes are space-separated in the scope parameter:
scope=models.run%20kv.read%20kv.writeaccount.manage must be enabled for the app and approved by the user. Existing
models.run grants already cover video but do not gain account management.
All actions still require the user's own permissions and ownership checks.
Rules#
- An app can only request scopes that are enabled for it in the console. See Enable Connect.
- Calling an endpoint without the scope for it returns
403. - Read and write are separate.
kv.readdoes not implykv.write. - The granted scopes come back on the token response in
scope, and are also reported by/connect/userinfo. Check them rather than assuming.
Choosing scopes#
| If your app | Request |
|---|---|
| Only runs models, keeps nothing | models.run |
| Remembers settings between sessions | models.run kv.read kv.write |
| Personalizes with the user's name | add profile.read |
| Signs the user into your own account system | add profile.read profile.email |
| Reports app crashes and API failures | add errors.report |
| Produces documents the user keeps | add files.read files.write |
Asking for storage scopes an app never uses is a common reason users decline at the consent screen, and a common reason a listing draws complaints.
Checking what you got#
curl https://api.portmodels.com/connect/userinfo \
-H "Authorization: Bearer pmc_..."{ "user_id": "...", "username": "...", "scopes": ["models.run", "kv.read"], "app_id": "acme/chatbot" }Degrade gracefully when a scope is missing: an app that hard-fails because the
user declined files.write is worse than one that keeps working without saved
output.