The Accounts API manages OAuth connections to external services like Google, GitHub, and Notion. These accounts enable widgets to access user data from integrated services.
Supported Providers
google - Google OAuth integration
github - GitHub OAuth integration
notion - Notion OAuth integration
Get Connected Accounts
Retrieve all connected OAuth accounts for the authenticated user.
curl -X GET http://localhost:3000/api/accounts \
-H "Cookie: session=your-session-token"
Response
Returns an array of connected account objects.
Unique account identifier
Provider-specific account ID
OAuth provider: google, github, or notion
ID of the user who connected this account
OAuth access token (sensitive - handle with care)
OAuth refresh token (sensitive - handle with care)
Access token expiration timestamp
Refresh token expiration timestamp
Account connection timestamp
Success (200)
Error (401)
[
{
"id": "acc_1234567890",
"accountId": "google_user_id_xyz",
"providerId": "google",
"userId": "user123",
"accessToken": "ya29.a0AfH6SMB...",
"refreshToken": "1//0gLn8...",
"idToken": null,
"accessTokenExpiresAt": "2024-01-20T16:30:00.000Z",
"refreshTokenExpiresAt": null,
"scope": "https://www.googleapis.com/auth/userinfo.email",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T15:30:00.000Z"
},
{
"id": "acc_0987654321",
"accountId": "github_user_id_abc",
"providerId": "github",
"userId": "user123",
"accessToken": "gho_16C7e42F292...",
"refreshToken": "ghr_1B4a2e77...",
"idToken": null,
"accessTokenExpiresAt": "2024-01-21T10:30:00.000Z",
"refreshTokenExpiresAt": "2024-07-15T10:30:00.000Z",
"scope": "repo,user",
"createdAt": "2024-01-16T12:00:00.000Z",
"updatedAt": "2024-01-20T15:30:00.000Z"
}
]
The response includes sensitive tokens. Never expose these in client-side code or logs.
Update Account
Update a connected account’s refresh token.
curl -X PUT http://localhost:3000/api/accounts \
-H "Content-Type: application/json" \
-H "Cookie: session=your-session-token" \
-d '{
"provider": "google",
"refreshToken": "1//0gLn8..."
}'
Request Body
OAuth provider: google, github, or notion
New refresh token for the account
Response
Returns the updated account object.
Success (200)
Error (400)
Error (404)
{
"id": "acc_1234567890",
"accountId": "google_user_id_xyz",
"providerId": "google",
"userId": "user123",
"accessToken": "ya29.a0AfH6SMB...",
"refreshToken": "1//0gLn8...",
"idToken": null,
"accessTokenExpiresAt": "2024-01-20T16:30:00.000Z",
"refreshTokenExpiresAt": null,
"scope": "https://www.googleapis.com/auth/userinfo.email",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T16:00:00.000Z"
}
{ "error": "Account not found or could not be updated" }
Delete Account
Disconnect an OAuth account.
curl -X DELETE "http://localhost:3000/api/accounts?provider=google" \
-H "Cookie: session=your-session-token"
Query Parameters
OAuth provider to disconnect: google, github, or notion
Response
Returns the deleted account object.
Success (200)
Error (400)
Error (404)
{
"id": "acc_1234567890",
"accountId": "google_user_id_xyz",
"providerId": "google",
"userId": "user123",
"accessToken": "ya29.a0AfH6SMB...",
"refreshToken": "1//0gLn8...",
"idToken": null,
"accessTokenExpiresAt": "2024-01-20T16:30:00.000Z",
"refreshTokenExpiresAt": null,
"scope": "https://www.googleapis.com/auth/userinfo.email",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T15:30:00.000Z"
}
{ "error": "Account not found" }
Deleting an account will disconnect the OAuth integration and may break widgets that depend on it.
OAuth Flow
Connecting a new account typically follows this flow:
- Initiate OAuth - User clicks “Connect [Provider]” in the UI
- Redirect to Provider - User is redirected to the OAuth provider’s authorization page
- Authorization - User grants permissions
- Callback - Provider redirects back to Forge with authorization code
- Token Exchange - BetterAuth exchanges the code for access/refresh tokens
- Account Created - Account record is created in the database
- Widget Access - Widgets can now use the account to access provider APIs
This flow is handled automatically by BetterAuth. The Accounts API is primarily used to:
- View connected accounts
- Update refresh tokens when needed
- Disconnect accounts
Token Refresh
Access tokens expire periodically. When a widget needs to use an expired token:
- Detect token expiration (check
accessTokenExpiresAt)
- Use the refresh token to obtain a new access token
- Update the account using
PUT /api/accounts
Most OAuth libraries handle this automatically.