# Update booking link

Change a booking link you own. Only supplied fields change. Activating a link requires calendar write permission; changing reminder timing also updates future bookings.

POST https://api.brigg.app/v1/operations/meetings.UpdateBookingLink

## Access & visibility

Allow `meetings.UpdateBookingLink` on your API key.

**Acting member required.** Send `Brigg-Act-As` with an [approved member account ID](https://developer.brigg.app/authentication#member-delegation). The key supplies permissions; the member selects whose data is used.

The selected member must be active and approved by the credential. This selects whose private data is used; the credential supplies permissions. Private ownership and project boundaries still apply.

[Set up authentication](https://developer.brigg.app/authentication) · [Choose permissions](https://developer.brigg.app/permissions)

## Request fields

Send a JSON object with the following fields. Required fields must be included; omit optional fields you do not need.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Use a link's id from items. This is not an individual booking ID. [meetings.ListBookingLinks](https://developer.brigg.app/reference/meetings/ListBookingLinks). At least 1 character. |
| `name` | string | No | Meeting name displayed on the public booking page. At least 1 character. At most 120 characters. |
| `description` | string | No | Introduction displayed to invitees. Send an empty string to clear it. At most 2000 characters. |
| `duration_minutes` | integer | No | Fixed meeting length in minutes. Supplying this alone clears any previous choice of lengths. duration_options takes precedence when both are supplied. Range: 10 to 480. |
| `duration_options` | array of integer | No | Offered lengths in minutes. One length makes a fixed-duration link; several let the invitee choose. The stored duration_minutes is the shortest offered length. At least 1 item. At most 4 items. |
| `location_kind` | string | No | video creates a conference link; phone, in_person and custom use location_detail for instructions or an address. Allowed: `"video"`, `"phone"`, `"in_person"`, `"custom"`. |
| `location_detail` | string | No | Instructions for the chosen location, such as a phone number or street address. Send an empty string to clear them. At most 500 characters. |
| `timezone` | string | No | An IANA time zone; refused invalid_timezone otherwise. |
| `availability` | [object](#request-availability) | No | Complete weekly availability in the link's IANA timezone. Omitted or empty weekdays within this object are unavailable. This replaces the whole schedule, not only the listed days. |
| `window_days` | integer | No | Number of days into the future an invitee can book. Range: 1 to 90. |
| `min_notice_minutes` | integer | No | Minimum notice required before a meeting starts, in minutes. Range: 0 to 10080. |
| `buffer_before_minutes` | integer | No | Minutes reserved before each meeting. Range: 0 to 240. |
| `buffer_after_minutes` | integer | No | Minutes reserved after each meeting. Range: 0 to 240. |
| `max_per_day` | integer | No | Maximum bookings in a day. Zero means no daily limit. Range: 0 to 50. |
| `questions` | array of [object](#request-questions) | No | Complete replacement question list. Send [] to remove all questions; omit the field on an update to preserve them. At most 5 items. |
| `reminder_hours` | integer | No | Hours before a meeting to send a reminder. Zero disables reminders. Range: 0 to 336. |
| `collect_phone` | boolean | No | Whether the booking form asks invitees for a phone number. |
| `active` | boolean | No | Whether new bookings are accepted. False does not cancel confirmed appointments. Setting true requires the acting member's calendar write permission. |

### request.availability

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `mon` | array of [object](#request-availability-mon) | No | Monday availability intervals in the booking link's timezone. At most 6 items. |
| `tue` | array of [object](#request-availability-tue) | No | Tuesday availability intervals in the booking link's timezone. At most 6 items. |
| `wed` | array of [object](#request-availability-wed) | No | Wednesday availability intervals in the booking link's timezone. At most 6 items. |
| `thu` | array of [object](#request-availability-thu) | No | Thursday availability intervals in the booking link's timezone. At most 6 items. |
| `fri` | array of [object](#request-availability-fri) | No | Friday availability intervals in the booking link's timezone. At most 6 items. |
| `sat` | array of [object](#request-availability-sat) | No | Saturday availability intervals in the booking link's timezone. At most 6 items. |
| `sun` | array of [object](#request-availability-sun) | No | Sunday availability intervals in the booking link's timezone. At most 6 items. |

### request.availability.mon[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.tue[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.wed[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.thu[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.fri[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.sat[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.availability.sun[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### request.questions[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Stable question key you choose, unique within this link, such as project_goal. Reuse it when editing that question; no create-record call is needed. At least 1 character. At most 40 characters. |
| `label` | string | Yes | Text shown for this booking question or choice. At least 1 character. At most 200 characters. |
| `kind` | string | Yes | Question control: text is a short answer, textarea a longer answer, select a choice from options, and checkbox a yes/no response. Allowed: `"text"`, `"textarea"`, `"select"`, `"checkbox"`. |
| `required` | boolean | No | Whether the invitee must answer this booking question. |
| `options` | array of string | No | Choices for a select question; at least one is required when kind=select. Omit for other controls. At least 1 item. At most 12 items. |

## Patch only what you intend to change

Omitted top-level fields keep their current values; creation defaults are not reapplied. For example, {id, active:false} disables new bookings without changing duration, availability or reminders. Read the returned link for the complete saved configuration.

Supplying availability replaces the entire weekly schedule, and questions replaces the entire question list. Include entries you want to retain. Empty description and location_detail strings clear those values. Changing reminder_hours also reschedules reminders for existing future bookings; it does not cancel those bookings.

## Booking links and individual bookings

A booking link belongs to the acting member and advertises availability in its IANA `timezone`. Availability times are local wall-clock times in that zone; confirmed bookings use numeric timestamps. Use [List booking links](https://developer.brigg.app/reference/meetings/ListBookingLinks) to read both links (`items`) and their confirmed bookings starting in the next 366 days (`upcoming_bookings`).

The link ID changes or deactivates the booking page. An individual booking ID cancels one confirmed appointment. Deactivating a link stops new bookings without cancelling appointments already made. A link with future bookings cannot be deleted; deactivate it or cancel those bookings first. Active links require a connected writable calendar.

## Response

Returns **200 OK** with a JSON body.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `link` | [BookingLink](#bookinglink-response-link) | Yes | The link row plus its public url. |

### BookingLink · response.link

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Booking link ID. Use it to update or delete this link. |
| `org_id` | string | Yes | Workspace that owns the link. |
| `owner_account_id` | string | Yes | Member whose calendar supplies the available time slots. |
| `slug` | string | Yes | Unique URL segment for this link within the workspace. |
| `name` | string | Yes | Meeting name displayed to invitees. |
| `description` | string or null | Yes | Introduction displayed on the booking page. |
| `duration_minutes` | integer | Yes | Default meeting length in minutes; the shortest length when several are offered. |
| `duration_options` | array of integer or null | Yes | Offered meeting lengths in minutes. Null means a fixed duration_minutes. |
| `location_kind` | string | Yes | video creates a conference link; phone, in_person and custom use location_detail for instructions or an address. Allowed: `"video"`, `"phone"`, `"in_person"`, `"custom"`. |
| `location_detail` | string or null | Yes | Address, phone instructions or other location details. |
| `timezone` | string | Yes | IANA time zone used to interpret the weekly availability, for example Europe/Oslo. |
| `availability` | [WeeklyAvailability](#weeklyavailability-response-link-availability) | Yes | Bookable local-time intervals by weekday. Missing or empty days are unavailable. |
| `window_days` | integer | Yes | How many days into the future invitees can book. |
| `min_notice_minutes` | integer | Yes | Minimum time before a meeting can start, in minutes. |
| `buffer_before_minutes` | integer | Yes | Minutes reserved before each meeting. |
| `buffer_after_minutes` | integer | Yes | Minutes reserved after each meeting. |
| `max_per_day` | integer | Yes | Maximum bookings per day. Zero means no daily limit. |
| `questions` | array of [object](#response-link-questions) or null | Yes | Additional questions shown to invitees. Null means no questions. |
| `reminder_hours` | integer | Yes | Hours before the meeting to send a reminder. Zero disables reminders. |
| `collect_phone` | boolean | Yes | Whether invitees are asked for a phone number. |
| `active` | boolean | Yes | Whether invitees can make new bookings through this link. |
| `created_at` | integer | Yes | Creation time in Unix milliseconds. |
| `updated_at` | integer | Yes | Last change in Unix milliseconds. |
| `url` | string | Yes | Public booking URL to share with invitees. Format: uri. |

### WeeklyAvailability · response.link.availability

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `mon` | array of [object](#response-link-availability-mon) | No | Monday availability intervals in the booking link's timezone. At most 6 items. |
| `tue` | array of [object](#response-link-availability-tue) | No | Tuesday availability intervals in the booking link's timezone. At most 6 items. |
| `wed` | array of [object](#response-link-availability-wed) | No | Wednesday availability intervals in the booking link's timezone. At most 6 items. |
| `thu` | array of [object](#response-link-availability-thu) | No | Thursday availability intervals in the booking link's timezone. At most 6 items. |
| `fri` | array of [object](#response-link-availability-fri) | No | Friday availability intervals in the booking link's timezone. At most 6 items. |
| `sat` | array of [object](#response-link-availability-sat) | No | Saturday availability intervals in the booking link's timezone. At most 6 items. |
| `sun` | array of [object](#response-link-availability-sun) | No | Sunday availability intervals in the booking link's timezone. At most 6 items. |

### response.link.availability.mon[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.tue[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.wed[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.thu[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.fri[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.sat[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.availability.sun[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | string | Yes | Start of the interval. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |
| `end` | string | Yes | End of the interval; must be later than its start. Pattern: `^([01]\d\|2[0-3]):[0-5]\d$`. |

### response.link.questions[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Stable question key you choose, unique within this link, such as project_goal. Reuse it when editing that question; no create-record call is needed. At least 1 character. At most 40 characters. |
| `label` | string | Yes | Text shown for this booking question or choice. At least 1 character. At most 200 characters. |
| `kind` | string | Yes | Question control: text is a short answer, textarea a longer answer, select a choice from options, and checkbox a yes/no response. Allowed: `"text"`, `"textarea"`, `"select"`, `"checkbox"`. |
| `required` | boolean | No | Whether the invitee must answer this booking question. |
| `options` | array of string | No | Choices for a select question; at least one is required when kind=select. Omit for other controls. At least 1 item. At most 12 items. |

## Errors & retries

Set `BRIGG_REQUEST_ID` once for each logical action. The samples send it as `Idempotency-Key`. Reuse the same value and body on retries, including after a timeout; a missing response does not prove the action failed.

For rate limits, follow the server’s retry guidance and back off. See [HTTP errors](https://developer.brigg.app/http#errors) and [safe retries and limits](https://developer.brigg.app/reliability).

| HTTP status | Code | What to do |
| --- | --- | --- |
| 400 | `invalid_json` | Send a JSON object with Content-Type: application/json. |
| 400 | `invalid_input` | Check the request fields and types. Supply a stable Idempotency-Key containing 1–200 characters. |
| 401 | `invalid_key` | The workspace API key is missing, invalid or revoked. |
| 403 | `forbidden` | Check the key’s operation and resource grants. Supply Brigg-Act-As with a member authorized by the key’s delegation grant. The selected member must be active and approved by the credential. This selects whose private data is used; the credential supplies permissions. Private ownership and project boundaries still apply. |
| 404 | `not_found` | The requested operation or resource is not available to this credential. |
| 429 | `rate_limited` | Wait for Retry-After before retrying. Reuse the original Idempotency-Key. |
| 409 | `needs_auth` | Grant calendar write access before activating the link. |
| 422 | `invalid_timezone` | Use a valid IANA time zone. |

## Next steps

- [List booking links](https://developer.brigg.app/reference/meetings/ListBookingLinks)
- [List calendar connections](https://developer.brigg.app/reference/meetings/ListCalendarConnections)
- [Cancel booking](https://developer.brigg.app/reference/meetings/CancelBooking)

[Download OpenAPI](https://developer.brigg.app/openapi.json) · [Versioning & retirement](https://developer.brigg.app/versioning)

## Examples

### Example request

Fictional values. Replace IDs and business details with values from your workspace.
#### cURL


```sh
curl 'https://api.brigg.app/v1/operations/meetings.UpdateBookingLink' \
  -H "Authorization: Bearer $BRIGG_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Brigg-Act-As: $BRIGG_ACT_AS" \
  -H "Idempotency-Key: $BRIGG_REQUEST_ID" \
  --data-raw '{
  "id": "bkl_example",
  "active": false
}'
```

#### TypeScript


```typescript
const actAs = process.env.BRIGG_ACT_AS;
if (!actAs) throw new Error("Set BRIGG_ACT_AS to an approved member account ID.");

const requestId = process.env.BRIGG_REQUEST_ID;
if (!requestId) throw new Error("Set BRIGG_REQUEST_ID once per action and reuse it on retries.");

const response = await fetch("https://api.brigg.app/v1/operations/meetings.UpdateBookingLink", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BRIGG_API_KEY}`,
    "Content-Type": "application/json",
    "Brigg-Act-As": actAs,
    "Idempotency-Key": requestId, // Create once per action; reuse on retries.
  },
  body: JSON.stringify({
    "id": "bkl_example",
    "active": false
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${result.error} — ${result.message}`);
console.log(result);
```

#### Python


```python
import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

request_id = os.environ["BRIGG_REQUEST_ID"]  # Reuse for retries of this action.
payload = {
  "id": "bkl_example",
  "active": False
}
request = Request(
    "https://api.brigg.app/v1/operations/meetings.UpdateBookingLink",
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['BRIGG_API_KEY']}",
        "Content-Type": "application/json",
        "Brigg-Act-As": os.environ["BRIGG_ACT_AS"],
        "Idempotency-Key": request_id,  # Create once per action; reuse on retries.
    },
    method="POST",
)
try:
    with urlopen(request) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))
    raise
```

#### Response example


```json
{
  "link": {
    "id": "bkl_example",
    "org_id": "o_example",
    "owner_account_id": "a_example",
    "slug": "project-introduction",
    "name": "Project introduction",
    "description": null,
    "duration_minutes": 30,
    "duration_options": null,
    "location_kind": "video",
    "location_detail": null,
    "timezone": "Europe/Oslo",
    "availability": {
      "mon": [
        {
          "start": "09:00",
          "end": "17:00"
        }
      ]
    },
    "window_days": 30,
    "min_notice_minutes": 240,
    "buffer_before_minutes": 0,
    "buffer_after_minutes": 0,
    "max_per_day": 0,
    "questions": null,
    "reminder_hours": 24,
    "collect_phone": false,
    "active": false,
    "created_at": 1794301200000,
    "updated_at": 1794301200000,
    "url": "https://example.com/book/project-introduction"
  }
}
```

## JSON schemas


```json-schema-request
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "Use a link's id from items. This is not an individual booking ID. [meetings.ListBookingLinks](https://developer.brigg.app/reference/meetings/ListBookingLinks)."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "Meeting name displayed on the public booking page."
    },
    "description": {
      "type": "string",
      "maxLength": 2000,
      "description": "Introduction displayed to invitees. Send an empty string to clear it."
    },
    "duration_minutes": {
      "type": "integer",
      "minimum": 10,
      "maximum": 480,
      "description": "Fixed meeting length in minutes. Supplying this alone clears any previous choice of lengths. duration_options takes precedence when both are supplied."
    },
    "duration_options": {
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 10,
        "maximum": 480
      },
      "minItems": 1,
      "maxItems": 4,
      "description": "Offered lengths in minutes. One length makes a fixed-duration link; several let the invitee choose. The stored duration_minutes is the shortest offered length."
    },
    "location_kind": {
      "type": "string",
      "enum": [
        "video",
        "phone",
        "in_person",
        "custom"
      ],
      "description": "video creates a conference link; phone, in_person and custom use location_detail for instructions or an address."
    },
    "location_detail": {
      "type": "string",
      "maxLength": 500,
      "description": "Instructions for the chosen location, such as a phone number or street address. Send an empty string to clear them."
    },
    "timezone": {
      "type": "string",
      "description": "An IANA time zone; refused invalid_timezone otherwise."
    },
    "availability": {
      "type": "object",
      "properties": {
        "mon": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Monday availability intervals in the booking link's timezone."
        },
        "tue": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Tuesday availability intervals in the booking link's timezone."
        },
        "wed": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Wednesday availability intervals in the booking link's timezone."
        },
        "thu": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Thursday availability intervals in the booking link's timezone."
        },
        "fri": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Friday availability intervals in the booking link's timezone."
        },
        "sat": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Saturday availability intervals in the booking link's timezone."
        },
        "sun": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "Start of the interval."
              },
              "end": {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                "description": "End of the interval; must be later than its start."
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          },
          "maxItems": 6,
          "description": "Sunday availability intervals in the booking link's timezone."
        }
      },
      "additionalProperties": false,
      "description": "Complete weekly availability in the link's IANA timezone. Omitted or empty weekdays within this object are unavailable. This replaces the whole schedule, not only the listed days."
    },
    "window_days": {
      "type": "integer",
      "minimum": 1,
      "maximum": 90,
      "description": "Number of days into the future an invitee can book."
    },
    "min_notice_minutes": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10080,
      "description": "Minimum notice required before a meeting starts, in minutes."
    },
    "buffer_before_minutes": {
      "type": "integer",
      "minimum": 0,
      "maximum": 240,
      "description": "Minutes reserved before each meeting."
    },
    "buffer_after_minutes": {
      "type": "integer",
      "minimum": 0,
      "maximum": 240,
      "description": "Minutes reserved after each meeting."
    },
    "max_per_day": {
      "type": "integer",
      "minimum": 0,
      "maximum": 50,
      "description": "Maximum bookings in a day. Zero means no daily limit."
    },
    "questions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40,
            "description": "Stable question key you choose, unique within this link, such as project_goal. Reuse it when editing that question; no create-record call is needed."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Text shown for this booking question or choice."
          },
          "kind": {
            "type": "string",
            "enum": [
              "text",
              "textarea",
              "select",
              "checkbox"
            ],
            "description": "Question control: text is a short answer, textarea a longer answer, select a choice from options, and checkbox a yes/no response."
          },
          "required": {
            "type": "boolean",
            "description": "Whether the invitee must answer this booking question."
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            },
            "minItems": 1,
            "maxItems": 12,
            "description": "Choices for a select question; at least one is required when kind=select. Omit for other controls."
          }
        },
        "required": [
          "id",
          "label",
          "kind"
        ],
        "additionalProperties": false
      },
      "maxItems": 5,
      "description": "Complete replacement question list. Send [] to remove all questions; omit the field on an update to preserve them."
    },
    "reminder_hours": {
      "type": "integer",
      "minimum": 0,
      "maximum": 336,
      "description": "Hours before a meeting to send a reminder. Zero disables reminders."
    },
    "collect_phone": {
      "type": "boolean",
      "description": "Whether the booking form asks invitees for a phone number."
    },
    "active": {
      "type": "boolean",
      "description": "Whether new bookings are accepted. False does not cancel confirmed appointments. Setting true requires the acting member's calendar write permission."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "id": "bkl_example",
      "active": false
    }
  ]
}
```


```json-schema-response
{
  "type": "object",
  "properties": {
    "link": {
      "description": "The link row plus its public url.",
      "title": "BookingLink",
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Booking link ID. Use it to update or delete this link."
        },
        "org_id": {
          "type": "string",
          "description": "Workspace that owns the link."
        },
        "owner_account_id": {
          "type": "string",
          "description": "Member whose calendar supplies the available time slots."
        },
        "slug": {
          "type": "string",
          "description": "Unique URL segment for this link within the workspace."
        },
        "name": {
          "type": "string",
          "description": "Meeting name displayed to invitees."
        },
        "description": {
          "description": "Introduction displayed on the booking page.",
          "anyOf": [
            {
              "type": "string",
              "description": "Introduction displayed on the booking page."
            },
            {
              "type": "null"
            }
          ]
        },
        "duration_minutes": {
          "type": "integer",
          "description": "Default meeting length in minutes; the shortest length when several are offered."
        },
        "duration_options": {
          "description": "Offered meeting lengths in minutes. Null means a fixed duration_minutes.",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "integer"
              },
              "description": "Offered meeting lengths in minutes. Null means a fixed duration_minutes."
            },
            {
              "type": "null"
            }
          ]
        },
        "location_kind": {
          "type": "string",
          "enum": [
            "video",
            "phone",
            "in_person",
            "custom"
          ],
          "description": "video creates a conference link; phone, in_person and custom use location_detail for instructions or an address."
        },
        "location_detail": {
          "description": "Address, phone instructions or other location details.",
          "anyOf": [
            {
              "type": "string",
              "description": "Address, phone instructions or other location details."
            },
            {
              "type": "null"
            }
          ]
        },
        "timezone": {
          "type": "string",
          "description": "IANA time zone used to interpret the weekly availability, for example Europe/Oslo."
        },
        "availability": {
          "type": "object",
          "properties": {
            "mon": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Monday availability intervals in the booking link's timezone."
            },
            "tue": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Tuesday availability intervals in the booking link's timezone."
            },
            "wed": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Wednesday availability intervals in the booking link's timezone."
            },
            "thu": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Thursday availability intervals in the booking link's timezone."
            },
            "fri": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Friday availability intervals in the booking link's timezone."
            },
            "sat": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Saturday availability intervals in the booking link's timezone."
            },
            "sun": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Start of the interval."
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "End of the interval; must be later than its start."
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              "maxItems": 6,
              "description": "Sunday availability intervals in the booking link's timezone."
            }
          },
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#",
          "title": "WeeklyAvailability",
          "description": "Bookable local-time intervals by weekday. Missing or empty days are unavailable."
        },
        "window_days": {
          "type": "integer",
          "description": "How many days into the future invitees can book."
        },
        "min_notice_minutes": {
          "type": "integer",
          "description": "Minimum time before a meeting can start, in minutes."
        },
        "buffer_before_minutes": {
          "type": "integer",
          "description": "Minutes reserved before each meeting."
        },
        "buffer_after_minutes": {
          "type": "integer",
          "description": "Minutes reserved after each meeting."
        },
        "max_per_day": {
          "type": "integer",
          "description": "Maximum bookings per day. Zero means no daily limit."
        },
        "questions": {
          "description": "Additional questions shown to invitees. Null means no questions.",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40,
                    "description": "Stable question key you choose, unique within this link, such as project_goal. Reuse it when editing that question; no create-record call is needed."
                  },
                  "label": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Text shown for this booking question or choice."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "text",
                      "textarea",
                      "select",
                      "checkbox"
                    ],
                    "description": "Question control: text is a short answer, textarea a longer answer, select a choice from options, and checkbox a yes/no response."
                  },
                  "required": {
                    "type": "boolean",
                    "description": "Whether the invitee must answer this booking question."
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120
                    },
                    "minItems": 1,
                    "maxItems": 12,
                    "description": "Choices for a select question; at least one is required when kind=select. Omit for other controls."
                  }
                },
                "required": [
                  "id",
                  "label",
                  "kind"
                ],
                "additionalProperties": false
              },
              "maxItems": 5,
              "$schema": "http://json-schema.org/draft-07/schema#",
              "description": "Additional questions shown to invitees. Null means no questions."
            },
            {
              "type": "null"
            }
          ]
        },
        "reminder_hours": {
          "type": "integer",
          "description": "Hours before the meeting to send a reminder. Zero disables reminders."
        },
        "collect_phone": {
          "type": "boolean",
          "description": "Whether invitees are asked for a phone number."
        },
        "active": {
          "type": "boolean",
          "description": "Whether invitees can make new bookings through this link."
        },
        "created_at": {
          "type": "integer",
          "description": "Creation time in Unix milliseconds."
        },
        "updated_at": {
          "type": "integer",
          "description": "Last change in Unix milliseconds."
        },
        "url": {
          "type": "string",
          "description": "Public booking URL to share with invitees.",
          "format": "uri"
        }
      },
      "required": [
        "id",
        "org_id",
        "owner_account_id",
        "slug",
        "name",
        "description",
        "duration_minutes",
        "duration_options",
        "location_kind",
        "location_detail",
        "timezone",
        "availability",
        "window_days",
        "min_notice_minutes",
        "buffer_before_minutes",
        "buffer_after_minutes",
        "max_per_day",
        "questions",
        "reminder_hours",
        "collect_phone",
        "active",
        "created_at",
        "updated_at",
        "url"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "link"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "link": {
        "id": "bkl_example",
        "org_id": "o_example",
        "owner_account_id": "a_example",
        "slug": "project-introduction",
        "name": "Project introduction",
        "description": null,
        "duration_minutes": 30,
        "duration_options": null,
        "location_kind": "video",
        "location_detail": null,
        "timezone": "Europe/Oslo",
        "availability": {
          "mon": [
            {
              "start": "09:00",
              "end": "17:00"
            }
          ]
        },
        "window_days": 30,
        "min_notice_minutes": 240,
        "buffer_before_minutes": 0,
        "buffer_after_minutes": 0,
        "max_per_day": 0,
        "questions": null,
        "reminder_hours": 24,
        "collect_phone": false,
        "active": false,
        "created_at": 1794301200000,
        "updated_at": 1794301200000,
        "url": "https://example.com/book/project-introduction"
      }
    }
  ]
}
```

