> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meetingkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The calendar connect link object

> A hosted link that takes a user through calendar consent.

A connect link sends one of your users through Google or Microsoft consent and brings them back to your product. It lives 24 hours. See [Connect calendars](/meetingkit/calendar-connection).

## Attributes

<ResponseField name="id" type="string">
  Stable typed ID beginning with `ccl_`.
</ResponseField>

<ResponseField name="object" type="string">
  Always `calendar_connect_link`.
</ResponseField>

<ResponseField name="workspace_id" type="string">
  Workspace ID, beginning with `wks_`. Treat it as an opaque string.
</ResponseField>

<ResponseField name="member_id" type="string | null">
  The member connecting, or `null` to create the member from the connected account.
</ResponseField>

<ResponseField name="provider" type="string">
  * `google`: Google Calendar.
  * `microsoft`: Microsoft Outlook calendar.
</ResponseField>

<ResponseField name="return_url" type="string">
  Where the browser returns after consent, with the outcome in the query string.
</ResponseField>

<ResponseField name="client_reference_id" type="string | null">
  Your own reference, returned on the redirect.
</ResponseField>

<ResponseField name="member_data" type="object | null">
  The member the consent creates, as you sent it (`metadata` is `{}` when you sent none), or `null`.

  <Expandable title="properties">
    <ResponseField name="name" type="string">
      The member's name. A person who already has a MeetingKit account keeps their own.
    </ResponseField>

    <ResponseField name="email" type="string">
      Pre-fills the provider's account chooser. A hint, never a check.
    </ResponseField>

    <ResponseField name="metadata" type="object">
      Set on the member when it is created, or merged into an existing member's.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="url" type="string | null">
  The link to send the user to. `null` once it can no longer be opened.
</ResponseField>

<ResponseField name="expires_at" type="string">
  When the link stops working, 24 hours after it was created.
</ResponseField>

<ResponseField name="status" type="string">
  * `open`: Waiting for the user, including after they declined consent.
  * `completed`: The user connected their calendar.
  * `failed`: It could not connect. `error` says why.
  * `expired`: 24 hours went by.
</ResponseField>

<ResponseField name="calendar_connection_id" type="string | null">
  The connection it made, once `status` is `completed`.
</ResponseField>

<ResponseField name="error" type="object | null">
  Why the link failed, or `null`.

  <Expandable title="properties">
    <ResponseField name="code" type="string">
      `access_denied`, `link_expired`, `link_used`, `account_mismatch`,
      `calendar_already_connected`, `account_in_use`, `not_authorized`, `connect_failed`
    </ResponseField>

    <ResponseField name="message" type="string">
      What happened.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="created_at" type="string">
  When the link was created, in ISO 8601.
</ResponseField>

<ResponseExample>
  ```json The calendar connect link object theme={null}
  {
    "id": "ccl_01k6c0r9s8x7c2dvq3m5n6p4ab",
    "object": "calendar_connect_link",
    "workspace_id": "wks_01k6a2r9s8x7c2dvq3m5n6p4ab",
    "member_id": null,
    "provider": "google",
    "return_url": "https://app.gurusup.com/settings/calendar",
    "client_reference_id": "gs_user_4821",
    "member_data": {
      "name": "Ana García",
      "email": "ana@acme.com",
      "metadata": { "gurusup_user_id": "gs_user_4821" }
    },
    "url": "https://api.meetingkit.com/connect/calendar/ccl_01k6c0r9s8x7c2dvq3m5n6p4ab?token=…",
    "expires_at": "2026-09-23T10:10:00Z",
    "status": "open",
    "calendar_connection_id": null,
    "error": null,
    "created_at": "2026-09-22T10:10:00Z"
  }
  ```
</ResponseExample>
