---
title: "Create a calendar connect link"
method: POST
path: "/calendar_connect_links"
tags: ["Calendar connections"]
---

# Create a calendar connect link

`POST /calendar_connect_links`

## Request

- Base URL: `https://www.happyscribe.com/api/v1`
- URL: `https://www.happyscribe.com/api/v1/calendar_connect_links`
- Auth: API key in header `Authorization`

A hosted link that takes one of your users through Google or Microsoft consent and
connects their calendar. Put `url` behind your "Connect calendar" button: create it
when your page renders, or from a route of your own behind your login that creates it
and redirects. Creating one again for the same member, provider, `return_url`,
`client_reference_id` and `member_data` while one is open returns that link, so a
page that creates a link on every render adds nothing.

After consent the browser returns to `return_url` with
`calendar_connect_link_id`, `status` (`connected` or `error`), and `member_id`,
`calendar_connection_id`, `error` and `client_reference_id` when they apply.
`calendar_connection.connected` is sent as well.

Send `member_data` and the member is created when the user consents, with that name
and `metadata`. Its email is the account the user connects, as the provider verifies
it (a Microsoft account's user principal name), and it is never one of the workspace's
owners or admins. `member_data.email` only pre-fills the provider's account chooser.
Send `member_id` instead to reconnect a member you already have: whichever account
they approve is connected. A member whose calendar is already connected, through the
API or in HappyScribe, must be disconnected first.

## Request body

- CalendarConnectLinkCreate
  - `workspace_id` string, required: Workspace ID, beginning with `wks_`. Treat it as an opaque string. Integer workspace ids are still accepted.
  - `provider` 'google' | 'microsoft', required: The calendar to connect. - `google`: Google Calendar. - `microsoft`: Microsoft Outlook calendar.
  - `return_url` string, required: An absolute https URL. The browser returns here after consent, with the outcome in the query string.
  - `member_data` CalendarConnectLinkMemberData: The member to create when the user consents. Nothing is created until then.
    - `name` string: The member's name. A person who already has a HappyScribe account keeps their own.
    - `email` string, email: Pre-fills Google's or Microsoft's account chooser. It is a hint, never a check: the member's email is the account the user approves.
    - `metadata` Metadata: Your own key-value pairs, for your ids and context. HappyScribe stores them, returns them on the object and in every webhook that carries it, and never acts on them. Up to 50 keys of up to 40 characters (no square brackets), values up to 500 characters. See [metadata](/meetingkit/setup#a-workspace-per-customer).
  - `member_id` string: An existing member to reconnect, or one you created with `POST /members`. Whichever account they approve is connected. Not with `member_data`; send neither to create the member from the connected account with no name or metadata.
  - `client_reference_id` string: Your own id for the user, echoed on `return_url` and the link.

## Response `201`

The link, new or the open one it matched.

- CalendarConnectLink
  - `id` string: Stable typed ID beginning with `ccl_`.
  - `object` string: Always `calendar_connect_link`.
  - `workspace_id` string: Workspace ID, beginning with `wks_`. Treat it as an opaque string.
  - `member_id` string, nullable: The member connecting, or `null` to create the member from the connected account.
  - `provider` 'google' | 'microsoft': The calendar to connect. - `google`: Google Calendar. - `microsoft`: Microsoft Outlook calendar.
  - `return_url` string: Where the browser returns after consent, with the outcome in the query string.
  - `client_reference_id` string, nullable: Your own reference, returned on the redirect.
  - `member_data` CalendarConnectLinkMemberData: The member to create when the user consents. Nothing is created until then.
    - `name` string: The member's name. A person who already has a HappyScribe account keeps their own.
    - `email` string, email: Pre-fills Google's or Microsoft's account chooser. It is a hint, never a check: the member's email is the account the user approves.
    - `metadata` Metadata: Your own key-value pairs, for your ids and context. HappyScribe stores them, returns them on the object and in every webhook that carries it, and never acts on them. Up to 50 keys of up to 40 characters (no square brackets), values up to 500 characters. See [metadata](/meetingkit/setup#a-workspace-per-customer).
  - `url` string, nullable: The link to send the user to. `null` once it can no longer be opened.
  - `expires_at` string, date-time: When the link stops working, 24 hours after it was created.
  - `status` 'open' | 'completed' | 'failed' | 'expired': - `open`: waiting for the user, including after they declined consent. - `completed`: the user connected their calendar; see `calendar_connection_id`. - `failed`: it could not connect; `error` says why. - `expired`: 24 hours went by.
  - `calendar_connection_id` string, nullable: The connection it made, once `status` is `completed`.
  - `error` object, nullable: Why the link failed, or `null`.
    - `code` string: `access_denied`, `link_expired`, `link_used`, `account_mismatch`, `calendar_already_connected`, `account_in_use`, `not_authorized`, `sso_required`, `connect_failed`
    - `message` string: What happened.
  - `created_at` string, date-time: When the link was created, in ISO 8601.

## Other responses

- `401`: Missing or invalid API key, or the key is not an owner or admin of the workspace.
- `404`: The workspace or the member is not one the key can see.
- `409`: The member already has a connected calendar (`calendar_already_connected`). Disconnect it first.
- `422`: Invalid `provider`, `return_url` (it must be an absolute https URL), `member_data` or `client_reference_id`, or both `member_data` and `member_id`.

---

[API](https://skmtc.dev/happyscribe/apis/happyscribe-api.md) - [All operations](https://skmtc.dev/happyscribe/apis/happyscribe-api/llms.txt) - [OpenAPI document](https://skmtc.dev/happyscribe/apis/happyscribe-api/revisions/1281bd968c3d?raw)
