Short answer
Gitter does not document granular OAuth2 scopes such as read or write. Personal access tokens are not scoped and grant full read/write access to the authenticated account. For the OAuth2 authorization-code flow, the token endpoint is likely to return an access_token with an expires_in value and may include a refresh_token, but the public documentation does not explicitly confirm these fields, so they must be verified in your own environment.
Confirmed facts vs. likely behavior
| Behavior | Status |
| PATs provide full account read/write access | Confirmed |
OAuth2 access tokens include expires_in (commonly around one hour) | Likely, not documented |
Token endpoint accepts a scope parameter | Unconfirmed; likely ignored or rejected |
| Refresh token is returned for session renewal | Likely, but undocumented |
| Tokens expire automatically after TTL unless refreshed | Observed only if expires_in is present |
Verification steps
Inspect the token response. Exchange your authorization code and look for expires_in and refresh_token:
curl -s -X POST https://api.gitter.im/oauth/token \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "code=AUTH_CODE" \
-d "grant_type=authorization_code" \
-d "redirect_uri=YOUR_REDIRECT_URI" | jq '{expires_in, refresh_token}'
Test read and write access with the same token to confirm there is no scope enforcement:
# Read
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
https://api.gitter.im/v1/rooms
# Write
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"verification message"}' \
https://api.gitter.im/v1/rooms/ROOM_ID/chatMessages
If a refresh_token is present, attempt a refresh and confirm the old access token stops working after its TTL:
curl -s -X POST https://api.gitter.im/oauth/token \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "refresh_token=REFRESH_TOKEN" \
-d "grant_type=refresh_token" | jq '.'
Security implications
Because tokens are not scoped, least-privilege access cannot be enforced by the token itself. Use a dedicated Gitter account for automation, restrict outbound network access where possible, and filter rooms in application logic. If no refresh_token is returned, plan for manual rotation and handle 401 responses gracefully.
One diagnostic that changes the recommendation
Does your current token response include a refresh_token field? If yes, implement automatic renewal; if no, treat the credential as long-lived until manually revoked and rotate it on a schedule.