The Meeting object
Property | Description | Editable? |
id | Vitally's unique ID for the Meeting |
|
externalId | Your unique ID for the Meeting |
|
title | The title of the Meeting |
|
description | The description or body of the Meeting |
|
location | The location of the Meeting |
|
startDate | Date-only start value for the Meeting (when time is not applicable) |
|
startDateTime | ISO 8601 datetime for when the Meeting starts |
|
startTimeZone | Timezone for the Meeting's start time (e.g. |
|
endDate | Date-only end value for the Meeting (when time is not applicable) |
|
endDateTime | ISO 8601 datetime for when the Meeting ends |
|
endTimeZone | Timezone for the Meeting's end time (e.g. |
|
externalStatus | Status of the Meeting as reported by the external source (e.g. |
|
recordingUrl | URL to the Meeting recording |
|
recordingUrlFormatted | Formatted version of the recording URL, if available |
|
joiningInstructionsUri | URI for joining the Meeting (e.g. a dial-in page link) |
|
videoConferenceUri | Direct video conference link for the Meeting |
|
phoneConferenceNumbers | Array of phone conference dial-in numbers for the Meeting |
|
conferenceSolution | The conferencing platform used (e.g. Zoom, Google Meet) |
|
summary | A summary of the Meeting |
|
keyPoints | An array of key point strings from the Meeting |
|
riskAssessment | A risk assessment string associated with the Meeting |
|
source | Name of the integration that created the Meeting (e.g. |
|
participants | An array of Meeting Participant objects. At least one must be a |
|
accounts | Array of Vitally Account objects associated with the Meeting, resolved from participants |
|
organizations | Array of Vitally Organization objects associated with the Meeting, resolved from participants |
|
notes | Array of Note objects linked to the Meeting |
|
tasks | Array of Task objects linked to the Meeting |
|
traits | A key-value JSON object of custom Meeting traits |
|
archivedAt | Datetime the Meeting was archived |
|
The Meeting Participant object
Each participant in the participants array includes the following fields in responses:
Property | Description | Editable? |
id | Vitally's unique ID for the participant record |
|
The participant's email address |
| |
type | The participant's role: |
|
responseStatus | The participant's response: |
|
vitallyUser | If the participant is a Vitally admin/teammate, their resolved |
|
user | If the participant is a customer User in Vitally, their resolved User object including |
|
When creating or adding a participant, each participant object in the request requires the following fields.
For each participant, provide exactly one of the following to identify them:
Field | Type | Description |
userId |
| The customer User's |
vitallyUserId |
| Vitally's internal ID for a Vitally admin/teammate |
| Email address of an external attendee not in Vitally |
Each participant also requires the following:
Field | Type | Description |
type |
| Required. The participant's role: |
responseStatus |
| (optional) |
isOrganizer |
| (optional) Defaults to |
The Meeting Transcript object
Property | Description | Editable? |
id | Vitally's unique ID for the Transcript |
|
meetingId | The ID of the Meeting this Transcript belongs to |
|
transcript | An array of monologue objects. Each monologue contains a
The |
|
createdAt | Datetime the Transcript was created |
|
updatedAt | Datetime the Transcript was last updated |
|
Replace {subdomain} in the endpoints below with your Vitally subdomain.
You can find your subdomain in the URL used to log into Vitally (i.e., https://yoursubdomain.vitally.io)
List Meetings GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings
Paginated list of Meetings for the authenticated owner, by default ordered by updatedAt descending. Can also be scoped to an Account or Organization using the nested routes below.
Query Params (see Pagination)
Param | Type | Description |
limit |
| (optional) The number of items to return. Max is 100. |
from |
| (optional) The cursor returned from a previous request |
archived |
| (optional) If |
sortBy |
| (optional) Field to sort results by |
Example Requests
GET https://{subdomain}.rest.vitally.io/resources/meetings?limit=10&from=cursorGET https://{subdomain}.rest.vitally.io/resources/meetings?archived=true
Example Response
{
"results": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"externalId": "meeting-1",
"title": "Q1 Business Review",
"description": "Quarterly review of goals and KPIs.",
"startDate": null,
"startDateTime": "2026-01-10T17:00:00.000Z",
"startTimeZone": "utc",
"endDate": null,
"endDateTime": "2026-01-10T18:00:00.000Z",
"endTimeZone": "utc",
"externalStatus": null,
"location": "Zoom",
"phoneConferenceNumbers": [],
"joiningInstructionsUri": null,
"videoConferenceUri": null,
"conferenceSolution": null,
"recordingUrlFormatted": null,
"riskAssessment": null,
"keyPoints": null,
"summary": null,
"participants": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"vitallyUser": {
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Bertram Gilfoyle",
"email": "gilfoyle@your-org.vitally.io",
"licenseStatus": "active"
},
"user": null,
"email": "gilfoyle@your-org.vitally.io",
"responseStatus": "accepted",
"type": "organizer"
},
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"vitallyUser": null,
"user": {
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"createdAt": "2025-10-23T22:59:35.075Z",
"updatedAt": "2026-04-09T06:18:47.559Z",
"externalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Customer Name",
"email": "customer@example.com",
"avatar": null,
"traits": {},
"firstKnown": "2025-07-24T22:56:07.716Z",
"lastSeenTimestamp": null,
"lastInboundMessageTimestamp": null,
"lastOutboundMessageTimestamp": null,
"npsLastScore": null,
"npsLastFeedback": null,
"npsLastRespondedAt": null,
"unsubscribedFromConversations": false,
"unsubscribedFromConversationsAt": null,
"deactivatedAt": null,
"joinDate": "2025-07-24T22:56:07.716Z"
},
"email": "customer@example.com",
"responseStatus": "accepted",
"type": "attendee"
}
],
"accounts": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Example Account",
...
}
],
"organizations": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Example Organization",
...
}
],
"notes": [],
"tasks": [],
"traits": {}
}
],
"next": "...xZDExYmEifQ=="
}
List Meetings For An Account GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/accounts/:accountId/meetings
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/accounts/:accountId/meetings
Paginated list of Meetings for a given Account, ordered by updatedAt descending.
Request Params
Property | Type | Description |
accountId |
| The Account ID assigned by Vitally |
Example Request
GET https://{subdomain}.rest.vitally.io/resources/accounts/:accountId/meetings?limit=10&from=cursor
List Meetings For An Organization GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/organizations/:organizationId/meetings
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/organizations/:organizationId/meetings
Paginated list of Meetings for a given Organization, ordered by updatedAt descending.
Request Params
Property | Type | Description |
organizationId |
| The Organization ID assigned by Vitally |
Example Request
GET https://{subdomain}.rest.vitally.io/resources/organizations/:organizationId/meetings?limit=10&from=cursor
Create A Meeting POST
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings
Creates a new Meeting. If an externalId is provided and already exists, the Meeting is updated.
Request Body
Property | Type | Description |
title |
| Required The title of the Meeting |
participants |
| Required At least one participant required. At least one must be a |
externalId |
| Required Your unique ID for the Meeting. Used to check for existing Meetings. |
description |
| The description or body of the Meeting |
location |
| The location of the Meeting |
startDateTime |
| Start date and time of the Meeting |
endDateTime |
| End date and time of the Meeting |
recordingUrl |
| URL to the Meeting recording |
summary |
| A summary of the Meeting |
keyPoints |
| An array of key point strings from the Meeting |
riskAssessment |
| A risk assessment for the Meeting |
source |
| Integration source identifier (e.g. |
traits |
| Custom field values keyed by field path |
transcript |
| Optionally create the transcript in the same request. See transcript format for details. |
Errors
400— No participants, empty participants array, or no participant is a user linked to an account or organization.422— Schema validation failure (missingtitle, unknown field, etc.).
Example Request
POST https://{subdomain}.rest.vitally.io/resources/meetings
{
"title": "Q1 Business Review",
"externalId": "meeting-q1",
"description": "Quarterly review of goals and KPIs.",
"location": "Zoom",
"startDateTime": "2026-05-01T17:00:00.000Z",
"endDateTime": "2026-05-01T18:00:00.000Z",
"summary": "Discussed Q1 performance and roadmap priorities.",
"keyPoints": ["Onboarding complete", "Expansion opportunity identified"],
"riskAssessment": "Low",
"source": "gong",
"participants": [
{
"vitallyUserId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"type": "organizer"
},
{
"userId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"type": "attendee",
"responseStatus": "accepted"
}
],
"traits": {}
}
Example Response
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"externalId": "meeting-q1",
"title": "Q1 Business Review",
"description": "Quarterly review of goals and KPIs.",
"startDate": null,
"startDateTime": "2026-05-01T17:00:00.000Z",
"startTimeZone": "utc",
"endDate": null,
"endDateTime": "2026-05-01T18:00:00.000Z",
"endTimeZone": "utc",
"externalStatus": null,
"location": "Zoom",
"phoneConferenceNumbers": [],
"joiningInstructionsUri": null,
"videoConferenceUri": null,
"conferenceSolution": null,
"recordingUrlFormatted": null,
"riskAssessment": "Low",
"keyPoints": ["Onboarding complete", "Expansion opportunity identified"],
"summary": "Discussed Q1 performance and roadmap priorities.",
"source": "gong",
"participants": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"vitallyUser": {
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Bertram Gilfoyle",
"email": "gilfoyle@your-org.vitally.io",
"licenseStatus": "active"
},
"user": null,
"email": "gilfoyle@your-org.vitally.io",
"responseStatus": null,
"type": "organizer"
},
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"vitallyUser": null,
"user": {
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"createdAt": "2025-10-23T22:59:35.075Z",
"updatedAt": "2026-04-09T06:18:47.559Z",
"externalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Customer Name",
"email": "customer@example.com",
"avatar": null,
"traits": {},
"firstKnown": "2025-07-24T22:56:07.716Z",
"lastSeenTimestamp": null,
"lastInboundMessageTimestamp": null,
"lastOutboundMessageTimestamp": null,
"npsLastScore": null,
"npsLastFeedback": null,
"npsLastRespondedAt": null,
"unsubscribedFromConversations": false,
"unsubscribedFromConversationsAt": null,
"deactivatedAt": null,
"joinDate": "2025-07-24T22:56:07.716Z"
},
"email": "customer@example.com",
"responseStatus": "accepted",
"type": "attendee"
}
],
"accounts": [...],
"organizations": [...],
"notes": [],
"tasks": [],
"traits": {}
}
Get A Meeting GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id
Returns a single Meeting by Vitally id or externalId. Also returns archived meetings.
Request Params
Property | Type | Description |
id |
| The Meeting ID assigned by Vitally, or the Meeting's |
Example Requests
GET https://{subdomain}.rest.vitally.io/resources/meetings/:idGET https://{subdomain}.rest.vitally.io/resources/meetings/:externalId
Errors
404— Meeting not found. Double check the ID.
Update A Meeting PUT
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id
Updates an existing, non-archived Meeting. Accepts the Meeting's Vitally id or externalId. All body fields are optional.
Request Body (all fields optional)
Property | Type | Description |
title |
| The title of the Meeting |
description |
| The description or body of the Meeting |
location |
| The location of the Meeting |
startDateTime |
| Start date and time of the Meeting |
endDateTime |
| End date and time of the Meeting |
recordingUrl |
| URL to the Meeting recording |
summary |
| A summary of the Meeting |
keyPoints |
| An array of key point strings from the Meeting |
riskAssessment |
| A risk assessment for the Meeting |
traits |
| Custom field values keyed by field path |
Errors
400— Meeting is archived.404— Meeting not found. Double check the ID.
Example Request
PUT https://{subdomain}.rest.vitally.io/resources/meetings/:id
{
"summary": "Updated summary after follow-up.",
"riskAssessment": "Medium"
}
Delete A Meeting DELETE
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id
Deletes a Meeting. Accepts the Meeting's Vitally id or externalId.
Request Params
Property | Type | Description |
id |
| The Meeting ID assigned by Vitally, or the Meeting's |
Add A Participant POST
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id/participants
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id/participants
Adds a participant to an existing, non-deleted Meeting.
Request Body
Identifier (exactly one required)
Field | Type | Description |
userId |
| The customer User's |
vitallyUserId |
| Vitally's internal ID for a Vitally admin/teammate |
| Email address of an external attendee not in Vitally |
Additional fields
Field | Type | Description |
type |
| Required. The participant's role: |
responseStatus |
| (optional) |
isOrganizer |
| (optional) Defaults to |
Errors
400— Meeting is archived, multiple identifiers provided, no identifier provided, oruserId/vitallyUserIdnot found.404— Meeting not found. Double check the ID.
Example Request
POST https://{subdomain}.rest.vitally.io/resources/meetings/:id/participants
{
"email": "newattendee@example.com",
"type": "attendee",
"responseStatus": "accepted"
}
Remove A Participant DELETE
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id/participants/:participantId
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id/participants/:participantId
Removes a participant from a Meeting. The participantId can be retrieved from the id field of any participant object in the participants array returned by a Get A Meeting or Create A Meeting response.
Request Params
Property | Type | Description |
id |
| The Meeting ID assigned by Vitally |
participantId |
| The ID of the participant to remove |
Errors
400— Meeting is archived, or removing this participant would leave the meeting with no participant linked to an account or organization.404— Meeting not found, participant not found, or participant belongs to a different meeting. Double check the IDs.
List Transcripts GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetingTranscripts
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetingTranscripts
Paginated list of all Meeting Transcripts, ordered by updatedAt descending.
Query Params (see Pagination)
Param | Type | Description |
limit |
| (optional) The number of items to return. Max is 100. |
from |
| (optional) The cursor returned from a previous request |
sortBy |
| (optional) Field to sort results by |
Example Request
GET https://{subdomain}.rest.vitally.io/resources/meetingTranscripts?limit=10&from=cursor
Get A Transcript GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetingTranscripts/:id
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetingTranscripts/:id
Returns a single Transcript by its own ID. The id for a specific Transcript can be retrieved from the id field returned in the response from Create / Replace A Meeting's Transcript or List Transcripts. Note that this is the Transcript's own ID, it's not the Meeting's id.
Errors
400—idis not a valid UUID.404— Transcript not found.
Get A Meeting's Transcript GET
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id/transcript
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id/transcript
Returns the Transcript for a specific Meeting. Accepts the Meeting's Vitally id or externalId.
Errors
404— Meeting not found, or Meeting has no transcript. Double check the Meeting ID.
Example Request
GET https://{subdomain}.rest.vitally.io/resources/meetings/:id/transcript
Create / Replace A Meeting's Transcript POST
If the caller doesn't already know the Meeting id, use Find a Meeting and Update / Create Transcript POST instead.
US Data Center (default):
https://{subdomain}.rest.vitally.io/resources/meetings/:id/transcript
EU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/:id/transcript
Creates or replaces the Transcript for a Meeting. Accepts the Meeting's Vitally id or externalId.
Request Body
Property | Type | Description |
transcript |
| Required An array of monologue objects |
Each monologue in the transcript array should follow this format:
{
"speaker": {
"externalId": "string (required)",
"email": "string",
"name": "string"
},
"sentences": [
{
"text": "string",
"startTime": 0,
"endTime": 1000
}
]
}
Errors
400— Meeting is deleted, or body fails schema validation.404— Meeting not found. Double check the ID.
Example Request
POST https://{subdomain}.rest.vitally.io/resources/meetings/:id/transcript
{
"transcript": [
{
"speaker": {
"externalId": "speaker-001",
"email": "monica@example.com",
"name": "Monica Piper"
},
"sentences": [
{
"text": "Thanks for joining today's business review.",
"startTime": 0,
"endTime": 3200
},
{
"text": "Let's start with a look at your onboarding progress.",
"startTime": 3500,
"endTime": 7000
}
]
}
]
}
Example Response
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"meetingId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"createdAt": "2026-01-10T18:30:00.000Z",
"updatedAt": "2026-01-10T18:30:00.000Z",
"transcript": [
{
"speaker": {
"externalId": "speaker-001",
"email": "monica@example.com",
"name": "Monica Piper"
},
"sentences": [
{
"text": "Thanks for joining today's business review.",
"startTime": 0,
"endTime": 3200
},
{
"text": "Let's start with a look at your onboarding progress.",
"startTime": 3500,
"endTime": 7000
}
]
}
]
}
Find a Meeting POST
Read-only. Matches a recording or calendar hint to an existing Meeting and returns ranked candidates. Does not create a Meeting or write a transcript.
US Data Center:
https://{subdomain}.rest.vitally.io/resources/meetings/findEU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/find
Request Body (at least one match hint required)
Property | Type | Description |
calendarEventId | string | The meeting's unique ID in the calendar, sent exactly as the provider stores it. Google: the event id — for a recurring meeting, the occurrence id ( |
iCalUID | string | The calendar event UID per RFC 5545 §3.8.4.7. For a recurring invite every occurrence shares the same UID, so include |
recorderCallId | string, max 100 | The external recorder's call id. Finds a Meeting already linked to that recording. Not a calendar id. |
startDateTime | ISO-8601 | The Meeting's scheduled start, not the first spoken word. Required when |
endDateTime | ISO-8601 | The Meeting's scheduled end. |
title | string | Heuristic match when there's no calendar id. |
participantEmails | array of strings | Heuristic match when there's no calendar id. |
conferenceUrl | string | Heuristic match when there's no calendar id. |
timeWindowMinutes | integer, 1-60, default 15 | Window around |
Response
200—{ matches }. Each item hasmeeting,confidence(exact,high,medium,low), andmatchReasons. Empty array means no match. A valid request always returns200, including no match.400— No match hint sent, orstartDateTimeomitted when the calendar/recorder hints were also omitted.
Notes
Doesn't write anything — no Meeting creation, recording link, or transcript storage.
calendarEventIdmust match character-for-character what Vitally already has from calendar sync.Archived meetings are not matched.
Example Request
POST https://{subdomain}.rest.vitally.io/resources/meetings/find
{
"calendarEventId": "abc123_20260115T170000Z",
"startDateTime": "2026-01-15T17:00:00.000Z"
}Example Response
{
"matches": [
{ "meeting": { "id": "...", "title": "Q1 Business Review" }, "confidence": "exact", "matchReasons": ["calendarEventId"] }
]
}
Find a Meeting and Update / Create Transcript POST
Matches a Meeting, then creates or updates its REST API transcript. Can create the Meeting first when createIfNotFound is true and nothing matched. If the caller already knows the Meeting id, the existing Create / Replace A Meeting's Transcript endpoint above still works — use this one when the caller has match hints instead of an id, or wants Vitally to create the Meeting.
US Data Center:
https://{subdomain}.rest.vitally.io/resources/meetings/transcriptEU Data Center:
https://{subdomain}.rest.vitally-eu.io/resources/meetings/transcript
Request Body
Property | Type | Description |
transcript | array | Required. Same monologue shape as the existing transcript endpoint. Sentence |
calendarEventId / iCalUID | string | Same as in POST /resources/meetings/find. |
recorderCallId | string, max 100 | Used for idempotent retries. Send it on every upload, including a |
startDateTime | ISO-8601 | Required when |
endDateTime | ISO-8601 | The Meeting's scheduled end. |
title | string | Heuristic match when there's no calendar id. Optional when creating a Meeting (defaults to "Imported meeting"). |
participantEmails | array of strings | Heuristic match when there's no calendar id. Required in practice when |
conferenceUrl | string | Heuristic match when there's no calendar id. |
timeWindowMinutes | integer, 1-60, default 15 | Window around |
meetingId | string | Skips matching, uploads to this Meeting directly. Typical retry after a |
createIfNotFound | boolean | Creates a Meeting only when matching returns zero candidates — not on ambiguous or medium/low-confidence matches. |
Response
201— One exact/high match; Meeting or transcript created. Body:meeting,transcript,meetingCreated,transcriptCreated, optionallyconfidence/matchReasons.200— One exact/high match; transcript already existed and was replaced. Same body as201.409— More than one exact/high match, or only medium/low matches. Body:error,matches. Retry withmeetingIdset to one of the returned matches.404— No Meeting matched. Retry withcreateIfNotFound: trueonly if creating a Meeting is acceptable.400—createIfNotFoundtrue but no participant resolved to an external User,startDateTimemissing when required, or target Meeting archived.
Notes
Doesn't replace a Gong, calendar, or Vitally Recorder transcript — stored under the REST API integration. A repeat upload replaces only that REST API transcript. The UI prefers it when more than one transcript exists.
speaker.externalIdis a stable key within that transcript only — not a Vitally user, team member, or Meeting id. Speaker-to-participant linking usesspeaker.email, thenname.createIfNotFoundrequiresstartDateTimeand at least oneparticipantEmailsaddress that already exists as an external User. Owned-domain (internal) emails alone aren't enough.createIfNotFounddoes nothing on a409— resolve ambiguous/low-confidence matches withmeetingIdinstead.Archived meetings can't receive a transcript.
A Meeting created this way uses
recorderCallId(or a generated id) as its external id. Send a calendar event id too if you have one, so later uploads can match on that key.
Example Request
POST https://{subdomain}.rest.vitally.io/resources/meetings/transcript
{
"recorderCallId": "granola-note-abc123",
"startDateTime": "2026-01-15T17:00:00.000Z",
"participantEmails": ["customer@example.com"],
"transcript": [
{ "speaker": { "externalId": "speaker-001", "email": "monica@example.com", "name": "Monica Piper" },
"sentences": [{ "text": "Thanks for joining today's business review.", "startTime": 0, "endTime": 3200 }] }
]
}Example Response
{
"meeting": { "id": "...", "title": "Q1 Business Review" },
"transcript": { "id": "..." },
"meetingCreated": false,
"transcriptCreated": true,
"confidence": "exact",
"matchReasons": ["calendarEventId"]
}