SapanCalDeveloper Docs

Managing users and connections

Look up users and their connections, change the default calendar, disconnect accounts and erase users.

BentoCal identifies your users by your own ids. A user exists once they've connected a calendar, and each Google or Microsoft account they connect is a connection. This page covers reading and managing both.

Get a user

GET /users/{user_id} returns the user and all their connections, including revoked ones:

JSON
{
  "user_id": "user_123",
  "default_connection_id": "conn_4kT9pQ2vXa7LmN3s",
  "connections": [
    {
      "id": "conn_4kT9pQ2vXa7LmN3s",
      "user_id": "user_123",
      "provider": "google",
      "email": "sam@example.com",
      "display_name": "Sam Lee",
      "status": "active",
      "primary_calendar_id": "sam@example.com",
      "connected_at": "2026-10-01T03:12:45Z",
      "last_used_at": "2026-10-14T22:01:09Z"
    }
  ],
  "created_at": "2026-10-01T03:12:45Z"
}

A user who has never connected a calendar returns 404 not_found. URL-encode user ids that contain characters like / or @.

Connection statuses

statusMeaningWhat to do
activeWorking.Nothing.
relink_requiredGoogle or Microsoft stopped accepting its access, for example because the user removed your app's access.Send the user through a relink session. The connection.relink_required webhook tells you when this happens.
revokedDisconnected for good. Kept so you can see its history.Send the user through a new connect session if they want to connect again.

The default connection

Events are written to the user's default connection unless the write names a connection_id. The first connection a user makes becomes their default, and a new connection becomes the default whenever the user has no usable one.

To change it, call PATCH /users/{user_id} with an active connection of that user:

Bash
curl -X PATCH https://api.bentocal.com/au/v1/users/user_123 \
  -H "Authorization: Bearer $BENTOCAL_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "default_connection_id": "conn_8Wm3Jd6Rt1Zq5LnC" }'

List a connection's calendars

GET /connections/{connection_id}/calendars reads the account's calendars live from the provider:

JSON
[
  { "id": "sam@example.com", "name": "Sam Lee", "primary": true, "can_write": true, "time_zone": "Australia/Sydney" }
]

Use the ids in calendar_ids for free/busy and availability, or as calendar_id when writing events. Only calendars with can_write: true accept events. You can use this to let users choose which calendars count as busy.

Disconnect an account

DELETE /connections/{connection_id} revokes a connection. Use it when a user clicks "Disconnect" in your app:

  • BentoCal revokes its access at Google or Microsoft (best effort) and deletes the stored tokens.
  • Event links made through it are forgotten. The events stay in the user's calendar.
  • The connection stays readable with status revoked.
  • If it was the user's default, their oldest other active connection becomes the default.
  • A connection.revoked webhook is sent.

Revoking a connection that is already revoked is a success.

Erase a user

DELETE /users/{user_id} removes everything BentoCal holds about a user. Use it when someone closes their account with you, or asks for their data to be deleted:

  • Every connection is revoked at the provider (best effort) and its tokens are deleted.
  • The user's event links and the user record are deleted. Events already in their calendars are left in place.
  • A connection.revoked webhook is sent for each connection that wasn't already revoked.

After this, GET /users/{user_id} returns 404. If the person comes back, they connect again as a new user.

In the console

The application's Connections tab lists every connection with its user, provider, status, when it connected and when it was last used. Search by user id or email, filter by status, and open a connection to see its history.