Using the token
Every endpoint a Connect access token can reach, with examples.
All calls authenticate the same way:
Authorization: Bearer pmc_...One token per login#
An authorization-code exchange or device-flow approval issues a token for that login. Multiple devices can stay connected to the same app at once, and each token keeps its own approved scopes. Store tokens by your own user plus session or device installation when your app needs to support those sessions independently.
Disconnecting the app from Settings → Connected apps revokes all of its tokens for that user. Reconnecting afterwards creates a new token; it does not restore a token that was revoked.
Run models (models.run)#
Same OpenAI-compatible API as regular API keys:
curl https://api.portmodels.com/openai/v1/chat/completions \
-H "Authorization: Bearer pmc_..." \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-ai/DeepSeek-V3",
"messages": [{"role": "user", "content": "Hello"}]
}'Billing: the user's credits are charged provider cost plus your app's markup
rate, and your developer share of the markup accrues to your earnings exactly
like calls made inside your app. Your app's allowed_models list applies.
See Chat completions for the full request and response shape.
Who is this user? (profile.read)#
curl https://api.portmodels.com/connect/userinfo \
-H "Authorization: Bearer pmc_..."{ "user_id": "...", "username": "...", "scopes": ["..."], "app_id": "acme/chatbot" }Request profile.email as well when your app needs to associate the account
with an email address. The response then includes an email field; email is
kept separate from profile.read so apps do not receive contact details by
default.
Per-user key/value store (kv.read / kv.write)#
# Store — any JSON value
curl -X PUT https://api.portmodels.com/connect/kv/preferences \
-H "Authorization: Bearer pmc_..." \
-H "Content-Type: application/json" \
-d '{"value": {"theme": "dark", "volume": 7}}'
# Read one
curl https://api.portmodels.com/connect/kv/preferences \
-H "Authorization: Bearer pmc_..."
# List all
curl https://api.portmodels.com/connect/kv \
-H "Authorization: Bearer pmc_..."
# Delete
curl -X DELETE https://api.portmodels.com/connect/kv/preferences \
-H "Authorization: Bearer pmc_..."Limits: values up to 64KB, up to 1000 keys per user. See Key/value store.
Per-user files (files.read / files.write)#
Backed by S3-compatible storage under users/{user}/apps/{your app}/....
Files are up to 10MB each, and .. traversal is rejected.
# Upload — raw body
curl -X PUT https://api.portmodels.com/connect/files/notes/2026-07.md \
-H "Authorization: Bearer pmc_..." \
-H "Content-Type: text/markdown" \
--data-binary @notes.md
# Download
curl https://api.portmodels.com/connect/files/notes/2026-07.md \
-H "Authorization: Bearer pmc_..."
# List, optionally by prefix
curl "https://api.portmodels.com/connect/files?prefix=notes" \
-H "Authorization: Bearer pmc_..."
# Delete
curl -X DELETE https://api.portmodels.com/connect/files/notes/2026-07.md \
-H "Authorization: Bearer pmc_..."See File storage.
Errors you should handle#
| Status | Meaning |
|---|---|
| 400 | invalid_grant on /token — bad, expired, or replayed code, bad redirect, or invalid PKCE code_verifier |
| 400 | authorization_pending / slow_down / access_denied / expired_token on /device/token |
| 401 | Token invalid, expired, or connection revoked — re-run connect for that login |
| 403 | Token lacks the scope for that endpoint |
| 413 | File upload over the 10MB limit |
| 429 | Rate limited — honor Retry-After |
See Errors for the full reference.