Users connect their Google or Microsoft calendar on a page BentoCal hosts. You don't write any OAuth code: your server creates a connect session, sends the user to its URL, and checks the result when they come back.
The flow
- Your server calls
POST /connect_sessionswith your id for the user and a registeredredirect_uri. - You send the user to the returned
url(a redirect, a link or a popup). - On the hosted page they accept the terms, choose Google or Microsoft and sign in.
- BentoCal sends them back to your
redirect_uriwith the result in the query string. - Your server confirms the result with
GET /connect_sessions/{id}or theconnection.createdwebhook.
curl -X POST https://api.bentocal.com/au/v1/connect_sessions \
-H "Authorization: Bearer $BENTOCAL_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"redirect_uri": "https://app.example.com/calendar/connected"
}'The response has the session id, the url to send the user to and expires_at. Each session can be used once and expires after 30 minutes. Create a new one each time the user clicks "Connect calendar".
What the user sees
The page shows your application's name and logo, what it will be able to do (see free/busy time, add and update events), and a checkbox to accept BentoCal's terms. The page follows the user's light or dark mode.
Set the name and logo on the application's Settings tab under Branding: Display name is your product name as your users know it, and Logo is an image under 1 MB. Without a logo, the page shows the first letter of the display name.
Redirect URIs
redirect_uri must exactly match one of the URIs on the application's Settings tab, under Redirect URIs. Otherwise the request fails with 400 invalid_request.
httpsonly. Development applications may also usehttp://localhostandhttp://127.0.0.1.- No
#fragment, at most 2048 characters, up to 20 per application.
Handle the redirect
When the flow ends, the user is redirected (303) to:
{redirect_uri}?connect_session_id=cs_…&status=successstatus | Meaning |
|---|---|
success | A calendar was connected or relinked. |
denied | The user declined at Google or Microsoft. |
error | Something went wrong. error_code says what. |
error_code | Meaning |
|---|---|
account_mismatch | During a relink the user signed in to a different account from the one being relinked. |
connection_limit_reached | The company reached the development limit. See Development and production. |
connection_not_found | The connection being relinked was deleted while the user was signing in. |
session_expired | The user took longer than 30 minutes. |
internal_error | An unexpected error. Try again. |
New codes may be added, so treat unknown ones like internal_error.
GET /connect_sessions/{connect_session_id} (or the connection.created webhook) before you rely on it.Session statuses
GET /connect_sessions/{connect_session_id} returns the session with one of these statuses:
status | Meaning |
|---|---|
pending | Created, not opened yet. |
redirected | The user went on to Google or Microsoft. |
completed | A connection was made or relinked. connection holds it. |
denied | The user declined at the provider. |
error | See error_code. |
expired | Not finished within 30 minutes. |
After connecting
- The user exists from now on: use your user id with free/busy and availability and events.
- If the user had no usable connection, the new one becomes their default connection, which events are written to.
- A
connection.createdwebhook is sent. BentoCal also starts watching the account's primary calendar, so you getcalendar.changedwebhooks if you subscribe to them. - A user can connect several accounts by going through the flow again. Connecting an account they already connected updates that same connection and sends
connection.relinked.
Choose the provider
Pass provider (google or microsoft) to offer only that provider on the connect page. The page still shows, with its terms checkbox, but only one button.
{ "user_id": "user_123", "redirect_uri": "https://app.example.com/calendar/connected", "provider": "microsoft" }Relink a connection
Google and Microsoft can stop accepting a connection's access, for example when the user changes their password or removes your app's access. BentoCal then marks the connection relink_required, sends a connection.relink_required webhook, and calls that need the connection fail with 409 relink_required.
To fix it, send the user through a connect session for that connection:
{ "user_id": "user_123", "redirect_uri": "https://app.example.com/calendar/connected", "connection_id": "conn_4kT9pQ2vXa7LmN3s" }The page says Reconnect your calendar and asks the user to sign in again as the same account. If they do, the connection keeps its id and goes back to active, and connection.relinked is sent. If they sign in to a different account, the session ends with error_code: account_mismatch.
Microsoft 365 admin consent
Some organisations stop their users from approving third-party apps themselves. Those users see "Need admin approval" from Microsoft instead of the consent screen.
The application's Admin consent tab has an Admin consent link to send to that organisation's IT team. Once a Microsoft 365 global admin approves your application, everyone in their tenant can connect. The connect page also shows users a "Work or school Microsoft account that needs approval? Ask your IT admin." link to the same page.
Google Workspace has no equivalent link. Workspace admins can allow BentoCal in their Admin console under Security, API controls, App access control.