The Speak AI API exposes 4 comments endpoints under the base URL https://api.speakai.co/v1. Every request needs the x-speakai-key and x-access-token headers described in Authentication.
Comment threads on a passage of a transcript or on the whole file, with one level of replies, resolve and reopen. Comments on passages follow their words when the transcript is edited, the same way labels do.
Permissions
Admins set these per person in Team management. Owners pass every check. Reading comments needs no permission, and you can always edit and delete your own comments.
| Permission | Allows | Admin default | Member default |
|---|---|---|---|
| Comments: Create | Start a thread and reply | Yes | Yes |
| Comments: Update | Resolve and reopen threads | Yes | Yes |
| Comments: Delete | Delete other people’s comments | Yes | No |
Notifications
Every comment change is listed for the person who made it under the comment category of GET /v1/notification. The person who started a thread is also told when someone else replies to it, resolves it or reopens it.
What can you do with the comments endpoints?
Speak AI groups these 4 endpoints under the comments resource. Each entry below links to the full reference for that endpoint further down this page.
List comment threads
/media/{mediaId}/commentsReturns the media’s comment threads, oldest first, with the media’s current transcriptRevision. Each thread is its first comment with a replies array. Anyone who can open the file can read its comments; no comments permission is needed. The media must belong to your company and be one you can open. Owners and members with the folder Access all permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.
A deleted first comment that still has replies stays in the list with an empty body and isDeleted: true, so the replies keep their context. Deleted replies are left out.
When a transcript is saved, labels and comments on passages are moved to the new text in the background, after the save has answered. Until that finishes, which is normally a moment, a list can return anchors whose anchor.transcriptRevision is lower than the top-level transcriptRevision. Fetch the list again shortly after a save.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
mediaId |
path | string | Yes | Id of the media file. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
filter |
query | string | No | all (the default), open or resolved threads, or file for comments on the whole file only. One of: all, open, resolved, file. |
curl -X GET 'https://api.speakai.co/v1/media/b4994aa1267c/comments?filter=open' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 Success
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | success on every 2xx response. One of: success . |
data |
object | The result. |
data.transcriptRevision |
integer | The media’s current transcript revision. |
data.threads |
object[] | Threads, oldest first. |
data.threads – 15 more fields
| Field | Type | Description |
|---|---|---|
commentId |
string | Id of the comment. |
mediaId |
string | Id of the media. |
anchor |
object | The passage the comment is on, or null for a comment on the whole file. Replies carry null. |
parentId |
string | commentId of the thread’s first comment for a reply, null for the first comment. |
body |
string | Comment text. Empty on a deleted first comment that still has replies. |
mediaLabelId |
string | Labelled passage the comment is linked to. Present only when one was linked. |
status |
string | Present only on comments with an anchor. active: the same words, possibly at new positions after an edit. shifted: most of the words survived an edit near the same time, but the text changed. needs_review: the words changed too much to follow; anchor then holds a suggested passage on the new transcript and lastResolved the last position a person confirmed. One of: active, shifted, needs_review . |
lastResolved |
object | Present only while status is needs_review: the last position a person confirmed. |
isResolved |
boolean | true once the thread is resolved. Only set on the first comment of a thread. |
resolvedBy |
string | Id of the person who resolved the thread. Present only while it is resolved. |
isDeleted |
boolean | true on a deleted first comment kept because it has replies. |
userId |
string | Id of the author. |
createdAt |
string (date-time) | When it was posted. |
updatedAt |
string (date-time) | When it last changed. |
replies |
object[] | Replies, oldest first, with the same fields. Deleted replies are left out. |
anchor – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
lastResolved – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
replies – 14 more fields
| Field | Type | Description |
|---|---|---|
commentId |
string | Id of the comment. |
mediaId |
string | Id of the media. |
anchor |
object | The passage the comment is on, or null for a comment on the whole file. Replies carry null. |
parentId |
string | commentId of the thread’s first comment for a reply, null for the first comment. |
body |
string | Comment text. Empty on a deleted first comment that still has replies. |
mediaLabelId |
string | Labelled passage the comment is linked to. Present only when one was linked. |
status |
string | Present only on comments with an anchor. active: the same words, possibly at new positions after an edit. shifted: most of the words survived an edit near the same time, but the text changed. needs_review: the words changed too much to follow; anchor then holds a suggested passage on the new transcript and lastResolved the last position a person confirmed. One of: active, shifted, needs_review . |
lastResolved |
object | Present only while status is needs_review: the last position a person confirmed. |
isResolved |
boolean | true once the thread is resolved. Only set on the first comment of a thread. |
resolvedBy |
string | Id of the person who resolved the thread. Present only while it is resolved. |
isDeleted |
boolean | true on a deleted first comment kept because it has replies. |
userId |
string | Id of the author. |
createdAt |
string (date-time) | When it was posted. |
updatedAt |
string (date-time) | When it last changed. |
anchor – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
lastResolved – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
Example response (Success), application/json.
{
"status": "success",
"data": {
"transcriptRevision": 3,
"threads": [
{
"commentId": "Cm8WpE3kLv6NdHa",
"mediaId": "b4994aa1267c",
"anchor": {
"startWord": 42,
"endWord": 49,
"exact": "we need the pricing sheet by Friday",
"prefix": "Before we close the quarter, ",
"suffix": ". Can you send it over?",
"startInSec": 61.4,
"endInSec": 64.2,
"speakerIds": [
"1"
],
"transcriptRevision": 3
},
"parentId": null,
"body": "Can we confirm this date with finance?",
"status": "active",
"isResolved": false,
"isDeleted": false,
"userId": "65f0c1a2b3c4d5e6f7a8b9c0",
"createdAt": "2026-10-06T14:05:12.000Z",
"updatedAt": "2026-10-06T14:05:12.000Z",
"replies": [
{
"commentId": "Cm2YsF9qJt4BxMr",
"mediaId": "b4994aa1267c",
"anchor": null,
"parentId": "Cm8WpE3kLv6NdHa",
"body": "Confirmed, Friday works.",
"isResolved": false,
"isDeleted": false,
"userId": "65f0c1a2b3c4d5e6f7a8b9c1",
"createdAt": "2026-10-06T15:20:40.000Z",
"updatedAt": "2026-10-06T15:20:40.000Z"
}
]
}
]
}
}400 A path or query value failed validation
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (A path or query value failed validation), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 400,
"message": "\"filter\" must be one of [all, open, resolved, file]",
"hints": [
"The API request is invalid or improperly formed."
]
}404 The media does not exist or you cannot open it
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The media does not exist or you cannot open it), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 404,
"message": "Media not found.",
"hints": [
"The requested operation failed because a resource associated with the request could not be found."
]
}Post a comment or reply
/media/{mediaId}/commentsRequires the Comments: Create permission (on by default for admins and members). The media must belong to your company and be one you can open. Owners and members with the folder Access all permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.
Three kinds of comment
- On a passage: send
rangeandexpectedTranscriptRevisiontogether.expectedTranscriptRevisionis thetranscriptRevisionyou read the transcript at, fromGET /media/transcript/{mediaId},GET /media/insight/{mediaId}, or the list endpoints on this page. The server builds the anchor from its own copy of the transcript. If the transcript has been saved since, the request returns 409 “This transcript changed since you opened it. Reload to keep editing.” and nothing is written: read the transcript again and recompute the word range. - On the whole file: leave out both
rangeandexpectedTranscriptRevision. - A reply: send
parentId, thecommentIdof a thread’s first comment. A reply cannot carryrangeormediaLabelId; it belongs to its thread. Replies go one level deep, so replying to a reply returns 400.
Add mediaLabelId to link a new thread to a labelled passage on the same media.
A reply sends an in-app notification to the person who started the thread, unless they wrote the reply. A transcript holds at most 5,000 comments on passages; whole-file comments and replies are not counted.
Errors
400when a field fails validation, the rules above are broken, the range runs past the transcript, or the limit is reached.403without the permission.404when the media, the parent comment or the labelled passage does not exist.409whenexpectedTranscriptRevisionis stale.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
mediaId |
path | string | Yes | Id of the media file. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
body |
string, required | Comment text. Trimmed, then 1 to 5,000 characters. |
range |
object | The passage to comment on. Send it with expectedTranscriptRevision; leave both out for a whole-file comment. Not allowed on a reply. Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from entities in order (an entity that holds several words, such as “New York”, counts as several), or from the sentence text split on whitespace when the sentence has no entities. A token that is only punctuation is not counted. |
range.start |
integer, required | Position of the first word. Integer, 0 or more. |
range.end |
integer, required | Position of the last word, inclusive. Integer, at least start. A range that runs past the last word returns 400 “The selected words are outside this transcript.” |
expectedTranscriptRevision |
integer | Required when you send range, not allowed without it. The transcriptRevision you read the transcript at. Integer, 0 or more. A stale value returns 409. |
parentId |
string | commentId of the thread’s first comment, to post a reply. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
mediaLabelId |
string | A labelled passage on this media to link the thread to. Not allowed on a reply. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
curl -X POST 'https://api.speakai.co/v1/media/b4994aa1267c/comments' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{
"body": "Can we confirm this date with finance?",
"range": {
"start": 42,
"end": 49
},
"expectedTranscriptRevision": 3
}'200 Success
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | success on every 2xx response. One of: success . |
data |
object | A comment. |
data – 14 more fields
| Field | Type | Description |
|---|---|---|
commentId |
string | Id of the comment. |
mediaId |
string | Id of the media. |
anchor |
object | The passage the comment is on, or null for a comment on the whole file. Replies carry null. |
parentId |
string | commentId of the thread’s first comment for a reply, null for the first comment. |
body |
string | Comment text. Empty on a deleted first comment that still has replies. |
mediaLabelId |
string | Labelled passage the comment is linked to. Present only when one was linked. |
status |
string | Present only on comments with an anchor. active: the same words, possibly at new positions after an edit. shifted: most of the words survived an edit near the same time, but the text changed. needs_review: the words changed too much to follow; anchor then holds a suggested passage on the new transcript and lastResolved the last position a person confirmed. One of: active, shifted, needs_review . |
lastResolved |
object | Present only while status is needs_review: the last position a person confirmed. |
isResolved |
boolean | true once the thread is resolved. Only set on the first comment of a thread. |
resolvedBy |
string | Id of the person who resolved the thread. Present only while it is resolved. |
isDeleted |
boolean | true on a deleted first comment kept because it has replies. |
userId |
string | Id of the author. |
createdAt |
string (date-time) | When it was posted. |
updatedAt |
string (date-time) | When it last changed. |
anchor – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
lastResolved – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
Example response (Success), application/json.
{
"status": "success",
"data": {
"commentId": "Cm8WpE3kLv6NdHa",
"mediaId": "b4994aa1267c",
"anchor": {
"startWord": 42,
"endWord": 49,
"exact": "we need the pricing sheet by Friday",
"prefix": "Before we close the quarter, ",
"suffix": ". Can you send it over?",
"startInSec": 61.4,
"endInSec": 64.2,
"speakerIds": [
"1"
],
"transcriptRevision": 3
},
"parentId": null,
"body": "Can we confirm this date with finance?",
"status": "active",
"isResolved": false,
"isDeleted": false,
"userId": "65f0c1a2b3c4d5e6f7a8b9c0",
"createdAt": "2026-10-06T14:05:12.000Z",
"updatedAt": "2026-10-06T14:05:12.000Z"
}
}400 Validation, reply depth, range or limit problem
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (Validation, reply depth, range or limit problem), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 400,
"message": "Replies can only be added to the first comment in a thread.",
"hints": [
"The API request is invalid or improperly formed."
]
}403 You lack the Comments: Create permission
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
message |
string | Why the request was refused. |
Example response (You lack the Comments: Create permission), application/json.
{
"status": "failed",
"message": "You do not have permission to perform this action"
}404 The media, parent comment or labelled passage does not exist
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The media, parent comment or labelled passage does not exist), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 404,
"message": "Comment not found.",
"hints": [
"The requested operation failed because a resource associated with the request could not be found."
]
}409 The transcript changed since you read it
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The transcript changed since you read it), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 409,
"message": "This transcript changed since you opened it. Reload to keep editing.",
"hints": [
"Please use PUT for update instead of POST",
"The requested operation failed because it tried to create a resource that already exists."
]
}Edit, resolve or reopen a comment
/media/{mediaId}/comments/{commentId}Send exactly one of body or isResolved; both or neither returns 400.
bodyedits the text. Only the author can edit a comment; anyone else gets 403 “You can only edit your own comments.” No permission is needed to edit your own.isResolvedresolves (true) or reopens (false) a thread. It needs the Comments: Update permission (on by default for admins and members) and works only on the first comment of a thread; a reply returns 400.
Errors
400when the body breaks the rules above or fails validation.403when you edit someone else’s comment (the error envelope shown), or resolve without the permission ({"status": "failed", "message": "You do not have permission to perform this action"}).404when the media or the comment does not exist, or the comment was deleted.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
mediaId |
path | string | Yes | Id of the media file. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
commentId |
path | string | Yes | Id of the comment. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
body |
string | New text. Author only. Comment text. Trimmed, then 1 to 5,000 characters. |
isResolved |
boolean | true to resolve the thread, false to reopen it. First comment of a thread only. |
curl -X PATCH 'https://api.speakai.co/v1/media/b4994aa1267c/comments/Cm8WpE3kLv6NdHa' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{
"isResolved": true
}'200 Success
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | success on every 2xx response. One of: success . |
data |
object | A comment. |
data – 14 more fields
| Field | Type | Description |
|---|---|---|
commentId |
string | Id of the comment. |
mediaId |
string | Id of the media. |
anchor |
object | The passage the comment is on, or null for a comment on the whole file. Replies carry null. |
parentId |
string | commentId of the thread’s first comment for a reply, null for the first comment. |
body |
string | Comment text. Empty on a deleted first comment that still has replies. |
mediaLabelId |
string | Labelled passage the comment is linked to. Present only when one was linked. |
status |
string | Present only on comments with an anchor. active: the same words, possibly at new positions after an edit. shifted: most of the words survived an edit near the same time, but the text changed. needs_review: the words changed too much to follow; anchor then holds a suggested passage on the new transcript and lastResolved the last position a person confirmed. One of: active, shifted, needs_review . |
lastResolved |
object | Present only while status is needs_review: the last position a person confirmed. |
isResolved |
boolean | true once the thread is resolved. Only set on the first comment of a thread. |
resolvedBy |
string | Id of the person who resolved the thread. Present only while it is resolved. |
isDeleted |
boolean | true on a deleted first comment kept because it has replies. |
userId |
string | Id of the author. |
createdAt |
string (date-time) | When it was posted. |
updatedAt |
string (date-time) | When it last changed. |
anchor – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
lastResolved – 9 more fields
| Field | Type | Description |
|---|---|---|
startWord |
integer | Position of the first word. |
endWord |
integer | Position of the last word, inclusive. |
exact |
string | The quoted words, joined by single spaces. |
prefix |
string | Up to 32 characters of transcript text before the quote. |
suffix |
string | Up to 32 characters of transcript text after the quote. |
startInSec |
number | Start time of the first word, in seconds. |
endInSec |
number | End time of the last word, in seconds. |
speakerIds |
string[] | Speakers of the quoted words. |
transcriptRevision |
integer | The transcript revision these positions refer to. |
Example response (Success), application/json.
{
"status": "success",
"data": {
"commentId": "Cm8WpE3kLv6NdHa",
"mediaId": "b4994aa1267c",
"anchor": {
"startWord": 42,
"endWord": 49,
"exact": "we need the pricing sheet by Friday",
"prefix": "Before we close the quarter, ",
"suffix": ". Can you send it over?",
"startInSec": 61.4,
"endInSec": 64.2,
"speakerIds": [
"1"
],
"transcriptRevision": 3
},
"parentId": null,
"body": "Can we confirm this date with finance?",
"status": "active",
"isResolved": true,
"isDeleted": false,
"userId": "65f0c1a2b3c4d5e6f7a8b9c0",
"createdAt": "2026-10-06T14:05:12.000Z",
"updatedAt": "2026-10-06T16:30:00.000Z",
"resolvedBy": "65f0c1a2b3c4d5e6f7a8b9c0"
}
}400 The body broke a rule or failed validation
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The body broke a rule or failed validation), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 400,
"message": "Only the first comment in a thread can be resolved.",
"hints": [
"The API request is invalid or improperly formed."
]
}403 Not your comment, or no Comments: Update permission
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (Not your comment, or no Comments: Update permission), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 403,
"message": "You can only edit your own comments.",
"hints": [
"The requested operation is forbidden and cannot be completed."
]
}404 The media or comment does not exist
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The media or comment does not exist), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 404,
"message": "Comment not found.",
"hints": [
"The requested operation failed because a resource associated with the request could not be found."
]
}Delete a comment
/media/{mediaId}/comments/{commentId}You can always delete your own comments. Deleting someone else’s needs the Comments: Delete permission (on by default for admins only); without it the request returns 403.
A deleted first comment that has replies stays in the list as an empty placeholder so the replies keep their context.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
mediaId |
path | string | Yes | Id of the media file. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
commentId |
path | string | Yes | Id of the comment. Trimmed, then 1 to 64 characters from A-Z, a-z, 0-9, _ and - (pattern ^[A-Za-z0-9_-]{1,64}$). Anything else returns 400. |
curl -X DELETE 'https://api.speakai.co/v1/media/b4994aa1267c/comments/Cm8WpE3kLv6NdHa' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 Success
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | success on every 2xx response. One of: success . |
data |
object | The result. |
data.commentId |
string | Id of the comment you deleted. |
Example response (Success), application/json.
{
"status": "success",
"data": {
"commentId": "Cm8WpE3kLv6NdHa"
}
}403 Someone else’s comment, and you lack Comments: Delete
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
message |
string | Why the request was refused. |
Example response (Someone else’s comment, and you lack Comments: Delete), application/json.
{
"status": "failed",
"message": "You do not have permission to perform this action"
}404 The media or comment does not exist, or it was already deleted
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | failed. One of: failed . |
requestId |
string | Id of this request, for support. |
code |
integer | The HTTP status code again. |
message |
string | What went wrong, in words you can show to a person. |
hints |
string[] | Generic hints for this kind of error. |
Example response (The media or comment does not exist, or it was already deleted), application/json.
{
"status": "failed",
"requestId": "req_0000000000000000",
"code": 404,
"message": "Comment not found.",
"hints": [
"The requested operation failed because a resource associated with the request could not be found."
]
}Related pages
- API reference for the base URL, authentication, and the error format.
- Authenticate with the Speak AI API using access tokens
- Upload audio and video to Speak AI and read insights
- Create and update live transcription sessions
- Analyze text notes with the Speak AI text endpoints
Get an API key on the Speak AI developer page.