# Criar reunião

`POST /api/v1/calendar/events`

Cria uma reunião no calendário nativo com o membro da chave como proprietário. O proprietário nunca vem do corpo da requisição.
`createConference` solicita um link do Google Meet e implica `syncToGoogle`. Ambas as opções exigem conexão Google com permissão de escrita. Se o Google falhar, a criação inteira falha. `recordWithBot` exige um link de conferência criado nesta chamada ou informado em `conferenceUrl`; o bot participa apenas do Google Meet ou Microsoft Teams.

## Autenticação

Envie a chave em `Authorization: Bearer pf_live_…`.

## Corpo da requisição

Content-Type: `application/json`

```json
{
  "summary": "Apresentação da proposta",
  "start": {
    "dateTime": "2026-10-06T14:00:00-03:00",
    "timeZone": "America/Sao_Paulo"
  },
  "end": {
    "dateTime": "2026-10-06T14:30:00-03:00",
    "timeZone": "America/Sao_Paulo"
  },
  "allDay": false
}
```

### Campos

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `summary` | `string` | Sim | Até 255 caracteres. |
| `description` | `string` | Não | Aceita null. |
| `location` | `string` | Não | Aceita null. Até 500 caracteres. |
| `start` | `EventDateTime` | Sim | Mesmo formato do Google Calendar: `date` para dia inteiro ou `dateTime` para instante ISO 8601. Nunca envie ambos. |
| `start.date` | `string` | Não | Data no formato YYYY-MM-DD para eventos de dia inteiro. Formato: date. Aceita null. |
| `start.dateTime` | `string` | Não | Formato: date-time. Aceita null. |
| `start.timeZone` | `string` | Não | Fuso IANA. Padrão: fuso do workspace. Aceita null. |
| `end` | `EventDateTime` | Sim | Mesmo formato do Google Calendar: `date` para dia inteiro ou `dateTime` para instante ISO 8601. Nunca envie ambos. |
| `end.date` | `string` | Não | Data no formato YYYY-MM-DD para eventos de dia inteiro. Formato: date. Aceita null. |
| `end.dateTime` | `string` | Não | Formato: date-time. Aceita null. |
| `end.timeZone` | `string` | Não | Fuso IANA. Padrão: fuso do workspace. Aceita null. |
| `allDay` | `boolean` | Não | Aceita null. |
| `status` | `string` | Não | confirmed (padrão), tentative, cancelled. Aceita null. |
| `attendees` | `array` | Não | Cada entrada usa { type: member, memberId } ou { type: contact, contactId }. Identificador desconhecido resulta em `400`. Aceita null. |
| `attendees[].type` | `string` | Não | Valores: member, contact. |
| `attendees[].memberId` | `string` | Não | Aceita null. |
| `attendees[].contactId` | `string` | Não | Aceita null. |
| `attendees[].responseStatus` | `string` | Não | Valores: needs_action, accepted, declined, tentative. |
| `attendees[].organizer` | `boolean` | Não |  |
| `attendees[].optional` | `boolean` | Não |  |
| `extendedProperties` | `object` | Não | Aceita null. |
| `syncToGoogle` | `boolean` | Não | Sincroniza a reunião no Google Calendar do proprietário. Exige conexão com permissão de escrita. Aceita null. |
| `createConference` | `boolean` | Não | Solicita um link do Google Meet. Implica syncToGoogle. Aceita null. |
| `recordWithBot` | `boolean` | Não | Solicita gravação pelo bot. Requer link de Google Meet ou Microsoft Teams; caso contrário, retorna 400. Aceita null. |
| `conferenceUrl` | `string` | Não | Link de reunião existente, quando não estiver criando uma conferência. Para gravação pelo bot, use Google Meet ou Microsoft Teams. Aceita null. Até 1000 caracteres. |

## Respostas

### 201

Criado

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `data` | `CalendarEvent` | Não | Formato único do calendário, utilizado por todos os itens, independentemente da fonte. |
| `data.id` | `string` | Não | provider:kind:id, por exemplo, native:meeting:5f2c… |
| `data.provider` | `string` | Não | Valores: native, google. |
| `data.kind` | `string` | Não | Valores: meeting, task, cadence_task. |
| `data.readOnly` | `boolean` | Não | Não pode ser alterado por esta API; somente reuniões nativas permitem escrita. |
| `data.status` | `string` | Não | confirmed, tentative, cancelled. |
| `data.summary` | `string` | Não |  |
| `data.description` | `string` | Não | Aceita null. |
| `data.location` | `string` | Não | Aceita null. |
| `data.start` | `EventDateTime` | Não | Mesmo formato do Google Calendar: `date` para dia inteiro ou `dateTime` para instante ISO 8601. Nunca envie ambos. |
| `data.start.date` | `string` | Não | Data no formato YYYY-MM-DD para eventos de dia inteiro. Formato: date. Aceita null. |
| `data.start.dateTime` | `string` | Não | Formato: date-time. Aceita null. |
| `data.start.timeZone` | `string` | Não | Fuso IANA. Padrão: fuso do workspace. Aceita null. |
| `data.end` | `EventDateTime` | Não | Mesmo formato do Google Calendar: `date` para dia inteiro ou `dateTime` para instante ISO 8601. Nunca envie ambos. |
| `data.end.date` | `string` | Não | Data no formato YYYY-MM-DD para eventos de dia inteiro. Formato: date. Aceita null. |
| `data.end.dateTime` | `string` | Não | Formato: date-time. Aceita null. |
| `data.end.timeZone` | `string` | Não | Fuso IANA. Padrão: fuso do workspace. Aceita null. |
| `data.attendees` | `array` | Não |  |
| `data.attendees[].type` | `string` | Não | Valores: member, contact. |
| `data.attendees[].member` | `object` | Não | Aceita null. |
| `data.attendees[].member.id` | `string` | Não |  |
| `data.attendees[].member.userId` | `string` | Não |  |
| `data.attendees[].member.name` | `string` | Não |  |
| `data.attendees[].member.email` | `string` | Não |  |
| `data.attendees[].member.image` | `string` | Não | Aceita null. |
| `data.attendees[].member.role` | `string` | Não |  |
| `data.attendees[].contact` | `object` | Não | Aceita null. |
| `data.attendees[].contact.id` | `string` | Não |  |
| `data.attendees[].contact.displayName` | `string` | Não |  |
| `data.attendees[].contact.email` | `string` | Não | Aceita null. |
| `data.attendees[].contact.phone` | `string` | Não | Aceita null. |
| `data.attendees[].removed` | `boolean` | Não | A identidade não existe mais; o convidado continua no histórico. |
| `data.attendees[].responseStatus` | `string` | Não | Valores: needs_action, accepted, declined, tentative. |
| `data.attendees[].organizer` | `boolean` | Não |  |
| `data.attendees[].optional` | `boolean` | Não |  |
| `data.owner` | `object` | Não | Nulo quando o membro proprietário saiu do workspace. Aceita null. |
| `data.owner.userId` | `string` | Não |  |
| `data.owner.name` | `string` | Não |  |
| `data.owner.email` | `string` | Não |  |
| `data.owner.image` | `string` | Não | Aceita null. |
| `data.owner.role` | `string` | Não | Papel do membro no workspace, por exemplo owner. |
| `data.owner.id` | `string` | Não | ID do vínculo de membro no workspace. userId identifica o usuário. |
| `data.extendedProperties` | `object` | Não | Aceita null. |
| `data.conferenceUrl` | `string` | Não | Link da reunião, independentemente de sua origem. Aceita null. |
| `data.botEnabled` | `boolean` | Não | O bot de gravação está configurado para esta reunião. |
| `data.botStatus` | `string` | Não | Último estado informado pelo bot. Aceita null. |
| `data.created` | `string` | Não | Formato: date-time. Aceita null. |
| `data.updated` | `string` | Não | Formato: date-time. Aceita null. |
| `message` | `string` | Não | Aceita null. |

```json
{
  "type": "object",
  "properties": {
    "data": {
      "$ref": "#/components/schemas/CalendarEvent"
    },
    "message": {
      "type": "string",
      "nullable": true
    }
  }
}
```

### 400

Falha de validação dos campos; `fieldErrors` contém os erros.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 401

Chave ausente, malformada, desconhecida, revogada ou expirada, ou membro emissor inativo.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 403

Autenticado, mas sem acesso: falta de permissão (`FORBIDDEN`), recurso desligado no workspace (`FEATURE_DISABLED`) ou tentativa de acessar uma agenda não permitida.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 429

Limite de requisições excedido por workspace ou IP.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```
