---
title: "Create a meeting"
method: POST
path: "/api/v1/meetings"
tags: ["Meetings"]
---

# Create a meeting

`POST /api/v1/meetings`

## Request

- Base URL: `https://api.recruitwithatlas.com`
- URL: `https://api.recruitwithatlas.com/api/v1/meetings`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/recruitwithatlas/apis/atlas-api/docs/api/v1/meetings/post.ts> (a function with typed inputs; its response is checked against the schema)

Logs, imports or schedules a general meeting, through the same service the Atlas app uses. Returns the created meeting in the same shape as `GET /api/v1/meetings/{meetingId}`.

**Logging or importing a past meeting:** send `skipCalendarEvent: true` with past `startAt` / `endAt`. There is no separate backdating flag: a meeting whose `endAt` is already in the past is stored as `completed`; one that ends in the future is `scheduled`.

**Scheduling:** send `skipCalendarEvent: false` and `senderEmail`; the calendar event is created from that user’s connected calendar. If that calendar cannot be reached the meeting is still created, without a calendar event — except when its authorisation has expired, which returns `401` and creates nothing.

The user that owns the API key (or `senderEmail`, when given) is the organizer and is always added as an attendee; that user needs a connected mailbox in Atlas. Only general meetings can be created here — candidate interviews are not supported.

## Request body

- object
  - `name` string, required: Meeting title
  - `startAt` string, date-time, required: Start time, ISO 8601 with `Z` or an explicit offset
  - `endAt` string, date-time, required: End time, ISO 8601 with `Z` or an explicit offset. A meeting whose end is already in the past is stored as `completed`, so send past times to log or import a meeting that already happened.
  - `timeZone` string, required: IANA time zone the meeting is held in, used for the calendar event
  - `communicationMethod` 'video_call' | 'phone_call' | 'in_person', required: How the meeting is held
  - `attendees` object[], required: People and users in the meeting (1-50). The user that owns the API key is always added.
    - `id` string, uuid: Atlas person ID (or user ID when `isUser` is true) of this attendee. Without it every person holding `email` is linked, Gmail aliases included. Must belong to your agency.
    - `email` string, email, required: Attendee email address
    - `isUser` boolean, required: `true` when the attendee is a user of your agency, `false` for a person (candidate or contact).
    - `optional` boolean: Invite the attendee as optional on the calendar event. Only used when `skipCalendarEvent` is false.
    - `calendarOnly` boolean: Invite the attendee on the calendar event only, without linking them to the meeting record. Only used when `skipCalendarEvent` is false.
  - `skipCalendarEvent` boolean, required: `true` logs the meeting in Atlas only. `false` also creates a calendar event, sent from `senderEmail`’s connected calendar.
  - `senderEmail` string, email: Email of the active agency user whose calendar sends the invite. Required when `skipCalendarEvent` is false; not accepted otherwise.
  - `description` string, nullable: Meeting description, also used as the calendar event body
  - `location` string, nullable: Meeting location
  - `projectId` string, uuid, nullable: Project the meeting relates to. Must belong to your agency.
  - `isPrivate` boolean: Mark the meeting private. Defaults to `false`.
  - `hideAttendees` boolean: Hide the attendee list on the calendar event. Defaults to `true`.
  - `inviteAINotetaker` boolean: Invite the AI notetaker to record the meeting. Requires `skipCalendarEvent: false`. Defaults to `false`.
  - `peopleNotes` string, nullable: Plain-text notes about the meeting (the manual note)
  - `candidateEvent` object, nullable: A separate calendar invite for the candidate, with its own title and body, so they do not see the main event or its attendees. Requires `skipCalendarEvent: false`.
    - `enabled` boolean, required: Send the separate invite. Requires `skipCalendarEvent: false`.
    - `eventTitle` string, nullable: Title of the invite. Defaults to the meeting `name`.
    - `description` string, nullable: Body of the invite
    - `inviteeEmail` string, email: Address the invite is sent to. Required when `enabled` is true. A person in your agency with this email is linked to the meeting.
    - `inviteeName` string, nullable: Name of the invitee

## Response `201`

Meeting created

- object
  - `status` 'ok', required
  - `data` object, required
    - `id` string, uuid, required
    - `name` string, nullable, required
    - `description` string, nullable, required
    - `location` string, nullable, required
    - `meetingUrl` string, nullable, required
    - `method` 'video_call' | 'phone_call' | 'in_person' | 'null', nullable, required: Communication method. Null when the meeting has no linked interview record.
    - `status` 'draft' | 'created' | 'scheduled' | 'coming' | 'waiting_to_join' | 'live' | 'completed' | 'transcribed' | 'failed' | 'canceled' | 'no_answer' | 'scheduling', required: Meeting status (meeting.status)
    - `direction` 'inbound' | 'outbound' | 'null', nullable, required: Call direction (`inbound`/`outbound`). Only populated for VoIP-sourced phone calls (e.g. RingOver, RingCentral); null for video meetings and manually logged calls.
    - `startAt` string, nullable, required: UTC ISO 8601 start time
    - `endAt` string, nullable, required: UTC ISO 8601 end time
    - `createdAt` string, nullable, required
    - `updatedAt` string, nullable, required: Effective last-updated timestamp: the later of the meeting row and its linked interview record — the same value the list endpoint reports.
    - `organizer` object, nullable, required: Meeting organizer — resolved the same way as the list shape: an Atlas user when the organizer email matches one of the meeting users, otherwise an `external` attendee with `id` null. Null when no organizer was recorded. The organizer may or may not also appear in `participants` — do not assume dedup.
      - `id` string, uuid, nullable, required: Atlas user ID when `type=user`; null when `type=external` (organizer not present in Atlas).
      - `name` string, required
      - `email` string, nullable, required
      - `type` 'user' | 'external', required
      - `relationship` 'user' | 'external', required: Same as `type`: `user` for an Atlas user, `external` for an organizer not present in Atlas.
    - `participants` object[], required: Flat list of users and people invited to the meeting. Filter by `type` to separate them.
      - `id` string, uuid, required: Atlas user or person ID
      - `name` string, required
      - `email` string, nullable, required
      - `type` 'user' | 'person', required
      - `relationship` 'user' | 'candidate' | 'company_contact' | 'person', required: How the participant relates to the interview: `user` (an Atlas user), `candidate` (the interview candidate), `company_contact` (a person who is an active contact of a company), or `person` (any other person).
    - `project` object, nullable, required: Project linked to the meeting. Null when no project is associated.
      - `id` string, uuid, required
      - `role` string, required: Job role (project.jobRole)
      - `companyName` string, nullable, required: Name of the project's company, null when none is set
    - `company` object, nullable, required: Company linked to the meeting. Resolved from the linked project's company when present, otherwise from the direct company link. Null when neither is set.
      - `id` string, uuid, required
      - `name` string, required
    - `customAttributes` object[], required
      - `attributeId` string, uuid, required: Custom attribute definition ID
      - `attributeName` string, nullable, required: Attribute name
      - `attributeType` 'options' | 'text_block' | 'text_line' | 'number_input' | 'integer' | 'date' | 'null', nullable, required: Attribute type — drives the shape of each entry in `values`.
      - `values` union[], required: All values recorded for this attribute. For single-value attributes the array has one entry; for multi-select `options` attributes it may have several.
        - union: A single value entry. Shape depends on `attributeType`: - `text_line` / `text_block` → string - `integer` / `number_input` → number - `date` → ISO `YYYY-MM-DD` string - `options` → `{ optionId, optionValue }` object
          - string
          - number
          - object
            - `optionId` string, uuid, required: Selected option ID
            - `optionValue` string, nullable, required: Display value of the option

## Other responses

- `401`: Missing or invalid API key, or (when scheduling) the sender’s calendar authorisation has expired and must be reconnected in Atlas
- `404`: `senderEmail` is not an active user of your agency, or `projectId` is not in your agency
- `415`: The request body is not sent as `application/json`
- `422`: The body failed validation, an attendee `id` is not in your agency, or the organizer has no connected mailbox in Atlas
- `429`: Too many requests - the caller has exceeded the per-agency rate limit for the tier this endpoint counts against (default per minute: 1200 read / 400 write / 60 upload). Inspect the `RateLimit-*` headers — returned on every response, not only on 429s — and back off until the window resets. See the "Rate limits" section of the introduction for details.

## Changes

- **2026-11-03** `158ee454751c`: 3 warning
  - added the new `undefined` enum value to the `data/customAttributes/items/attributeType` response property for the response status `201`
  - added the new `undefined` enum value to the `data/direction` response property for the response status `201`
  - added the new `undefined` enum value to the `data/method` response property for the response status `201`
- **2026-10-16** `2c0c6a89d8e7`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/recruitwithatlas/apis/atlas-api/changes/api/v1/meetings/post.md)

---

[API](https://skmtc.dev/recruitwithatlas/apis/atlas-api.md) - [All operations](https://skmtc.dev/recruitwithatlas/apis/atlas-api/llms.txt) - [OpenAPI document](https://skmtc.dev/recruitwithatlas/apis/atlas-api/revisions/158ee454751c?raw)
