PortModels
Log in

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#

ScopeGrants
profile.readGET /connect/userinfo — user id and username
profile.emailGET /connect/userinfo — the user's email address
models.runOpenAI-compatible API calls billed to the user with your app markup
kv.readRead per-user key/value data (scoped to your app)
kv.writeWrite per-user key/value data
files.readRead the user's folder for your app
files.writeWrite and delete files in that folder

Scopes are space-separated in the scope parameter:

text
scope=models.run%20kv.read%20kv.write

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.read does not imply kv.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 appRequest
Only runs models, keeps nothingmodels.run
Remembers settings between sessionsmodels.run kv.read kv.write
Personalizes with the user's nameadd profile.read
Signs the user into your own account systemadd profile.read profile.email
Produces documents the user keepsadd 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#

bash
curl https://api.portmodels.com/connect/userinfo \
  -H "Authorization: Bearer pmc_..."
json
{ "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.