{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/api-evangelist/hummingdeck/main/json-schema/hummingdeck-create-room-request-schema.json",
  "title": "CreateRoomRequest",
  "x-generated": "2026-10-24",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/hummingdeck-openapi.json#/components/schemas/CreateRoomRequest",
  "type": "object",
  "properties": {
    "labelIds": {
      "type": "array",
      "maxItems": 5,
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Workspace labels to apply, from GET /room-labels."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    },
    "welcomeMessage": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 2000
    },
    "companyId": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid",
      "description": "Existing company. Mutually exclusive with companyName."
    },
    "companyName": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Company to find by name, ignoring case, or create."
    },
    "companyDomain": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 255,
      "description": "Stored on a new company, or on a matched one that has no domain yet. Requires companyName."
    },
    "contactId": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid",
      "description": "Existing contact in the workspace."
    },
    "recipientName": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255
    },
    "recipientEmail": {
      "type": [
        "string",
        "null"
      ],
      "format": "email",
      "maxLength": 255,
      "description": "Finds the contact with this email or creates one."
    },
    "documentIds": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string"
      },
      "description": "Documents from your library, added in this order to the first tab. Documents still processing are accepted."
    },
    "tabLabels": {
      "type": "object",
      "properties": {
        "documents": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "default": "Documents"
        },
        "nextSteps": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "default": "Next Steps"
        }
      },
      "additionalProperties": false,
      "description": "Labels for the two default tabs. The API has no locale, so the defaults are English."
    },
    "sender": {
      "$ref": "#/$defs/RoomSenderRequest"
    },
    "primaryLink": {
      "$ref": "#/$defs/PrimaryLinkRequest"
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false,
  "$defs": {
    "AllowedEmail": {
      "description": "An address, or an address with the person's name.",
      "oneOf": [
        {
          "type": "string",
          "format": "email",
          "maxLength": 255
        },
        {
          "type": "object",
          "properties": {
            "email": {
              "type": "string",
              "format": "email",
              "maxLength": 255
            },
            "name": {
              "type": [
                "string",
                "null"
              ],
              "maxLength": 255
            }
          },
          "required": [
            "email"
          ],
          "additionalProperties": false
        }
      ]
    },
    "PrimaryLinkRequest": {
      "type": "object",
      "description": "Settings for the room's first audience link. Options that apply to one access mode only are refused with the others.",
      "properties": {
        "accessMode": {
          "type": "string",
          "enum": [
            "open",
            "verify-any",
            "verified-allowlist"
          ],
          "default": "open",
          "description": "open: anyone with the URL. verify-any: visitors confirm their email address with a one-time link before entering. verified-allowlist (Restricted): only allowedEmails and allowedDomains can enter, each confirming their address with a one-time link. verify-any and verified-allowlist need Pro or Business."
        },
        "requireEmail": {
          "type": "boolean",
          "description": "open links only: ask visitors for their email before they enter (Pro and Business)."
        },
        "allowedEmails": {
          "type": "array",
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/AllowedEmail"
          },
          "description": "verified-allowlist only. Each address becomes a contact. The API adds nobody on its own: include your own address if you want to preview the room."
        },
        "allowedDomains": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 253
          },
          "description": "verified-allowlist only. Anyone with an address at one of these domains can enter. \"@acme.com\", \"acme.com\", and \"https://acme.com\" all mean acme.com. Free email providers such as gmail.com are refused."
        },
        "label": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 100,
          "description": "verified-allowlist only. Your internal name for the link."
        },
        "expiresAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the link stops working. Must be in the future (Starter and above)."
        },
        "allowDownloads": {
          "type": "boolean",
          "description": "Whether viewers can download the room's documents; also the room's default for later links. Omitted, downloads are off on plans with download control (Starter and above) and on otherwise. false on a plan without download control is refused."
        },
        "notifyOnView": {
          "type": "boolean",
          "default": true
        },
        "notifySlack": {
          "type": "boolean",
          "default": true
        }
      },
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "required": [
              "requireEmail"
            ],
            "properties": {
              "requireEmail": {
                "const": true
              }
            }
          },
          "then": {
            "properties": {
              "accessMode": {
                "const": "open"
              }
            }
          }
        },
        {
          "if": {
            "anyOf": [
              {
                "required": [
                  "allowedEmails"
                ],
                "properties": {
                  "allowedEmails": {
                    "minItems": 1
                  }
                }
              },
              {
                "required": [
                  "allowedDomains"
                ],
                "properties": {
                  "allowedDomains": {
                    "minItems": 1
                  }
                }
              }
            ]
          },
          "then": {
            "required": [
              "accessMode"
            ],
            "properties": {
              "accessMode": {
                "const": "verified-allowlist"
              }
            }
          }
        },
        {
          "if": {
            "required": [
              "label"
            ],
            "properties": {
              "label": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          "then": {
            "required": [
              "accessMode"
            ],
            "properties": {
              "accessMode": {
                "const": "verified-allowlist"
              }
            }
          }
        },
        {
          "if": {
            "required": [
              "accessMode"
            ],
            "properties": {
              "accessMode": {
                "const": "verified-allowlist"
              }
            }
          },
          "then": {
            "anyOf": [
              {
                "required": [
                  "allowedEmails"
                ],
                "properties": {
                  "allowedEmails": {
                    "minItems": 1
                  }
                }
              },
              {
                "required": [
                  "allowedDomains"
                ],
                "properties": {
                  "allowedDomains": {
                    "minItems": 1
                  }
                }
              }
            ]
          }
        }
      ]
    },
    "RoomSenderRequest": {
      "type": "object",
      "description": "The point of contact shown in the room. null or an empty string clears a field.",
      "properties": {
        "name": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "title": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "email": {
          "type": [
            "string",
            "null"
          ],
          "format": "email",
          "maxLength": 255
        }
      },
      "additionalProperties": false,
      "minProperties": 1
    }
  }
}